wandb.plot のメソッドを使うと、学習中に時間とともに変化するものも含めて、wandb.Run.log() でチャートを記録・追跡できます。カスタムチャート用フレームワークの詳細については、カスタムチャートのウォークスルーを参照してください。
これらのシンプルなチャートを使うと、メトリクスや結果を基本的な形で簡単に可視化できます。
折れ線グラフ
散布図
棒グラフ
ヒストグラム
複数折れ線グラフ
カスタムの折れ線グラフをログします。任意の軸上にある、順序どおりに結ばれた点のリストです。import wandb
with wandb.init() as run:
data = [[x, y] for (x, y) in zip(x_values, y_values)]
table = wandb.Table(data=data, columns=["x", "y"])
run.log(
{
"my_custom_plot_id": wandb.plot.line(
table, "x", "y", title="Custom Y vs X Line Plot"
)
}
)
これを使うと、任意の 2 次元で曲線を記録できます。2 つの値のリスト同士をプロットする場合、各リスト内の値の数はまったく同じである必要があります。たとえば、各点には x と y が 1 つずつ必要です。アプリで表示コードを実行 任意の x 軸と y 軸上の点 (x, y) のリストとして、カスタム散布図をログします。import wandb
with wandb.init() as run:
data = [[x, y] for (x, y) in zip(class_x_scores, class_y_scores)]
table = wandb.Table(data=data, columns=["class_x", "class_y"])
run.log({"my_custom_id": wandb.plot.scatter(table, "class_x", "class_y")})
任意の 2 次元上に散布図の点をログできます。2 つの値のリスト同士をプロットする場合、各リスト内の値の数はまったく同じである必要があります。たとえば、各点には x と y の両方が必要です。アプリで表示コードを実行 カスタム棒グラフ(ラベル付き値のリストを棒として表示したもの)を、数行のコードでそのままログできます:import wandb
with wandb.init() as run:
data = [[label, val] for (label, val) in zip(labels, values)]
table = wandb.Table(data=data, columns=["label", "value"])
run.log(
{
"my_bar_chart_id": wandb.plot.bar(
table, "label", "value", title="Custom Bar Chart"
)
}
)
任意の棒グラフをログするために使用できます。リスト内のラベル数と値の数は必ず一致している必要があります。それぞれのデータポイントには、ラベルと値の両方が必要です。アプリで確認するコードを実行する カスタムヒストグラムを、値のリストを出現回数(頻度)ごとにビン分けして、数行のコードだけで直接ログできます。たとえば、予測の信頼度スコアのリスト(scores)があり、その分布を可視化したいとします。import wandb
with wandb.init() as run:
data = [[s] for s in scores]
table = wandb.Table(data=data, columns=["scores"])
run.log({"my_histogram": wandb.plot.histogram(table, "scores", title="Histogram")})
これは任意のヒストグラムを記録するために使用できます。data はリストのリストであり、行と列からなる 2 次元配列を扱えるようになっています。アプリで見るコードを実行する 複数の線、または複数の異なる x-y 座標ペアのリストを、1 つの共通の x-y 軸上にプロットします:import wandb
with wandb.init() as run:
run.log(
{
"my_custom_id": wandb.plot.line_series(
xs=[0, 1, 2, 3, 4],
ys=[[10, 20, 30, 40, 50], [0.5, 11, 72, 3, 41]],
keys=["metric Y", "metric Z"],
title="Two Random Metrics",
xname="x units",
)
}
)
x と y の各点の数は必ず一致している必要があります。1 つの x 値リストを複数の y 値リストに対応させることも、各 y 値リストごとに別々の x 値リストを用意することもできます。アプリで見る
これらのプリセットチャートには組み込みの wandb.plot() メソッドがあり、スクリプトからチャートを直接すばやくログして、UI 上で必要な情報をそのまま確認できます。
1行のコードで Precision-Recall 曲線 を作成します:import wandb
with wandb.init() as run:
# ground_truth は真のラベルのリストで、predictions は予測スコアのリストです
# 例: ground_truth = [0, 1, 1, 0], predictions = [0.1, 0.4, 0.35, 0.8]
ground_truth = [0, 1, 1, 0]
predictions = [0.1, 0.4, 0.35, 0.8]
run.log({"pr": wandb.plot.pr_curve(ground_truth, predictions)})
コードが次の情報にアクセスできるときはいつでも、これをログとして記録できます:
- 一連のサンプルに対するモデルの予測スコア(
predictions)
- それらのサンプルに対応する正解ラベル(
ground_truth)
- (オプション)ラベルインデックス 0 が cat、1 = dog、2 = bird などを意味する場合の、ラベル/クラス名のリスト(
labels=["cat", "dog", "bird"...])
- (オプション)プロットで可視化するための、ラベルのサブセット(同じくリスト形式)
アプリで見るコードを実行 次の1行でROC曲線を作成できます:import wandb
with wandb.init() as run:
# ground_truth は正解ラベルのリスト、predictions は予測スコアのリスト
# 例: ground_truth = [0, 1, 1, 0], predictions = [0.1, 0.4, 0.35, 0.8]
ground_truth = [0, 1, 1, 0]
predictions = [0.1, 0.4, 0.35, 0.8]
run.log({"roc": wandb.plot.roc_curve(ground_truth, predictions)})
コードで次の情報にアクセスできる任意のタイミングで、これをログできます。
- 一連のサンプルに対するモデルの予測スコア(
predictions)
- それらのサンプルに対応する正解ラベル(
ground_truth)
- (オプション)ラベル/クラス名のリスト(ラベルインデックス 0 が cat、1 が dog、2 が bird などの場合の
labels=["cat", "dog", "bird"...])
- (オプション)プロット上で可視化するための、これらのラベルのサブセット(リスト形式のまま)
アプリで見るコードを実行 1 行のコードでマルチクラスの混同行列を作成します:import wandb
cm = wandb.plot.confusion_matrix(
y_true=ground_truth, preds=predictions, class_names=class_names
)
with wandb.init() as run:
run.log({"conf_mat": cm})
コードから次の情報にアクセスできる場所であれば、どこからでもログできます:
- 一連のサンプルに対するモデルの予測ラベル(
preds)または正規化された確率スコア(probs)。確率は (サンプル数, クラス数) の形状である必要があります。確率か予測のどちらか一方のみを指定でき、両方を同時には指定できません。
- それらのサンプルに対応する正解ラベル(
y_true)
- ラベル/クラス名の完全なリスト(文字列)としての
class_names。例: インデックス 0 が cat, 1 が dog, 2 が bird の場合、class_names=["cat", "dog", "bird"]。
アプリで見るコードを実行する
完全にカスタマイズするには、組み込みの Custom Chart プリセット を調整するか、新しいプリセットを作成してチャートを保存します。チャート ID を使用すると、スクリプトからそのカスタムプリセットに直接データを記録できます。
import wandb
# プロットする列を含むテーブルを作成する
table = wandb.Table(data=data, columns=["step", "height"])
# テーブルの列をチャートのフィールドにマッピングする
fields = {"x": "step", "value": "height"}
# テーブルを使用して新しいカスタムチャートプリセットにデータを入力する
# 保存済みのチャートプリセットを使用するには、vega_spec_name を変更する
# タイトルを編集するには、string_fields を変更する
my_custom_chart = wandb.plot_table(
vega_spec_name="carey/new_chart",
data_table=table,
fields=fields,
string_fields={"title": "Height Histogram"},
)
with wandb.init() as run:
# カスタムチャートをログに記録する
run.log({"my_custom_chart": my_custom_chart})
コードを実行する
Matplotlib と Plotly のプロット
wandb.plot() を使った W&B の Custom Charts の代わりに、matplotlib や Plotly で生成したチャートを記録できます。
import wandb
import matplotlib.pyplot as plt
with wandb.init() as run:
# シンプルなmatplotlibプロットを作成する
plt.figure()
plt.plot([1, 2, 3, 4])
plt.ylabel("some interesting numbers")
# プロットをW&Bに記録する
run.log({"chart": plt})
matplotlib のプロットまたは figure オブジェクトを wandb.Run.log() に渡すだけです。デフォルトでは、そのプロットを Plotly のグラフに変換します。プロットを画像としてログしたい場合は、プロットを wandb.Image に渡します。Plotly のチャートもそのまま渡せます。
「You attempted to log an empty plot」というエラーが出る場合は、fig = plt.figure() でプロットとは別に figure を作成し、その後 wandb.Run.log() の呼び出しで fig をログしてください。
カスタム HTML を W&B Tables に記録する
W&B では、Plotly と Bokeh のインタラクティブなチャートを HTML として記録し、Tables に追加できます。
インタラクティブな Plotly チャートを HTML に変換して、wandb Tables にログできます。
import wandb
import plotly.express as px
# 新しいrunを初期化する
with wandb.init(project="log-plotly-fig-tables", name="plotly_html") as run:
# テーブルを作成する
table = wandb.Table(columns=["plotly_figure"])
# Plotly図のパスを作成する
path_to_plotly_html = "./plotly_figure.html"
# Plotly図の例
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
# Plotly図をHTMLに書き出す
# auto_play を False に設定すると、アニメーション付きのPlotlyチャートが
# テーブル内で自動再生されるのを防ぐ
fig.write_html(path_to_plotly_html, auto_play=False)
# Plotly図をHTMLファイルとしてテーブルに追加する
table.add_data(wandb.Html(path_to_plotly_html))
# テーブルをログに記録する
run.log({"test_table": table})
インタラクティブな Bokeh チャートを HTML に変換して、wandb Tables にログできます。
from scipy.signal import spectrogram
import holoviews as hv
import panel as pn
from scipy.io import wavfile
import numpy as np
from bokeh.resources import INLINE
hv.extension("bokeh", logo=False)
import wandb
def save_audio_with_bokeh_plot_to_html(audio_path, html_file_name):
sr, wav_data = wavfile.read(audio_path)
duration = len(wav_data) / sr
f, t, sxx = spectrogram(wav_data, sr)
spec_gram = hv.Image((t, f, np.log10(sxx)), ["Time (s)", "Frequency (hz)"]).opts(
width=500, height=150, labelled=[]
)
audio = pn.pane.Audio(wav_data, sample_rate=sr, name="Audio", throttle=500)
slider = pn.widgets.FloatSlider(end=duration, visible=False)
line = hv.VLine(0).opts(color="white")
slider.jslink(audio, value="time", bidirectional=True)
slider.jslink(line, value="glyph.location")
combined = pn.Row(audio, spec_gram * line, slider).save(html_file_name)
html_file_name = "audio_with_plot.html"
audio_path = "hello.wav"
save_audio_with_bokeh_plot_to_html(audio_path, html_file_name)
wandb_html = wandb.Html(html_file_name)
with wandb.init(project="audio_test") as run:
my_table = wandb.Table(columns=["audio_with_plot"], data=[[wandb_html]])
run.log({"audio_table": my_table})