Path: blob/master/site/ja/agents/tutorials/bandits_tutorial.ipynb
25118 views
Copyright 2023 The TF-Agents Authors.
TF-Agents における多腕バンディット問題のチュートリアル
セットアップ
以下の依存関係をインストールしていない場合は、実行します。
インポート
はじめに
タ腕バンディット問題(MAB)は、エージェントがある環境の状態を観察した後に何らかのアクションを取ることで、その環境における報酬を得るという強化学習の特殊なケースです。一般的な RL と MAB の主な違いは、MAB では、エージェントが環境の次の状態に影響を与えないことです。したがって、エージェントは状態遷移をモデル化したり、過去のアクションに対する報酬を与えたり、より多くの報酬を得るための「予測」を行いません。
ほかの RL 分野と同様に、MAB エージェントの目標は、できる限り多くの報酬を収集するポリシーを見つけ出すことです。ただし、十分に調べなかった場合により適したアクションを見逃す可能性があるため、最高の報酬を約束するアクションを常に使用しようとするのは間違いです。これが MAB で解決しなければならない主な問題であり、通常、探索と知識利用のジレンマと呼ばれています。
MAB のバンディット環境、ポリシー、およびエージェントは、tf_agents/bandits のサブディレクトリにあります。
環境
TF-Agents では、環境クラスは現在の状態(観測またはコンテキスト)に関する情報を提供し、アクションを入力として受け取って状態遷移を実行し、報酬を出力する役割があります。このクラスは、エピソードが終了したときに新しいエピソードが開始されるよう、リセットも行います。これは、状態のラベルがエピソードの「最後」となった時に reset
関数を呼び出して行われます。
詳細については、「TF-Agents 環境のチュートリアル」をご覧ください。
前述のとおり、MAB は、アクションが次の観測に影響を与えないという点で一般的な RL と異なりますが、もう一つの違いは、バンディットには、前の時間ステップから独立して新しい観測でステップが開始するたびに「エピソード」がないところにあります。
観測が確実に独立しており、RL エピソードの概念を中傷かするために、PyEnvironment
と TFEnvironment
のサブクラスである BanditPyEnvironment と BanditTFEnvironment を導入します。これらのクラスは、ユーザーが実装したままにする 2 つのプライベートメンバー関数を公開します。
と
_observe
関数は観測を戻します。すると、ポリシーがこの観測に基づくアクションを選択します。_apply_action
は、アクションを入力として受け取り、対応する報酬を戻します。これらのプライベートメンバー関数はそれぞれ、reset
関数と step
関数によって呼び出されます。
上記の中間抽象クラスは PyEnvironment
の _reset
関数と _step
関数を実装し、サブクラスが実装する抽象関数の _observe
と _apply_action
を公開します。
単純な環境クラスの例
以下のクラスは、観測が -2 から 2 のランダム整数で、3 つの可能なアクション (0, 1, 2) があり、報酬がこのアクションと観測の積である非常に単純な環境を提供します。
次に、この環境を使用して観測を取得し、アクションに対する報酬を受け取ります。
TF Environment
BanditTFEnvironment
をサブクラス化するか、RL 環境と同様に BanditPyEnvironment
を定義して TFPyEnvironment
でラップすることでバンディット環境を定義できます。単純さを維持するために、このチュートリアルでは、後者を使用することにします。
ポリシー
バンディット問題におけるポリシーは、RL 問題と同様に機能し、観測を入力としてアクション(またはアクションの分布)を提供します。
詳細については、「TF-Agents ポリシーのチュートリアル」をご覧ください。
環境と同様に、ポリシーの構築には 2 つの方法があります。1 つは、PyPolicy
を作成して TFPyPolicy
でラップする方法で、もう 1 つは、TFPolicy
を直接作成する方法です。ここでは、直接作成する方法を使用します。
この例は非常に単純であるため、最適なポリシーを手動で作成できます。アクションは観測の表示にのみ依存しており、負の場合は 0、正の場合は 2 となります。
次に、環境に観測をリクエストし、ポリシーを呼び出してポリシーを選択すると、環境が報酬を出力します。
バンディット環境の実装方法によって、ステップを取るたびに、選択したアクションに対する報酬が得られるだけでなく、次の観測も得られます。
エージェント
バンディット環境とバンディットポリシーを準備したので、バンディットエージェントを定義することにしましょう。バンディットエージェントは、トレーニングサンプルに基づいてポリシーの変更を行います。
バンディットエージェントの API は RL のエージェントと同じですが、_initialize
メソッドと _train
メソッドを実装し、policy
と collect_policy
を定義する必要があります。
より複雑な環境
バンディットエージェントを記述する前に、少し理解しにくい環境を用意する必要があります。もう少し面白くするために、次の環境は、reward = observation * action
または reward = -observation * action
のいずれかを必ず与えるようにしましょう。どちらが与えられるかは、環境か初期化するときに決定されます。
より複雑なポリシー
より複雑なかんきょうには、より複雑なポリシーが伴います。基盤の環境の動作を検出するポリシーが必要です。ポリシーが処理する必要のある状況は 3 つあります。
エージェントが、実行している環境のバージョンを検出していない場合
エージェントが、実行している環境の元のバージョンを検出した場合
エージェントが、実行している環境の反転バージョンを検出した場合
_situation
という tf_variable
を、[0, 2]
の値にエンコーディングされた情報を格納するように定義し、ポリシーが適宜に動作するようにします。
エージェント
では、環境のサインを検出して、ポリシーを適切に設定するエージェントを定義することにしましょう。
上記のコードでは、エージェントがポリシーを定義し、エージェントとポリシーが変数 situation
を共有しています。
また、_train
関数のパラメータ experience
はトラジェクトリです。
トラジェクトリ
TF-Agents では、trajectories
は名前付きのタプルであり、前のステップで取得されたサンプルを含みます。これらのサンプルはエージェントによってポリシーのトレーニングと更新に使用されます。RL では、トラジェクトリには現在の状態、次の状態、そして現在のエピソードが終了したかどうかに関する情報が含まれている必要があります。バンディットの世界では、これらの情報は不要であるため、ヘルパー関数をセットアップしてトラジェクトリを作成します。
エージェントのトレーニング
これで、バンディットエージェントをトレーニングするためのピースがすべて用意できました。
出力から、2 つ目のステップ(最初のステップで観測が 0 でなければ)の後に、ポリシーが正しい方法でアクションを選択しており、したがって収集された報酬が常に非負であることがわかります。
実際の文脈付きバンディットの例
線形ペイオフ関数を使った定常確率的環境
この例で使用する環境は、StationaryStochasticPyEnvironment です。この環境は、観測(コンテキスト)を提供する(非常にノイズの多い)関数をパラメータとして取り、アームごとに、与えられた観測に基づいて報酬を計算する(やはりノイズの多い)関数を取ります。このチュートリアルの例では、d 次元の立方体から均一にコンテキストをサンプリングすると、報酬関数はコンテキストの線形関数で、一部はガウスノイズです。
LinUCB エージェント
以下のエージェントは、LinUCB アルゴリズムを実装します。
Regret 基準
バンディットで最も重要な基準は regret です。エージェントが収集した報酬と、環境の報酬関数にアクセスできる予測ポリシーの期待報酬の差として計算されます。そのため、RegretMetric には、特定の観測があった場合に、達成可能な最大の期待報酬を計算する baseline_reward_fn 関数が必要です。このチュートリアルの例では、この環境に定義した報酬関数に相当するノイズのない関数の最大値を取る必要があります。
トレーニング
上記で説明した環境、ポリシー、およびエージェントの要素をすべてを組み合わせましょう。ドライバーを使用して、環境でポリシーを実行してトレーニングデータを出力し、そのデータでエージェントをトレーニングします。
必要なステップ数を共に指定するパラメータが 2 つあることに注意してください。num_iterations
はトレーナーループを実行する回数を指定し、ドライバーはイテレーションごとに steps_per_loop
ステップを実行します。これらのパラメータを維持するのは、主に、イテレーションごとに実行される演算と、ステップごとにドライバーが行う演算があるためです。たとえば、エージェントの train
関数はイテレーションにつき一度しか呼び出されません。ここでは、トレーニングの頻度を高めると、ポリシーが「より新しく」なるのに対し、より大きなバッチでトレーニングすると時間の効率がよくなるというトレードオフがあります。
最後のコードスニペットを実行したら、生成されるプロットから、エージェントのトレーニングが増えて、特定の観測が与えられる場合にポリシーが適切なアクションを選択する確率が高まる過程で、平均 Regret が下降しているのが示されます(そうであることを願います)。
今後の内容
さらに機能例を確認する場合は、bandits/agents/examples をご覧ください。さまざまなエージェントと環境用にすぐに実行できる例が掲載されています。
TF-Agents ライブラリは、アームごとの特徴量でタ腕バンディットを処理することもできます。それについては、アームごとのバンディット問題のチュートリアルをご覧ください。