ichou1のブログ

主に音声認識、時々、データ分析のことを書く

Kerasメモ(強化学習)

Deep Reinforcement Learningを試してみる。

今回、使ったソース
Deep-Learning-with-Keras/rl-network-train.py at master · PacktPublishing/Deep-Learning-with-Keras · GitHub

ゲーム内容は、プレイヤーが「paddle」を動かして、落下してくる「ball」をキャッチする。
プレイヤーが選択できるアクションは3種類。

NUM_ACTIONS = 3 # number of valid actions (left, stay, right)

ゲーム画面は、縦横ともに400px。
下図は、1マスの縦横が5pxのグリッド線を書き足した状態。
f:id:ichou1:20190413095650p:plain

「ball」は、1回に2マス分、落下する(「paddle」のheightと同じ)
また、「paddle」は1回に4マス分、移動できる(「ball」のwidthと同じ)
f:id:ichou1:20190412215006p:plain

下図が、ボールが落ち切った状態。
スタートしてから落ち切るまでに遷移する状態数は「32」
f:id:ichou1:20190412215241p:plain

モデル全体像。
(80, 80)の画像を1frameとして、直近4frameをもとに、次のアクションを予測する。
f:id:ichou1:20190412220154p:plain

報酬(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)を避けるようになる。