Kerasメモ(強化学習)
Deep Reinforcement Learningを試してみる。
ゲーム内容は、プレイヤーが「paddle」を動かして、落下してくる「ball」をキャッチする。
プレイヤーが選択できるアクションは3種類。
NUM_ACTIONS = 3 # number of valid actions (left, stay, right)
ゲーム画面は、縦横ともに400px。
下図は、1マスの縦横が5pxのグリッド線を書き足した状態。
「ball」は、1回に2マス分、落下する(「paddle」のheightと同じ)
また、「paddle」は1回に4マス分、移動できる(「ball」のwidthと同じ)
下図が、ボールが落ち切った状態。
スタートしてから落ち切るまでに遷移する状態数は「32」
モデル全体像。
(80, 80)の画像を1frameとして、直近4frameをもとに、次のアクションを予測する。
報酬(reward)は以下のとおり。
- キャッチ成功:1
- キャッチ失敗:-1
- ボール落下中: 0
バッチ1つ分を構成するデータは以下のとおり。
Xがトレーニングデータ、Yが教師データに該当する。
Yには、model.predict( )で得られる、各アクションに対する報酬の予測値が入る。
s_t, a_t, r_t, s_tp1, game_over = batch[i] # s_t : state, shape --> (1, 80, 80, 4) # a_t : action # r_t : reward (at state "s_t", take action "a_t" ) # s_tp1 : state(t+1), shape --> (1, 80, 80, 4) X[i] = s_t Y[i] = model.predict(s_t)[0] # example Y[i] # --> array([ 0.09449015, -0.01138393, -0.06042233])
この後、ゲームの状態に応じて、Yを書き換える。
ボールが落ち切った場合、報酬で上書きする。
Y[i, a_t] = r_t # example # a_t : 2 # r_t : 1 # before Y[i] : [ 0.09449015, -0.01138393, -0.06042233] # after Y[i] : [ 0.09449015, -0.01138393, 1. ]
ボールが落下中の場合、アクションa_tに対する予測値を、状態t+1の予測値の最大値に書き換える。
(この時、割引率gammaを掛ける)
Q_sa = np.max(model.predict(s_tp1)[0]) Y[i, a_t] = r_t + gamma * Q_sa # gamma = 0.99 # example # a_t : 2 # r_t : 0 # model.predict(s_tp1)[0] --> [ 0.00574994, -0.04766183, -0.0417471 ] # Q_sa : 0.0057499357 # before Y[i] : [-0.02611616, -0.09139924, -0.0712234 ] # after Y[i] : [-0.02611616, -0.09139924, 0.00569244 ]
X、Yをもとにmodelをトレーニングする。
model.train_on_batch(X, Y)
報酬が大きくなる行動(キャッチ成功、reward=1)を選び、報酬が小さくなる行動(キャッチ失敗、reward=-1)を避けるようになる。