連続的なアクションの扱い方
前回のチュートリアルのプロジェクトから始めて、連続的アクションを追加してみましょう。スタータープロジェクトを使って一緒に進めるか、完成したプロジェクトを確認してもよいでしょう。
離散的アクションと連続的アクション
前回のガイドでは、離散的アクションを扱いました - エージェントはパターンに一致するために有限の選択肢(0または1)から選ぶ必要がありました。実際のシナリオでは、どのボタンを押すかを決定するために多数のセンサーデータや視覚入力を受け取ることがあります。
しかし、多くの実世界のアプリケーションでは、これが常に可能とは限りません。例えば以下のような制御には:
- 車両のステアリング角度
- ロボットアームの関節トルク
- エンジンの出力レベル
エージェントは連続的アクション、つまりカテゴリ的な選択ではなく、正確な浮動小数点値を出力する必要があります。
環境に連続的アクションを追加する
環境を修正して、離散的アクションと連続的アクションの両方を含めましょう。元のパターンマッチングタスクを維持しつつ、AIが新しい値の平方根を出力すると期待する第2のパターンを追加します。
私たちの「期待」以外は何も変えないことに注目してください - エージェントは報酬シグナルだけを頼りに、試行錯誤を通じて私たちが望むことを理解する必要があります!
まず、PatternMatchingEnvironment.cs
に第2のパターンと連続的アクションを追跡するための新しいフィールドを追加します:
private int pattern = 0;private int pattern2 = 0;private int aiChoice = 0;private float aicontinuousChoice = 0f;private bool roundFinished = false;
次に、2つ目の観測メソッドと連続的アクションメソッドを追加します:
[RLMatrixObservation]public float SeePattern() => pattern;
[RLMatrixObservation]public float SeePattern2() => pattern2;
[RLMatrixActionContinuous]public void MakeChoiceContinuous(float input){ aicontinuousChoice = input;}
次に、報酬関数を作成しましょう:
[RLMatrixReward]public float GiveReward() => aiChoice == pattern ? 1.0f : -1.0f;
// AIの連続的な出力が第2パターンの平方根に近い場合に+2の報酬を追加[RLMatrixReward]public float ExtraRewards() => Math.Abs(aicontinuousChoice - Math.Sqrt(pattern2)) < 0.1f ? 2f : 0.0f;
最後に、両方のパターンを生成するようにStartNewRound
メソッドを更新する必要があります:
[RLMatrixReset]public void StartNewRound(){ pattern = Random.Shared.Next(2); pattern2 = Random.Shared.Next(10); aiChoice = 0; roundFinished = false;}
pattern2には0-9の範囲を使用していることに注目してください。これによりエージェントにさまざまな平方根を予測するという、より興味深い課題を与えます。
コンパイルエラーの修正
ソリューションをビルドしようとすると、一連のエラーが発生します。これは実際には役立つことです - RLMatrixは実行時エラーを防ぎ、連続的アクションの正しい実装に導くために強力な型付けを使用しています。
エラー1:環境の型の不一致
Argument 1: cannot convert from 'PatternMatchingExample.PatternMatchingEnvironment' to 'RLMatrix.IEnvironmentAsync<float[]>'
これは、RLMatrixが型の安全性を確保するために連続的環境と離散的環境に異なるインターフェースを持っているために発生します。Program.cs
のコードを更新しましょう:
var env = new List<IEnvironmentAsync<float[]>> {var env = new List<IContinuousEnvironmentAsync<float[]>> { environment, //new PatternMatchingEnvironment().RLInit() //並列トレーニング用にさらに追加可能};
エラー2:エージェントの型の不一致
この変更の後、2つ目のエラーが発生します:
Argument 2: cannot convert from 'System.Collections.Generic.List<RLMatrix.IContinuousEnvironmentAsync<float[]>>' to 'System.Collections.Generic.IEnumerable<RLMatrix.IEnvironmentAsync<float[]>>'
これは、連続的環境に離散的エージェントを使用しようとしているためです。エージェントの型を変更する必要があります:
var agent = new LocalDiscreteRolloutAgent<float[]>(learningSetup, env);var agent = new LocalContinuousRolloutAgent<float[]>(learningSetup, env);
エラー3:アルゴリズムオプションの不一致
これにより3つ目のエラーが発生します:
Argument 1: cannot convert from 'RLMatrix.DQNAgentOptions' to 'RLMatrix.PPOAgentOptions'
この最後のエラーは、DQNが連続的アクションと互換性がないことを示しています。離散的アクション空間と連続的アクション空間の両方を扱えるPPO(近位方策最適化)に切り替える必要があります:
var learningSetup = new DQNAgentOptions( batchSize: 32, memorySize: 1000, gamma: 0.99f, epsStart: 1f, epsEnd: 0.05f, epsDecay: 150f);var learningSetup = new PPOAgentOptions( batchSize: 128, memorySize: 1000, gamma: 0.99f, width: 128, lr: 1E-03f);
最初のトレーニング実行
では、トレーニングを実行して何が起こるか見てみましょう:
Step 800/1000 - Last 50 steps accuracy: 42.0%Press Enter to continue...
Step 850/1000 - Last 50 steps accuracy: 38.0%Press Enter to continue...
Step 900/1000 - Last 50 steps accuracy: 40.0%Press Enter to continue...
Step 950/1000 - Last 50 steps accuracy: 38.0%Press Enter to continue...
Step 1000/1000 - Last 50 steps accuracy: 37.0%Press Enter to continue...
驚きです!AIはほとんど学習していません。正確さは50%を超えず、ダッシュボードを確認すると、離散的アクション(パターンの一致)に対して+1の報酬を定期的に収集していますが、連続的アクション(√pattern2の予測)に対する+2の報酬はほとんど得られていません。
なぜこれが起こるのか?
自問してみてください:なぜAIは連続的アクションよりも離散的アクションの方が簡単に学習できるのでしょうか?
最初の直感は学習率(lr
)かもしれません - 低すぎるのでしょうか?1E-02f
に変更してトレーニングを再実行してみましょう…
効果はありましたか?おそらくないでしょう。実際、エージェントは離散的アクションをより速く学習する一方で、連続的アクション空間をほとんど探索せず、トレーニングが進むにつれて正確さはさらに悪化することに気づくかもしれません。
では実際には何が起きているのでしょうか?
誘導シグナルの追加
より役立つ報酬シグナルを提供することでこれを解決してみましょう。正確な一致だけに報酬を与えるのではなく、エージェントが正しい平方根に近づくにつれて増加する報酬を追加します:
[RLMatrixReward]public float ExtraSupportingReward() => 0.5f / (1 + Math.Abs(aicontinuousChoice - (float)Math.Sqrt(pattern2)));
//学習率を1E-03fに戻すことを忘れないでください!
この報酬関数は勾配を作成します - エージェントが正しい値に近づくにつれて強くなる連続的なシグナルです。完全に正確でなくても、「温かい」か「冷たい」かについてのフィードバックを得られます。
この変更でトレーニングを再実行し、何が起こるか見てみましょう:
Step 850/1000 - Last 50 steps accuracy: 35.0%Press Enter to continue...
Step 900/1000 - Last 50 steps accuracy: 40.0%Press Enter to continue...
Step 950/1000 - Last 50 steps accuracy: 47.0%Press Enter to continue...
Step 1000/1000 - Last 50 steps accuracy: 36.0%Press Enter to continue...
若干の改善が見られますが、まだ十分ではありません。ダッシュボードには学習が進んでいるヒントが表示されるかもしれませんが、明らかにこのより複雑なタスクにはより多くのトレーニング時間が必要です。
トレーニング時間の延長
連続的アクション予測のようなより複雑な課題では、より多くのトレーニングステップが必要になることがよくあります。プログラムを修正して1,000ステップではなく10,000ステップでトレーニングするようにしましょう:
for (int i = 0; i < 10000; i++){ await agent.Step();
if ((i + 1) % 500 == 0) { Console.WriteLine($"Step {i + 1}/10000 - Last 500 steps accuracy: {environment.RecentAccuracy:F1}%"); environment.ResetStats();
Console.WriteLine("\nPress Enter to continue..."); Console.ReadLine(); }}
実験:学習率の影響
より長いトレーニングの進行を観察しながら、異なる学習率を試してみてください。さらに低くするとどうなりますか?大幅に上げるとどうなりますか?
私の実験では、非常に高い学習率を設定すると、モデルは離散的アクションに対する+1の報酬のみを収集することに固執し、連続的な空間を適切に探索することに完全に失敗します。
重要なポイント
この演習を通じて、いくつかの重要な教訓を学びました:
-
連続的アクションは疎な報酬問題のため、離散的アクションよりも本質的に学習が難しいです。可能であれば、アクション空間を離散化しましょう!
-
報酬エンジニアリングは連続的制御問題において非常に重要です。「温かくなっている」というシグナルを提供することで、不可能な学習タスクを扱いやすいものに変えることができます。
-
複雑なタスクにはより多くのトレーニング時間が必要です。アクション空間に次元を追加するにつれて、トレーニング期間も適切にスケールする必要があります。
-
アルゴリズムの選択は重要です。DQNは連続的アクションをまったく扱えませんが、PPOは離散的、連続的、または混合アクション空間を扱うことができます。
-
学習率の調整は繊細です、特にPPOでは。高ければ常に良いというわけではなく、探索に対してはむしろ悪影響を及ぼすこともあります。
これらの原則は、RLMatrixでより複雑な強化学習の課題に取り組む際に役立つでしょう。
理解度テスト
連続的アクションの理解
次のステップ
連続的アクション空間の課題とその対処法を理解したので、より複雑な観測を伴う古典的な強化学習問題に挑戦する準備が整いました。