棒のバランスを取るCartPoleの動かし方 強化学習を始める前に
こんにちは!
ぷもんです。
今回は強化学習でバランスゲームを攻略! ステップとエピソードとは?
というnoteの続きでコードを細かく分けながら理解していきます。
前回はこちらの前半部分について理解しました。
import gym
import numpy as np
env = gym.make('CartPole-v0')
goal_average_steps = 195
max_number_of_steps = 200
num_consecutive_iterations = 100
num_episodes = 5000
last_time_steps = np.zeros(num_consecutive_iterations)
今回、理解していくのはこちらのコードです。
for episode in range(num_episodes):
observation = env.reset()
episode_reward = 0
for t in range(max_number_of_steps):
env.render()
action = np.random.choice([0, 1])
observation, reward, done, info = env.step(action)
episode_reward += reward
if done:
print('%d Episode finished after %f time steps / mean %f' % (episode, t + 1,
last_time_steps.mean()))
last_time_steps = np.hstack((last_time_steps[1:], [episode_reward]))
break
if (last_time_steps.mean() >= goal_average_steps):
print('Episode %d train agent successfuly!' % episode)
break
では早速やっていきます!!
・range関数
for episode in range(num_episodes):
こちらはrange関数を使っています。
range関数は長い回数繰り返す時に使います。
for 変数 in range(始まりの数値,最後の数値, 増加する量)
でループを指定することができて
始まりの数値と増加する量は省略することができます。
今回の場合は
変数が「episode」
始まりの数値と増加する量は省略されて
最後の数値が「num_episodes」
になっています。
ちなみに「num_episodes」は
強化学習でバランスゲームを攻略! ステップとエピソードとは?のnoteで
書いた前半部分で
num_episodes = 5000
と定義しているので
今回は5000回のエピソード(棒が倒れるまで)を
繰り返すrange関数ということになります。
・observationってなんや?
observation = env.reset()
observationとは特定の場面のことで
CartPoleでは、台車の位置やポールの角度などの観測可能な値があります。
強化学習でよく使う用語です。
ここではresetと書いている通り環境を初期化します。
ゲームをスタートした時、
前の続きだとおかしくなるのでリセットし直すイメージですね!
・range関数2回目の登場!!
episode_reward = 0
for t in range(max_number_of_steps):
まずは、episode_reward = 0と定義しています。
後々、episode_reward += rewardで繰り返すごとに値が増えていくものを
ここが始まりなので書いています。
「max_number_of_steps = 200」
と前回に定義しているので
200回繰り返すrange関数です。
・ゲームスタート!!
env.render()
環境を実行します。(ゲームをスタートします。)
今回の場合はCartPoleの棒のバランスを取るゲームです。
・actionってなんや?
action = np.random.choice([0, 1])
actionとはその名の通り行動のことです。
0は右、1は左の動きを指しているので
(多分、CartPoleの設定がそうなっているのだと思いますが
詳しくわからないので調べます。)
右、左のアクションをすることがわかります。
np.random.choice([0, 1])は
Numpyというモジュールによる乱数を作る方法を使っていて
choice([◯, △])の◯△の値(今回は0と1)をランダムに出すよ!
という意味です。
つまり、ランダムに右左の動きをするという意味になります
・ゲーム終了
observation, reward, done, info = env.step(action)
episode_reward += reward
棒が倒れてゲームが終了しました。
observation=場面の状況
reward=何回目なのか
done=ゲームの終了していいか?
info=学習には使用しない付加情報
などを保存します。
「episode_reward += reward」
で次のエピソードが始まります。
・ゲームが終了したら?
doneはゲームを終了するかどうかを表していると先ほど言いましたが
if doneはゲームが終わった時にどうするかを示しています。
if done:
print('%d Episode finished after %f time steps / mean %f' % (episode, t + 1,
last_time_steps.mean()))
last_time_steps = np.hstack((last_time_steps[1:], [episode_reward]))
break
%d、%fは出力フォーマット指定子と言われるもので
整数や実数などの数字の表示の型を表しています。
print('%d〜%f〜%f' % f(◯、△、×))
のような形で書くことで後ろのカッコが表すものを
%d、%fの型に合わせて当てはめていきます。
今回の場合
%d Episode finished after %f time steps / mean %f
のなかに
episode、 t + 1、last_time_steps.mean()
の値が入ることになります。
強化学習でバランスゲームを攻略! ステップとエピソードとは?
で実行してみた時に
次のような画面になりました。
棒のバランスをとっているウィンドウの後ろに
662 Episode finished after 28.000000 time steps / mean 20.910000
と出ています。
ここではこの値の出力の仕方を表しているのです。
last_time_steps= np.hstack((last_time_steps[1:], [episode_reward]))
では結果を保存しています。
last_time_stepsという
直近の100エピソードを保存している表みたいなものに
NumPyのhstack関数という表に値を追加する関数を使って
last_time_steps[1:]と[episode_reward]の値を
追加しています。
・ゲームが成功したら!
if (last_time_steps.mean() >= goal_average_steps):
print('Episode %d train agent successfuly!' % episode)
break
last_time_steps.mean()(直近の100エピソードの平均)が
goal_average_steps(195)以上であれば成功になって
「Episode %d train agent successfuly!' % episode」
と表示されます。
last_time_steps.mean()、goal_average_stepsの値は
最初に定義しています。
最後に...
これで一通り理解できました。
途中、次のように書いて
action = np.random.choice([0, 1])
行動をランダムで決めていることからもわかるように
このコードはランダムにCartPoleのゲームを動かすもので
強化学習はやっていません。
やっと強化学習をやるための
CartPoleのゲームの動かし方を学んだだけです。
強化学習制覇までの道は長い...。
難しかった...。
参考にしたサイトはこちらです!
最後まで読んでいただきありがとうございました。
ぷもんでした!