見出し画像

Unity ML-Agents 0.9.0 の汎化トレーニング

「Unity ML-Agents 0.9.0」の新機能である「汎化トレーニング」を紹介します。
[情報源]

1. 汎化トレーニング

同じ環境でエージェントを学習し続けると、エージェントが環境に過剰適合してしまうことがあります。過剰適合してしまうと、エージェントは環境が少し変わっただけでも適応できなくなってしまいます。これは「教師あり学習」で同一のデータセットで学習しすぎて過学習しているのと同じです。

そこで、環境にバリエーションを持たせて、エージェントが将来の環境の変化に適応できるように学習する必要があります。これを「汎化トレーニング」と呼びます。

2. 3DBallの汎化トレーニング

例として、サンプル学習環境「3DBall」の「汎化トレーニング」を行います。今回は、「重力」(gravity)、「ボールの重さ」(mass)、「ボールの大きさ」(scale)にバリエーションを持たせます。

画像1

画像2

3. バリエーションのパラメータをリセットパラメータで実装

はじめに、環境内のバリエーションのパラメータを「リセットパラメータ」で実装します。「リセットパラメータ」は、環境リセット時に更新する環境パラメータです。「Academy」に登録します。

画像3

4. サンプラーファイルの作成

次に、「リセットパラメータ」に対して、どのような値を適用するかを指定する「サンプラーファイル」(*.yaml)を作成します。

【3dball_generalize.yaml】

resampling-interval: 5000

mass:
    sampler-type: "uniform"
    min_value: 0.5
    max_value: 10

gravity:
    sampler-type: "uniform"
    min_value: 7
    max_value: 12

scale:
    sampler-type: "uniform"
    min_value: 0.75
    max_value: 3

◎ resampling-interval
特定の環境で学習を続けるステップ数です。
このステップ数を越えた後の環境リセット時に、「リセットパラメータ」の値が更新されます。

◎ リセットパラメータの名前(mass・gravity・scale)
「mass」「gravity」「scale」は、今回定義されている「リセットパラメータ」の名前です。

◎ sampler-type
「リセットパラメータ」の更新時に使用する「サンプラー種別」です。
「サンプラー種別」に応じた「サブ引数」も必要になります。

・uniform
「最小値」(min_value)と「最大値」(max_value)の間でfloat値を均一に適用します。-1.0〜1.0の値を均一に適用する設定は、次のとおりです。

<リセットパラメータの名前>:
    sampler-type: "uniform"
    min_value: -1.0
    max_value: 1.0

・ gaussian
「平均」(mean)と「標準偏差」(st_dev)のガウス分布でfloat値を適用します。平均50、標準偏差10の害す分布を適用する設定は、次のとおりです。

<リセットパラメータの名前>:
    sampler-type: "gaussian"
    mean: 50
    st_dev: 10

・multirange_uniform
指定された間隔(interval)でfloat値を均一に適用します。intervalの書式は次のとおりです。

[[間隔1の最小値, 間隔1の最大値], [間隔2の最小値, 間隔2の最大値], ...]

7〜10または10〜20の値を均一に適用する設定は、次のとおりです。

<リセットパラメータの名前>:
    sampler-type: "multirange_uniform"
    intervals: [[7, 10], [15, 20]]

5. 汎化トレーニングの実行

汎化トレーニングを実行するには、「mlagents-learn」の引数「--sampler」に「サンプラーファイル」を指定します。これによって、「リセットパラメータ」が定期的に更新されるようになり、環境にバリエーションをもたせることができます。

$ mlagents-learn config/trainer_config.yaml --sampler=config/3dball_generalize.yaml --run-id=3D-Ball-generalization --train

6. 独自のサンプラー種別の定義

独自のサンプラー種別を定義するには、はじめに「Samplerクラス」(ml-agents-envs/mlagents_envs/sampler_class.pyに含まれる)を継承したクラスを定義します。__init__()には必要な引数を渡し、sample_all()はサンプリングした値を返すように実装します。

class CustomSampler(Sampler):
    def __init__(self, argA, argB, argC):
        self.possible_vals = [argA, argB, argC]

    def sample_all(self):
        return np.random.choice(self.possible_vals)

これを、「SamplerFactory」のregister_sampler()で登録します。

SamplerFactory.register_sampler(string key, Sampler sanoker)

キー「custom-sampler」で「CustomSampler」を登録すると、サンプラーファイルで以下の定義が利用できるようになります。

mass:
    sampler-type: "custom-sampler"
    argA: 1
    argB: 2
    argC: 3


この記事が気に入ったらサポートをしてみませんか?