メインコンテンツへスキップ
このガイドでは、ハイパーパラメーター探索の最適化のために、W&BをPythonトレーニングスクリプトやノートブックに統合する方法についての推奨事項を説明します。

元のトレーニングスクリプト

モデルをトレーニングするPythonスクリプト(以下を参照)があると仮定します。ゴールは、検証精度(val_acc)を最大化するハイパーパラメーターを見つけることです。 Pythonスクリプトでは、train_one_epochevaluate_one_epoch の2つの関数を定義します。train_one_epoch 関数は1エポック分のトレーニングをシミュレートし、トレーニングの精度と損失を返します。evaluate_one_epoch 関数は、検証データセットでのモデル評価をシミュレートし、検証の精度と損失を返します。 学習率(lr)、バッチサイズ(batch_size)、エポック数(epochs)などのハイパーパラメーター値を含む設定辞書(config)を定義します。設定辞書の値がトレーニングプロセスを制御します。 次に、典型的なトレーニングループを模した main という関数を定義します。各エポックで、トレーニングデータセットと検証データセットに対して精度と損失が計算されます。
このコードは模擬トレーニングスクリプトです。モデルのトレーニングは行わず、ランダムな精度と損失の値を生成することでトレーニングプロセスをシミュレートしています。このコードの目的は、W&Bをトレーニングスクリプトに統合する方法を示すことです。
import random
import numpy as np

def train_one_epoch(epoch, lr, batch_size):
    acc = 0.25 + ((epoch / 30) + (random.random() / 10))
    loss = 0.2 + (1 - ((epoch - 1) / 10 + random.random() / 5))
    return acc, loss

def evaluate_one_epoch(epoch):
    acc = 0.1 + ((epoch / 20) + (random.random() / 10))
    loss = 0.25 + (1 - ((epoch - 1) / 10 + random.random() / 6))
    return acc, loss

# ハイパーパラメーターの値を持つconfig変数
config = {"lr": 0.0001, "batch_size": 16, "epochs": 5}

def main():
    lr = config["lr"]
    batch_size = config["batch_size"]
    epochs = config["epochs"]

    for epoch in np.arange(1, epochs):
        train_acc, train_loss = train_one_epoch(epoch, lr, batch_size)
        val_acc, val_loss = evaluate_one_epoch(epoch)

        print("epoch: ", epoch)
        print("training accuracy:", train_acc, "training loss:", train_loss)
        print("validation accuracy:", val_acc, "validation loss:", val_loss)

if __name__ == "__main__":
    main()
次のセクションでは、トレーニング中のハイパーパラメーターとメトリクスを追跡するために、PythonスクリプトにW&Bを追加します。W&Bを使用して、検証精度(val_acc)を最大化する最適なハイパーパラメーターを見つけます。

トレーニングスクリプトにW&Bを追加する

トレーニングスクリプトを更新してW&Bを含めます。PythonスクリプトまたはノートブックにW&Bを統合する方法は、Sweeps をどのように管理するかによって異なります。 W&B Python SDKを使用して Sweeps の開始、停止、管理を行う場合は、Python script or notebook タブの手順に従ってください。代わりにW&B CLIを使用する場合は、CLI タブの手順に従ってください。
sweep configuration を含むYAML設定ファイルを作成します。この設定ファイルには、sweep に探索させたいハイパーパラメーターが含まれます。次の例では、各 sweep 中にバッチサイズ(batch_size)、エポック数(epochs)、および学習率(lr)のハイパーパラメーターが変化します。
# config.yaml
program: train.py
method: random
name: sweep
metric:
  goal: maximize
  name: val_acc
parameters:
  batch_size:
    values: [16, 32, 64]
  lr:
    min: 0.0001
    max: 0.1
  epochs:
    values: [5, 10, 15]
W&B Sweep の設定作成方法の詳細については、Define sweep configuration を参照してください。YAMLファイルの program キーには、Pythonスクリプトの名前を指定する必要があります。次に、コード例に以下を追加します。
  1. W&B Python SDK (wandb) と PyYAML (yaml) をインポートします。PyYAMLはYAML設定ファイルを読み込むために使用されます。
  2. 設定ファイルを読み込みます。
  3. wandb.init() を使用して、データを W&B Run として同期およびログ記録するためのバックグラウンドプロセスを開始します。config オブジェクトを config パラメータに渡します。
  4. 値をハードコードする代わりに、wandb.Run.config からハイパーパラメーター値を定義します。
  5. 最適化したいメトリクスを wandb.Run.log() でログ記録します。設定で定義したメトリクスをログに記録する必要があります。設定辞書(この例では sweep_configuration)内で、val_acc の値を最大化するように sweep を定義しています。
import wandb
import yaml
import random
import numpy as np


def train_one_epoch(epoch, lr, batch_size):
    acc = 0.25 + ((epoch / 30) + (random.random() / 10))
    loss = 0.2 + (1 - ((epoch - 1) / 10 + random.random() / 5))
    return acc, loss


def evaluate_one_epoch(epoch):
    acc = 0.1 + ((epoch / 20) + (random.random() / 10))
    loss = 0.25 + (1 - ((epoch - 1) / 10 + random.random() / 6))
    return acc, loss


def main():
    # デフォルトのハイパーパラメーターを設定
    with open("./config.yaml") as file:
        config = yaml.load(file, Loader=yaml.FullLoader)

    with wandb.init(config=config) as run:
        for epoch in np.arange(1, run.config['epochs']):
            train_acc, train_loss = train_one_epoch(epoch, run.config['lr'], run.config['batch_size'])
            val_acc, val_loss = evaluate_one_epoch(epoch)
            run.log(
                {
                    "epoch": epoch,
                    "train_acc": train_acc,
                    "train_loss": train_loss,
                    "val_acc": val_acc,
                    "val_loss": val_loss,
                }
            )

# main関数を呼び出し
main()
CLIで、sweep agent が試行する最大 run 数を設定します。これはオプションです。この例では最大数を5に設定します。
NUM=5
次に、wandb sweep コマンドで sweep を初期化します。YAMLファイルの名前を指定します。オプションで、プロジェクトフラグ (--project) に Projects 名を指定します。
wandb sweep --project sweep-demo-cli config.yaml
これにより sweep ID が返されます。sweep の初期化方法の詳細については、Initialize sweeps を参照してください。sweep ID をコピーし、次のコードスニペットの sweepID を置き換えて、wandb agent コマンドで sweep ジョブを開始します。
wandb agent --count $NUM your-entity/sweep-demo-cli/sweepID
詳細については、Start sweep jobs を参照してください。
sweep におけるW&Bへのメトリクスのログ記録sweep configuration と wandb.Run.log() の両方で、定義した最適化対象のメトリクスをログに記録する必要があります。例えば、sweep configuration 内で最適化するメトリクスを val_acc と定義した場合、val_acc もW&Bにログ記録しなければなりません。メトリクスをログに記録しないと、W&Bは何を最適化すればよいか判断できません。
with wandb.init() as run:
    val_loss, val_acc = train()
    run.log(
        {
            "val_loss": val_loss,
            "val_acc": val_acc
            }
        )
以下は、W&Bへのメトリクスログ記録の誤った例です。sweep configuration で最適化されるメトリクスは val_acc ですが、コードでは validation というキーの下のネストされた辞書内に val_acc をログ記録しています。メトリクスは、ネストされた辞書内ではなく、直接ログに記録する必要があります。
with wandb.init() as run:
    val_loss, val_acc = train()
    run.log(
        {
            "validation": {
                "val_loss": val_loss, 
                "val_acc": val_acc
                }
            }
        )