Gymで強化学習⑳Q学習と線形近似
前回は、連続値をとる状態の処理を関数近似によって行う方法について解説しました。今回はGymのカートポール(CartPole-v1)の環境を使ったQ学習の実装を線形近似を使って行います。
カートポールのルール
カートポールの環境ではカートを左右に動かすことでポールのバランスをできるだけ長く保つことを目指します。
行動
行動としては2つの選択肢があります。
0:カートを左へ押す
1:カートを右へ押す
ただし、どのくらいの力が左あるいは右に加えられるのかは固定されておらず、その都度ランダムに決まります。よってエージェントはポールの傾きなどを考慮して行動を決める必要があります。
観測値
観測できるデータは、4つの数値を要素としてもつベクトルになっています。
要素1:カートの位置(-4.8から+4.8)
要素2:カートの速度(負の無限大から正の無限大)
要素3:ポールの角度(ラジアンで、-0.418から+0.418。角度で解釈すると-24度から+24度まで)
要素4:ポールの角速度(負の無限大から正の無限大)
カートの初期位置は、-0.05から+0.05の間でランダムに決まります。
例えば、次のような観測値が与えられます。
[-0.00131049 0.0047364 0.04382138 0.04789533]
カートの位置:-0.00131049 (中央からちょっと左の位置)
カートの速度:0.0047364 (右方向へ移動している)
ポールの角度:0.04382138 (時計回り右へ傾いている)
ポールの角速度:0.04789533 (時計回り右へ倒れている)
この場合、ポールが右へ倒れ始めているので、カートを右に押してバランスを取る必要があります。
報酬
報酬は、各ステップごとに+1を与えられます。つまり、できるだけ長くポールを立たせることで総報酬を大きく増やすことができます。
終了条件
エピソードの終了の条件は、以下になります。
カートの位置が-2.4から+2.4の範囲の外になったら終了
カートの角度が-0.2095から+0.2095の範囲(±12°)の外になったら終了
エピソードのステップ数が500(報酬が500)になったら終了
なお、エピソードの終了には、terminated と truncated があります。
カートの位置や角度が決められた範囲を超えた場合は、terminated となります。つまりは失敗です。
エピソードのステップ数が500に到達するとtruncated(切り捨て、時間切れ)となり終了しますが、こちらは成功とみなされます。
terminated と truncatedの違いは行動価値の計算に影響するので覚えておいてください。
なお、この環境に関する情報は、Cart Pole - Gymnasium Documentation (farama.org)にあります。
Python環境の設定
今回は新しいGymの環境を使うので、Pythonの環境から解説します。
# テスト用のフォルダを作る
mkdir cartpole
cd cartpole
#Pythonの環境を作る
python3 -m venv venv
source venv/bin/activate
# Pipを最新のものにしておく
pip install --upgrade pip
# ジムをインストール (classic-control)
pip install gymnasium[classic-control]
Gymをインストールする際に classic-control と指定しています。これによって、カートポールの環境が必要とする依存関係がインストールされます。
環境オブジェクトの作成などは、以前に「凍った湖」の環境でも解説したものと同様なので、ここで解説を割愛します。
エージェントの実装
エージェントのクラスはいつものように、いくつかのメソッドを定義することでエピソードを実行することができるようにしています。
今回は線形近似を行うので LinearAgent と名付けました。
class LinearAgent:
def __init__(self, env, ...):
# エージェントの初期化
...
def reset(self, observation, info):
# 状態の初期化
...
def act(self):
# 行動を選択する
...
def learn(self, observation, reward, terminated, truncated, info):
# 観測値、報酬などを受け取る
...
それぞれのメソッドの実装を一つずつ見ていきます。
この記事が気に入ったらサポートをしてみませんか?