強化学習(RL)は、機械学習の三つの主要なパラダイムの一つであり、他の二つは教師あり学習と教師なし学習です。RLでは、エージェントが環境と相互作用し、累積報酬を最大化することを学びます。試行錯誤を通じて異なる環境条件下での最適な行動を学びます。人間のフィードバックを用いた強化学習(RLHF)は、エージェントが各ステップで人間の入力に基づいて行動を修正できるようにします。
RLは、自動運転車、自動取引、ビデオゲームのコンピュータプレイヤー、ロボットのトレーニングなどの問題を解決します。深層ニューラルネットワークを用いてRLアルゴリズムを適用する場合、それは深層強化学習と呼ばれます。
このチュートリアルでは、強化学習アルゴリズムを開発・比較するためのオープンソースのPythonライブラリであるGymnasiumの使い方を紹介します。設定方法、さまざまなRL環境の探求、そしてPythonを使用してRLアルゴリズムを実装するためのシンプルなエージェントを構築する方法を示します。
Gymnasiumとは何ですか?
Gymnasiumは、RLアルゴリズムの開発をサポートするために設計されたオープンソースのPythonライブラリです。RLの研究開発を容易にするために、Gymnasiumは以下を提供しています:
- シンプルなゲームから現実世界のシナリオを模倣した問題まで幅広い環境。
- 環境とのインタフェースを簡略化するAPIおよびラッパー。
- カスタム環境の作成とAPIフレームワークの活用が可能。
開発者は、以下のようなタスクのためにRLアルゴリズムを構築し、APIコールを使用できます:
- エージェントが選択した行動を環境に渡す。
- 環境の状態と各アクションに続く報酬を知る。
- モデルのトレーニング。
- モデルのパフォーマンスをテストする。
OpenAIのGymとFaramaのGymnasium
OpenAIはGymの開発に多くのリソースを投入していませんでした。なぜなら、それは会社にとってビジネスの優先事項ではなかったからです。Farama財団は、長期的にRLライブラリを標準化し維持するために設立されました。Gymnasiumは、OpenAIのGymのFarama財団のフォークです。Gymnasium 0.26.2は、Gym 0.26.2のドロップイン置き換えです。このフォークにより、FaramaはすべてのAPI呼び出しに対して機能的(クラスベースに加えて)なメソッドを追加し、ベクター環境をサポートし、ラッパーを改善することを目指しています。全体的な目標は、フレームワークをよりクリーンで効率的にすることです。
Gymnasiumのセットアップ
ジムナジウムには、NumPyやPyTorchなどのさまざまな依存プログラムの特定バージョン(最新リリースではない)が必要です。したがって、新しいCondaまたはvenv環境、または新しいノートブックを作成して、Gymnasiumをインストールし、使用し、RLプログラムを実行することをお勧めします。
このDataLabワークブックを使用して、チュートリアルに従うことができます。
Gymnasiumのインストール
サーバーまたはローカルマシンにGymnasiumをインストールするには、次を実行します:
$ pip install gymnasium
Google ColabやDataCampのDataLabなどのノートブックを使用してインストールするには、次のコマンドを使用します:
!pip install gymnasium
上記のコマンドは、Gymnasiumと依存関係の正しいバージョンをインストールします。
Gymnasium環境の探索
2024年11月現在、Gymnasiumには60を超える組み込み環境が含まれています。使用可能な組み込み環境を参照するには、gym.envs.registry.all()
関数を使用します。次の例に示すように:
import gymnasium as gym for i in gym.envs.registry.keys(): print(i)
あなたも 体育館のホームページ を訪れることができます。左側のコラムにはすべての環境へのリンクがあります。各環境のウェブページには、アクション、状態などの詳細が記載されています。
環境は Classic Control、Box2Dなどのカテゴリに分類されています。以下に、各グループの一般的な環境のいくつかをリストします。
- Classic Control: これらはRL開発で使用される基本的な環境であり、多くの教科書の例の基礎を形成しています。新しいRLアルゴリズムをテストおよびベンチマークするための複雑さと単純さの適切なバランスを提供します。GymnasiumのClassic Control環境には、次のものが含まれます:
- Acrobot
- Cart Pole
- Mountain Car Discrete
- Mountain Car Continuous
- Pendulum
- Box2D: Box2Dは2Dゲームのための物理エンジンです。このエンジンをベースにした環境には、
- Lunar Lander
- やCar Racing
- などのシンプルなゲームが含まれます。ToyText: これらはRLアルゴリズムのデバッグによく使用される小さくシンプルな環境です。これらの環境の多くは小さなグリッドワールドモデルやシンプルなカードゲームに基づいています。例には、
- Blackjack
- 、Taxi
- 、Frozen Lake
- などがあります。MuJoCo: Multi-Joint dynamics with Contact(MuJoCo)は、ロボティクス、生体力学、機械学習などのアプリケーションのために環境をシミュレートするオープンソースの物理エンジンです。GymnasiumのMuJoCo環境には、
- Ant
- 、Hopper
- 、Humanoid
- 、Swimmer
- などが含まれます。
組み込みの環境に加えて、Gymnasiumは同じAPIを使用して多くの外部環境と連携することができます。
このチュートリアルでは、代表的なClassic Control環境の1つを使用します。特定の環境をインポートするには、.make()
コマンドを使用して環境の名前を引数として渡します。たとえば、CartPole(バージョン1)に基づいた新しい環境を作成するには、以下のコマンドを使用します:
import gymnasium as gym env = gym.make("CartPole-v1")
ジムナジウムでの強化学習概念の理解
要するに、強化学習は、エージェント(ロボットなど)が環境と相互作用するものです。ポリシーはエージェントの行動を決定します。エージェントの行動に応じて、環境は各タイムステップで報酬(またはペナルティ)を与えます。エージェントは、総報酬を最大化する最適なポリシーを見つけるためにRLを使用します。
RL環境の構成要素
以下はRL環境の主要な構成要素です:
- 環境: 外部システム、世界、または文脈。エージェントは一連のタイムステップで環境と相互作用します。各タイムステップにおいて、エージェントの行動に基づいて、環境は:
- 報酬(または罰)を与える
- 次の状態を決定する
- 状態: 環境の現在の構成を数学的に表現したもの。
- たとえば、振り子環境の状態には、各タイムステップでの振り子の位置と角速度が含まれることがあります。
- 終端状態:新しい/他の状態につながらない状態。
- エージェント: 環境を観察し、その観察に基づいてさまざまな行動を取るアルゴリズム。エージェントの目標は報酬を最大化することです。
- たとえば、エージェントは振り子をどのくらい強く、どの方向に押すかを決定します。
- 観察: 環境に関するエージェントの視点の数学的表現。たとえば、センサーを使用して獲得される。
- 行動: エージェントが次のステップに進む前に行う決定。行動は環境の次の状態に影響を与え、エージェントに報酬をもたらす。
- 報酬: 環境からエージェントへのフィードバック。行動と環境の状態に応じて、ポジティブまたはネガティブになることがある。
- リターン:将来の時間ステップにわたる期待される累積リターン。 将来の時間ステップからの報酬は、ディスカウントファクタを使用して割引することができます。
- ポリシー:エージェントのさまざまな状態でどのアクションを取るかに関する戦略。 通常、確率行列として表され、P、状態をアクションにマッピングします。
- 有限な状態の集合が与えられ、m個の可能な状態とn個の可能な行動があるとき、要素Pmnは、状態anで行動を取る確率を表します。
- エピソード: エージェントが終端状態に到達するまでの(ランダム化された)初期状態からのタイムステップの一連。
観測空間と行動空間
観測は、エージェントが環境について収集する情報です。エージェント、例えばロボットは、センサーを使用して環境情報を収集することができます。理想的には、エージェントは環境のすべての側面を説明する完全な状態を観察できるべきです。実際には、エージェントは観測を状態の代理として使用します。したがって、観測がエージェントの行動を決定します。
空間は数学的な集合に類似しています。アイテムの空間 X には X のすべての可能なインスタンスが含まれます。 X の空間は、タイプ X のすべてのアイテムの構造(構文と形式)も定義します。各ジムナジウム環境には、アクション空間 action_space
と観察空間 observation_space
の2つの空間があります。アクション空間と観察空間の両方は、親 gymnasium.spaces.Space
スーパークラスから派生しています。
観測空間
観測空間は、すべての可能な観測を含む空間です。また、観測が保存される形式を定義します。観測空間は通常、データ型 Box のオブジェクトとして表されます。これは ndarray であり、観測のパラメータを 記述しています。ボックスは各次元の境界を指定します。環境の観測空間は、observation_space
メソッドを使用して表示できます:
print("observation space: ", env.observation_space)
CartPole-v1
環境の場合、出力は以下の例のようになります:
observation space: Box([-4.8 -inf -0.41887903 -inf], [4.8 inf 0.41887903 inf], (4,), float32)
この例では、CartPole-v1
の観測空間は4次元です。観測配列の4つの要素は次のとおりです:
- カートの位置 -4.8から+4.8まで変化します
- カートの速度 – 範囲は – から +
- ポールの角度 – -0.4189 から +0.4189 まで変化します
- ポールの角速度 – 範囲は – から +
個々の観測配列の例を見るには、.reset()
コマンドを使用してください。
observation, info = env.reset() print("observation: ", observation)
CartPole-v1
環境の場合、出力は以下の例のようになります:
[ 0.03481963 -0.0277232 0.01703267 -0.04870504]
この配列の4つの要素は、前述の通り、4つの観測量(カートの位置、カートの速度、ポールの角度、ポールの角速度)に対応しています。
Action space
アクションスペースには、エージェントが取ることができるすべての可能なアクションが含まれます。アクションスペースは、アクションがどのように表現されるかも定義します。環境のアクションスペースを表示するには、action_space
メソッドを使用できます:
print("action space: ", env.action_space)
「CartPole-v1」環境では、出力は以下の例のようになります:
action space: Discrete(2)
「CartPole-v1」環境では、アクションスペースは離散的です。エージェントが取ることができるアクションは合計2つあります:
- 0: カートを左に押す
- 1: カートを右に押す
「Gymnasium」で最初のRL エージェントを構築する
前のセクションでは、RLとジムナジウムの基本的な概念を探求しました。このセクションでは、ジムナジウムを使用してRLエージェントを構築する方法を示します。
環境の作成とリセット
最初のステップは、環境のインスタンスを作成することです。新しい環境を作成するには、.make()
メソッドを使用します。
env = gym.make('CartPole-v1')
エージェントの相互作用は環境の状態を変えます。.reset()
メソッドは環境を初期状態にリセットします。デフォルトでは、環境はランダムな状態で初期化されます。.reset()
メソッドにSEED
パラメータを使用して、環境をプログラムを実行するたびに同じ状態で初期化できます。以下のコードは、これを行う方法を示しています:
SEED = 1111 env.reset(seed=SEED)
行動のサンプリングにはランダム性も関与しています。このランダム性を制御し、完全に再現可能なトレーニングパスを得るために、NumPyとPyTorchのランダムジェネレーターにシードを設定できます:
np.random.seed(SEED) torch.manual_seed(SEED)
ランダムな行動と知的な行動
マルコフ過程の各ステップで、エージェントはランダムに行動を選択し、環境を探索して端末状態に到達することができます。行動をランダムに選ぶことで:
- 端末状態に到達するまでに時間がかかることがあります。
- 累積報酬は、実際に得られたであろう報酬よりもはるかに低くなります。
過去の経験(環境との相互作用)に基づいて行動の選択を最適化するようエージェントを訓練することは、長期的な報酬を最大化するためにより効率的です。
未訓練のエージェントは、ランダムに初期化されたポリシーに基づいてランダムな行動から始まります。このポリシーは通常、ニューラルネットワークとして表現されます。訓練中、エージェントは報酬を最大化する最適なポリシーを学習します。強化学習(RL)では、この訓練プロセスはポリシー最適化とも呼ばれます。
さまざまなポリシー最適化の方法があります。ベルマン方程式は、RLポリシーの値を計算し、最適なポリシーを決定する方法を説明します。このチュートリアルでは、ポリシー勾配と呼ばれるシンプルな手法を使用します。他にも、近接ポリシー最適化(PPO)などの方法があります。
シンプルなポリシー勾配エージェントの実装
ポリシー勾配を使用するRLエージェントを構築するために、ポリシーを実装するためのニューラルネットワークを作成し、ステップごとの報酬とアクション確率からリターンと損失を計算する関数を書き、標準的なバックプロパゲーション技術を使用してポリシーを反復的に更新します。
ポリシーネットワークの設定
ポリシーを実装するためにニューラルネットワークを使用します。CartPole-v1
は単純な環境なので、次の条件を満たすニューラルネットワークを使用します:
- 環境の観察空間の次元と同じ入力次元。
- 64ニューロンの単一の隠れ層。
- 出力次元は環境の行動空間の次元と等しい。
したがって、ポリシーネットワークの機能は観測された状態をアクションにマッピングすることです。入力観測が与えられると、適切なアクションを予測します。以下のコードがポリシーネットワークを実装しています:
class PolicyNetwork(nn.Module): def __init__(self, input_dim, hidden_dim, output_dim, dropout): super().__init__() self.layer1 = nn.Linear(input_dim, hidden_dim) self.layer2 = nn.Linear(hidden_dim, output_dim) self.dropout = nn.Dropout(dropout) def forward(self, x): x = self.layer1(x) x = self.dropout(x) x = F.relu(x) x = self.layer2(x) return x
報酬の収集とフォワードパス
前述のように、マルコフプロセスの各ステップで、環境はエージェントの行動と状態に基づいて報酬を与えます。RLの目標は合計リターンを最大化することです。
- 各タイムステップでのリターンは、そのステップまでに得られた報酬の累積和です。
- 各エピソードでの総報酬は、そのエピソードからのすべての段階的な報酬を蓄積することによって得られます。したがって、総報酬は最後の時間ステップ(エージェントが終端状態に到達するとき)の報酬です。
実践では、報酬を蓄積する際に次のことが一般的です。
- 割引率を使用して将来の報酬を調整する。
- ステップごとの報酬の配列を正規化して、スムーズで安定したトレーニングを確保する。
以下のコードは、これを行う方法を示しています。
def calculate_stepwise_returns(rewards, discount_factor): returns = [] R = 0 for r in reversed(rewards): R = r + R * discount_factor returns.insert(0, R) returns = torch.tensor(returns) normalized_returns = (returns - returns.mean()) / returns.std() return normalized_returns
フォワードパスは、エージェントを現在のポリシーに基づいて実行し、ターミナルステートに達するまでの間、ステップごとの報酬とアクション確率を収集することで構成されます。以下のステップでは、フォワードパスの実装方法を説明します:
- 環境を初期状態にリセットします。
- アクション確率、報酬、および累積リターンを保存するためのバッファを初期化します。
.step()
関数を使用して、エージェントを環境内で繰り返し実行し、終了するまで続けます:- 環境の状態の観測を取得します。
- 観察に基づいてポリシーが予測したアクションを取得します。
Softmax
関数を使用して、予測されたアクションを取る確率を推定します。- これらの推定された確率に基づいてカテゴリカル確率分布をシミュレートします。
- この分布からサンプルを取得してエージェントのアクションを得ます。
- シミュレートされた分布からサンプリングされたアクションの対数確率を推定します。
- 各ステップのアクションの対数確率と報酬をそれぞれのバッファに追加します。
- 報酬に基づいて各ステップでのリターンの正規化および割引値を推定します。
def forward_pass(env, policy, discount_factor): log_prob_actions = [] rewards = [] done = False episode_return = 0 policy.train() observation, info = env.reset() while not done: observation = torch.FloatTensor(observation).unsqueeze(0) action_pred = policy(observation) action_prob = F.softmax(action_pred, dim = -1) dist = distributions.Categorical(action_prob) action = dist.sample() log_prob_action = dist.log_prob(action) observation, reward, terminated, truncated, info = env.step(action.item()) done = terminated or truncated log_prob_actions.append(log_prob_action) rewards.append(reward) episode_return += reward log_prob_actions = torch.cat(log_prob_actions) stepwise_returns = calculate_stepwise_returns(rewards, discount_factor) return episode_return, stepwise_returns, log_prob_actions
報酬に基づいてポリシーを更新します
損失は、勾配降下法を適用する量を表します。強化学習の目標はリターンを最大化することです。したがって、期待リターン値を損失の代理として使用します。期待リターン値は、ステップごとの期待リターンとステップごとのアクションの対数確率の積として計算されます。以下のコードは損失を計算します:
def calculate_loss(stepwise_returns, log_prob_actions): loss = -(stepwise_returns * log_prob_actions).sum() return loss
ポリシーを更新するには、損失関数に関して バックプロパゲーション を実行します。以下の update_policy()
メソッドでは calculate_loss()
メソッドを呼び出します。その後、この損失に対してバックプロパゲーションを実行してポリシーパラメータ、つまりポリシーネットワークのモデル重みを更新します。
def update_policy(stepwise_returns, log_prob_actions, optimizer): stepwise_returns = stepwise_returns.detach() loss = calculate_loss(stepwise_returns, log_prob_actions) optimizer.zero_grad() loss.backward() optimizer.step() return loss.item()
リターンの勾配に基づいてポリシーを更新することは、ポリシー勾配法 と呼ばれます。
ポリシーのトレーニング
ポリシーをトレーニングして評価するために必要なすべてのコンポーネントが揃いました。以下のステップに従ってトレーニングループを実装します:
開始する前に、ハイパーパラメータを宣言し、ポリシーをインスタンス化し、オプティマイザを作成します:
- ハイパーパラメータをPythonの定数として宣言します:
MAX_EPOCHS
は、ポリシーを訓練するために実行する最大イテレーション数です。DISCOUNT_FACTOR
は、将来の時間ステップからの報酬の相対的な重要性を決定します。割引率が1の場合、すべての報酬は同じ重要度ですが、0の場合は現在の時間ステップからの報酬のみが重要です。N_TRIALS
は、エージェントのパフォーマンスを評価するためにリターンを平均化するエピソードの数です。N_TRIALS
エピソードの平均リターンが閾値を上回る場合、トレーニングは成功と見なされます。REWARD_THRESHOLD
: ポリシーが閾値を超えるリターンを達成できる場合、それは成功と見なされます。DROPOUT
は、ランダムにゼロにすべき重みの割合を決定します。ドロップアウト関数は、モデルの重みの一部をランダムにゼロに設定します。これにより、特定のニューロンへの依存が減少し、過学習を防ぎ、ネットワークがより堅牢になります。学習率
は、各ステップでポリシーのパラメータがどれだけ修正できるかを決定します。各イテレーションでのパラメータの更新は、勾配と学習率の積です。- ポリシーを
PolicyNetwork
クラスのインスタンスとして定義します(以前に実装したもの)。 - 学習率を用いてAdamアルゴリズムのオプティマイザを作成します。
ポリシーを訓練するために、平均リターン(N_TRIALS
の平均)が報酬の閾値を超えるまで、訓練ステップを繰り返し実行します:
- 各エピソードについて、1回フォワードパスを実行します。アクションの対数確率、ステップごとのリターン、およびそのエピソードからの総リターンを収集します。エピソードリターンを配列に蓄積します。
- ログ確率と段階的リターンを使用して損失を計算します。損失に対してバックプロパゲーションを実行します。オプティマイザーを使用してポリシーパラメータを更新します。
N_TRIALS
の平均リターンが報酬の閾値を超えているか確認します。
以下のコードはこれらのステップを実装しています:
def main(): MAX_EPOCHS = 500 DISCOUNT_FACTOR = 0.99 N_TRIALS = 25 REWARD_THRESHOLD = 475 PRINT_INTERVAL = 10 INPUT_DIM = env.observation_space.shape[0] HIDDEN_DIM = 128 OUTPUT_DIM = env.action_space.n DROPOUT = 0.5 episode_returns = [] policy = PolicyNetwork(INPUT_DIM, HIDDEN_DIM, OUTPUT_DIM, DROPOUT) LEARNING_RATE = 0.01 optimizer = optim.Adam(policy.parameters(), lr = LEARNING_RATE) for episode in range(1, MAX_EPOCHS+1): episode_return, stepwise_returns, log_prob_actions = forward_pass(env, policy, DISCOUNT_FACTOR) _ = update_policy(stepwise_returns, log_prob_actions, optimizer) episode_returns.append(episode_return) mean_episode_return = np.mean(episode_returns[-N_TRIALS:]) if episode % PRINT_INTERVAL == 0: print(f'| Episode: {episode:3} | Mean Rewards: {mean_episode_return:5.1f} |') if mean_episode_return >= REWARD_THRESHOLD: print(f'Reached reward threshold in {episode} episodes') break
最後に、ポリシーをトレーニングするためにmain()
関数を呼び出します:
main()
UこのDataLabワークブックを使用して、上記のアルゴリズムを直接実行し、RLを使用してCartPole環境を解決します。
ジムナジウムにおける高度な技術
RLアルゴリズムの実装方法を示した後、実際に一般的に使用されるいくつかの高度な技術について説明します。
プリビルドアーキテクチャの使用
RLアルゴリズムをゼロから実装することは、特に複雑な環境や最先端のポリシーに対しては長くて困難なプロセスです。
より実用的な代替手段は、Stable Baselines3などのソフトウェアを使用することです。それにはRLアルゴリズムの試行済みの実装が付属しています。事前トレーニング済みのエージェント、トレーニングスクリプト、評価ツール、グラフのプロットおよびビデオの記録用モジュールが含まれています。
Ray RLibは、RL向けのもう1つの人気ツールです。RLibはスケーラブルなソリューションとして設計されており、マルチGPUシステムでのRLアルゴリズムの実装を容易にします。また、マルチエージェントRLもサポートしており、次のような新しい可能性を開くことができます:
- 独立したマルチエージェント学習:各エージェントは他のエージェントを環境の一部として扱います。
- 協調型マルチエージェントトレーニング: エージェントのグループが同じポリシーと価値関数を共有し、互いの経験から並行して学びます。
- 敵対的トレーニング: エージェント(またはエージェントのグループ)が競争的なゲームのような環境で互いに競い合います。
RLibとStable Baselines3の両方を使用すると、OpenAI Gymnasiumから環境をインポートして使用できます。
カスタム環境
Gymnasiumにパッケージされた環境は、新しいRL戦略のテストやトレーニングポリシーに最適な選択肢です。ただし、ほとんどの実用的なアプリケーションには、解決したい問題を正確に反映する環境を作成して使用する必要があります。Gymnasiumを使用してカスタム環境を作成できます。 Gymnasiumのカスタム環境を使用する利点は、RLibやStable Baselines3などの多くの外部ツールがすでにGymnasium API構造で動作するように構成されていることです。
Gymnasiumでカスタム環境を作成するには、次のものを定義する必要があります。
- 観測空間。
- 終了条件。
- エージェントが選択できるアクションのセット。
- 環境を初期化する方法(
reset()
関数が呼ばれたとき)。 - エージェントの行動に基づいて次の状態を決定する方法(
step()
関数が呼ばれたとき)。
詳細を学ぶには、Gymnasiumのカスタム環境作成ガイドを参照してください。
Gymnasiumのベストプラクティス
さまざまな環境で実験を行う
このチュートリアルのコードは、CartPole環境でポリシーグラディエントアルゴリズムを実装する方法を示しました。これは離散的なアクションスペースを持つ単純な環境です。RLをより良く理解するために、同じポリシーグラディエントアルゴリズム(および他のアルゴリズム、例えばPPO)を他の環境で適用することをお勧めします。
たとえば、Pendulum環境には連続したアクション空間があります。 これは、連続変数で表される単一の入力で構成されています。つまり、任意の状態で振り子に適用されるトルク(その大きさと方向)です。 このトルクは、-2から+2までの任意の値を取ることができます。 。
さまざまな環境で異なるアルゴリズムを試すことで、さまざまな種類のRLソリューションとその課題をより良く理解することができます。
トレーニングの進捗をモニター
RL環境は、ロボット、振り子、マウンテンカー、ビデオゲームなどで構成されることがよくあります。環境内でエージェントの行動を視覚化すると、方針のパフォーマンスについて直感的に理解しやすくなります。
ジムでは、env.render()
メソッドを使用して、エージェントと環境のインタラクションを視覚化します。現在の環境の状態(ゲーム画面、振り子やカートポールの位置など)がグラフィカルに表示されます。エージェントの行動と環境の応答の視覚フィードバックは、エージェントのパフォーマンスをモニターし、トレーニングプロセスを通じての進捗を支援します。
「human」、「rgb_array」、「ansi」、および「rgb_array_list」という4つのレンダーモードがあります。エージェントのパフォーマンスを視覚化するには、「human」レンダーモードを使用します。レンダーモードは環境の初期化時に指定されます。例:
env = gym.make(‘CartPole-v1’, render_mode=’human’)
レンダリングを実行するには、.render()
メソッドを、エージェントによる各アクションの後に(.step()
メソッドを呼び出すことで)呼び出します。以下の擬似コードは、これをどのように行うかを示しています:
while not done: … step, reward, terminated, truncated, info = env.step(action.item()) env.render() …
一般的なエラーのトラブルシューティング
Gymnasiumを使用すれば、複雑なRL環境と簡単にインターフェースすることができます。ただし、多くの依存関係を持つソフトウェアであり、継続的に更新されています。そのため、いくつかの一般的なエラータイプに注意することが重要です。
バージョンの不一致
- ジムナジウムバージョンの不一致: Faramaのジムナジウムソフトウェアパッケージは、OpenAIのジムからバージョン0.26.2でフォークされました。古いジムのバージョンと新しいジムナジウムの間にいくつかの互換性のない変更があります。多くの公開実装は古いジムのリリースに基づいており、最新リリースと直接動作しない場合があります。そのような場合は、インストールを古いバージョンに戻すか、コードを新しいリリースと互換性があるように適応させる必要があります。
- 環境バージョンの不一致:多くの体育館環境には異なるバージョンがあります。たとえば、2つのCartPole環境があります –
CartPole-v1
およびCartPole-v0
。環境の振る舞いは両バージョン間で同じですが、エピソードの長さ、報酬の閾値などのいくつかのパラメータが異なる場合があります。1つのバージョンでトレーニングされたポリシーが同じ環境の別のバージョンでうまく機能しない可能性があります。各環境バージョン用にトレーニングパラメータを更新してポリシーを再トレーニングする必要があります。 - 依存関係のバージョン不一致: ジムナジウムはNumPyやPyTorchなどの依存関係に依存しています。2024年12月時点で、これらの依存関係の最新バージョンは
numpy 2.1.3
とtorch 2.5.1
です。ただし、ジムナジウムはtorch 1.13.0
とnumpy 1.23.3
との組み合わせで最良の動作をします。これらの依存関係が事前にインストールされた環境にジムナジウムをインストールすると問題が発生する可能性があります。ジムナジウムは新しいConda環境でインストールして使用することをお勧めします。
収束問題
- ハイパーパラメータ:他の機械学習アルゴリズムと同様に、RLポリシーは学習率や割引率などのハイパーパラメータに敏感です。ハイパーパラメータを手動で調整するか、グリッドサーチやランダムサーチなどの自動化技術を使用して実験することをお勧めします。
- 探索と活用のバランス:いくつかのポリシークラス(例えばPPO)の場合、エージェントは二段階の戦略を採用します:環境を探索して新しい経路を発見し、これまでに知られている経路に基づいて報酬を最大化するために貪欲なアプローチを採用します。探索しすぎると、ポリシーは収束しません。逆に、十分に探索しないと最適な経路を試すこともありません。したがって、探索と活用のバランスを見つけることが重要です。また、トレーニング中に初期のエピソードでは探索を優先し、後のエピソードでは活用を優先することが一般的です。
トレーニングの不安定性
- 大きな学習率: 学習率が高すぎると、ポリシーのパラメータが各ステップで大きく更新されます。これにより、最適な値のセットを見逃す可能性があります。一般的な解決策は、学習率を徐々に減衰させ、トレーニングが収束するにつれて小さく安定した更新を確保することです。
- 過剰な探索: 行動選択におけるランダム性(エントロピー)が大きすぎると、収束を妨げ、後続のステップ間で損失関数に大きな変動をもたらします。安定し、収束するトレーニングプロセスを持つためには、探索と利用のバランスを取ることが重要です。
- アルゴリズムの誤った選択: ポリシー勾配のようなシンプルなアルゴリズムは、大きなアクションと状態空間を持つ複雑な環境で不安定なトレーニングを引き起こす可能性があります。そのような場合には、PPOや信頼領域ポリシー最適化(TRPO)など、より堅牢なアルゴリズムの使用をお勧めします。これらのアルゴリズムは、各ステップでの大きなポリシー更新を避けることができ、より安定する可能性があります。
- ランダム性: 強化学習アルゴリズムは、初期状態やアクション選択に内在するランダム性に非常に敏感です。トレーニングが不安定な場合、異なるランダムシードを使用したり、ポリシーを再初期化することで安定させることができることがあります。
結論
このチュートリアルでは、RLの基本原則を探求し、さまざまなRL環境とインターフェイスするクリーンなAPIを持つソフトウェアパッケージであるGymnasiumについて説明し、単純なRLアルゴリズムを実装し、Gymnasium環境で適用するPythonプログラムの書き方を示しました。
このチュートリアルで基本を理解した後は、タクシーの経路最適化や株取引シミュレーションなどの実践的な問題を解決するためにRLの概念を適用するためにGymnasium環境を使用することをお勧めします。
Source:
https://www.datacamp.com/tutorial/reinforcement-learning-with-gymnasium