Try in Colab
wandb.Table を使用してデータをログに記録し、W&B で可視化やクエリを実行します。このガイドでは、以下の方法について説明します。
- テーブルの作成
- データの追加
- データの取得
- テーブルの保存
テーブルの作成
Table を定義するには、データの各行に対して表示したい列を指定します。各行は、トレーニングデータセット内の単一のアイテム、トレーニング中の特定のステップやエポック、テストアイテムに対するモデルの予測、モデルによって生成されたオブジェクトなどになります。各列には、数値、テキスト、ブール値、画像、ビデオ、オーディオなどの固定タイプがあります。事前にタイプを指定する必要はありません。各列に名前を付け、その列のインデックスにはそのタイプのデータのみを渡すようにしてください。より詳細な例については、W&B Tables ガイド を参照してください。
wandb.Table コンストラクタは、次の 2 つの方法のいずれかで使用します。
-
行のリスト:
名前付きの列とデータの行をログに記録します。例えば、次のコードスニペットは 2 行 3 列のテーブルを生成します。
wandb.Table(columns=["a", "b", "c"], data=[["1a", "1b", "1c"], ["2a", "2b", "2c"]])
-
Pandas DataFrame:
wandb.Table(dataframe=my_df) を使用して DataFrame をログに記録します。列名は DataFrame から抽出されます。
既存の配列または DataFrame から作成
# モデルが 4 つの画像に対して予測を返したと仮定します。
# 以下のフィールドが利用可能です:
# - 画像 ID
# - wandb.Image() でラップされた画像ピクセル
# - モデルの予測ラベル
# - 正解(ground truth)ラベル
my_data = [
[0, wandb.Image("img_0.jpg"), 0, 0],
[1, wandb.Image("img_1.jpg"), 8, 0],
[2, wandb.Image("img_2.jpg"), 7, 1],
[3, wandb.Image("img_3.jpg"), 1, 1],
]
# 対応する列を持つ wandb.Table() を作成します
columns = ["id", "image", "prediction", "truth"]
test_table = wandb.Table(data=my_data, columns=columns)
データの追加
テーブルは可変(mutable)です。スクリプトの実行に合わせて、最大 200,000 行までデータをテーブルに追加できます。テーブルにデータを追加するには 2 つの方法があります。
- 行の追加:
table.add_data("3a", "3b", "3c")。新しい行はリストとして表現されないことに注意してください。行がリスト形式の場合は、アスタリスク記法 * を使用してリストを位置引数に展開します: table.add_data(*my_row_list)。行には、テーブルの列数と同じ数のエントリが含まれている必要があります。
- 列の追加:
table.add_column(name="col_name", data=col_data)。col_data の長さは、テーブルの現在の行数と等しくなければならないことに注意してください。ここで、col_data はリストデータ、または NumPy の NDArray を指定できます。
データの逐次追加
このコード例では、W&B テーブルを逐次的に作成してデータを投入する方法を示します。まず、すべての可能なラベルに対する確信度スコアを含む定義済みの列でテーブルを定義し、推論中に行ごとにデータを追加します。また、run を再開する際にテーブルにデータを逐次追加することも可能です。
# 各ラベルの確信度スコアを含む、テーブルの列を定義します
columns = ["id", "image", "guess", "truth"]
for digit in range(10): # 各数字 (0-9) の確信度スコア列を追加
columns.append(f"score_{digit}")
# 定義した列でテーブルを初期化
test_table = wandb.Table(columns=columns)
# テストデータセットを反復処理し、行ごとにテーブルにデータを追加
# 各行には、画像 ID、画像、予測ラベル、正解ラベル、および確信度スコアが含まれます
for img_id, img in enumerate(mnist_test_data):
true_label = mnist_test_data_labels[img_id] # 正解ラベル
guess_label = my_model.predict(img) # 予測ラベル
test_table.add_data(
img_id, wandb.Image(img), guess_label, true_label
) # テーブルに行データを追加
再開された run へのデータの追加
再開された Runs において、Artifact から既存のテーブルを読み込み、データの最後の行を取得して、更新されたメトリクスを追加することで、W&B テーブルを逐次的に更新できます。その後、互換性を確保するためにテーブルを再初期化し、更新されたバージョンを W&B に再度ログ出力します。
import wandb
# run を初期化
with wandb.init(project="my_project") as run:
# アーティファクトから既存のテーブルをロード
best_checkpt_table = run.use_artifact(table_tag).get(table_name)
# 再開のためにテーブルからデータの最後の行を取得
best_iter, best_metric_max, best_metric_min = best_checkpt_table.data[-1]
# 必要に応じて最適なメトリクスを更新
# 更新されたデータをテーブルに追加
best_checkpt_table.add_data(best_iter, best_metric_max, best_metric_min)
# 互換性を確保するために、更新されたデータでテーブルを再初期化
best_checkpt_table = wandb.Table(
columns=["col1", "col2", "col3"], data=best_checkpt_table.data
)
# Run を初期化
with wandb.init() as run:
# 更新されたテーブルを W&B にログ出力
run.log({table_name: best_checkpt_table})
データの取得
データが Table に入ったら、列または行でアクセスできます。
- 行イテレータ: ユーザーは、
for ndx, row in table.iterrows(): ... のような Table の行イテレータを使用して、データの行を効率的に反復処理できます。
- 列の取得: ユーザーは、
table.get_column("col_name") を使用してデータの列を取得できます。便宜上、convert_to="numpy" を渡すことで、列をプリミティブの NumPy NDArray に変換できます。これは、列に wandb.Image などのメディアタイプが含まれている場合に、基盤となるデータに直接アクセスするのに便利です。
テーブルの保存
スクリプトでデータのテーブル(例えばモデルの予測テーブル)を生成した後、その結果をライブで可視化するために W&B に保存します。
run へのテーブルのログ記録
wandb.Run.log() を使用して、次のようにテーブルを run に保存します。
with wandb.init() as run:
my_table = wandb.Table(columns=["a", "b"], data=[["1a", "1b"], ["2a", "2b"]])
run.log({"table_key": my_table})
同じキーに対してテーブルがログに記録されるたびに、テーブルの新しいバージョンが作成され、バックエンドに保存されます。つまり、同じテーブルを複数のトレーニングステップにわたってログに記録して、時間の経過とともにモデルの予測がどのように改善されるかを確認したり、同じキーにログが記録されている限り、異なる Runs 間でテーブルを比較したりできます。最大 200,000 行までログに記録できます。
200,000 行以上をログに記録するには、次のように制限を上書きできます:wandb.Table.MAX_ARTIFACT_ROWS = Xただし、これにより UI でのクエリの低速化など、パフォーマンスの問題が発生する可能性があります。
プログラムによるテーブルへのアクセス
バックエンドでは、Tables は Artifacts として永続化されます。特定のバージョンにアクセスしたい場合は、Artifact API を使用して行うことができます。
with wandb.init() as run:
my_table = run.use_artifact("run-<run-id>-<table-name>:<tag>").get("<table-name>")
Artifacts の詳細については、開発者ガイドの Artifacts チャプター を参照してください。
テーブルの可視化
この方法でログに記録されたテーブルは、Run ページと Project ページの両方の Workspace に表示されます。詳細については、テーブルの可視化と分析 を参照してください。
Artifact テーブル
Workspace ではなく、run の Artifacts セクションにテーブルをログ出力するには、artifact.add() を使用します。これは、一度ログに記録して将来の Runs で参照したいデータセットがある場合に便利です。
with wandb.init(project="my_project") as run:
# 意味のあるステップごとに wandb Artifact を作成
test_predictions = wandb.Artifact("mnist_test_preds", type="predictions")
# [上記のように予測データを構築します]
test_table = wandb.Table(data=data, columns=columns)
test_predictions.add(test_table, "my_test_key")
run.log_artifact(test_predictions)
画像データを使用した artifact.add() の詳細な例についてはこの Colab を、Artifacts と Tables を使用してテーブルデータのバージョン管理と重複排除を行う方法の例についてはこのレポートを参照してください。
Artifact テーブルの結合(Join)
wandb.JoinedTable(table_1, table_2, join_key) を使用して、ローカルで構築したテーブルや他のアーティファクトから取得したテーブルを結合できます。
| 引数 | 説明 |
|---|
| table_1 | (str, wandb.Table, ArtifactEntry) アーティファクト内の wandb.Table へのパス、テーブルオブジェクト、または ArtifactEntry |
| table_2 | (str, wandb.Table, ArtifactEntry) アーティファクト内の wandb.Table へのパス、テーブルオブジェクト、または ArtifactEntry |
| join_key | (str, [str, str]) 結合を実行するためのキーまたはキーのリスト |
以前にアーティファクトのコンテキストでログに記録した 2 つの Tables を結合するには、アーティファクトからそれらを取得し、その結果を新しい Table に結合します。
例えば、次のコード例では、'original_songs' というオリジナルの曲のテーブルと、同じ曲の合成バージョンのテーブル 'synth_songs' を読み込む方法を示しています。コードはこれら 2 つのテーブルを "song_id" で結合し、結果のテーブルを新しい W&B Table としてアップロードします。
import wandb
with wandb.init(project="my_project") as run:
# オリジナルの曲のテーブルを取得
orig_songs = run.use_artifact("original_songs:latest")
orig_table = orig_songs.get("original_samples")
# 合成された曲のテーブルを取得
synth_songs = run.use_artifact("synth_songs:latest")
synth_table = synth_songs.get("synth_samples")
# "song_id" でテーブルを結合
join_table = wandb.JoinedTable(orig_table, synth_table, "song_id")
join_at = wandb.Artifact("synth_summary", "analysis")
# テーブルをアーティファクトに追加し、W&B にログ出力
join_at.add(join_table, "synth_explore")
run.log_artifact(join_at)
異なる Artifact オブジェクトに保存された 2 つのテーブルを組み合わせる方法の例については、このチュートリアルを読んでください。