Kerasで重みの学習をする(Python Deep Q-Network(DQN))
Deep Q-Network(DQN)による倒立振子 第6回
はじめに
前回は学習したモデルで予測した結果を出しました。今回は学習させる方法を見ていきます。
# Qネットワークの重みを学習・更新する replay if (memory.len() > batch_size) and not islearned: mainQN.replay(memory, batch_size, gamma, targetQN)
ざっと流れを追ってみましたがなかなか理解するのは難しそうでした。少しずつやっていきます。
プログラムの流れ
if (memory.len() > batch_size) and not islearned:
memory.len() memory.buffer(状態、アクション、報酬、次の状態)のデータ数(何行あるか)
batch_size = 32 # Q-networkを更新するバッチの大記載
islearned = 0 # 学習が終わったフラグ
つまり「memory.bufferが32行より大きくて学習が終わってないとき」になります。(行動が32回までは学習せずに33回目以降から学習を始めます)
mainQN.replay(memory, batch_size, gamma, targetQN)
# [2]Q関数をディープラーニングのネットワークをクラスとして定義 class QNetwork: # 重みの学習 def replay(self, memory, batch_size, gamma, targetQN): inputs = np.zeros((batch_size, 4)) targets = np.zeros((batch_size, 2)) mini_batch = memory.sample(batch_size) for i, (state_b, action_b, reward_b, next_state_b) in enumerate(mini_batch): inputs[i:i + 1] = state_b target = reward_b if not (next_state_b == np.zeros(state_b.shape)).all(axis=1): # 価値計算(DDQNにも対応できるように、行動決定のQネットワークと価値観数のQネットワークは分離) retmainQs = self.model.predict(next_state_b)[0] next_action = np.argmax(retmainQs) # 最大の報酬を返す行動を選択する target = reward_b + gamma * targetQN.model.predict(next_state_b)[0][next_action]
targets[i] = self.model.predict(state_b) # Qネットワークの出力 targets[i][action_b] = target # 教師信号 self.model.fit(inputs, targets, epochs=1, verbose=0) # epochsは訓練データの反復回数、verbose=0は表示なしの設定
inputs 32行4列のリスト
targets 32行2列のリスト
mini_batch memory.bufferから順番もランダムに32個の状態を持ってくる
for i, (state_b, action_b, reward_b, next_state_b) in enumerate(mini_batch):
enumerate関数
引数にリストなどを指定する。インデックス番号, 要素の順に取得できる。
つまり「0, 状態, アクション, 報酬, 次の状態」~「31, 状態, アクション, 報酬, 次の状態」が返ります。
if not (next_state_b == np.zeros(state_b.shape)).all(axis=1):
next_state_bが[0,0,0,0]ではないとき(棒が倒れたとき以外)でいいと思います。
retmainQs = self.model.predict(next_state_b)[0] で次の状態を予測して
next_action = np.argmax(retmainQs) で次の行動を決めます。
target = reward_b + gamma * targetQN.model.predict(next_state_b)[0][next_action]
で報酬をQ関数で計算しなおして
targets[i] = self.model.predict(state_b) # Qネットワークの出力
targets[i][action_b] = target # 教師信号
で報酬を書き換えます。
self.model.fit(inputs, targets, epochs=1, verbose=0) # epochsは訓練データの反復回数、verbose=0は表示なしの設定
で最後に学習させます。
model.fit(引数1, 引数2, batch_size=None, epochs=1, verbose=1)
固定のエポック数でモデルを訓練する.
引数1: 訓練データのNumpy配列
引数2: ターゲット(ラベル)データのNumpy配列
batch_size: 設定したサンプル数ごとに勾配の更新を行います。省略すると32になります。
epochs: 整数でモデルを訓練するエポック数。エポックは,提供される引数1および引数2データ全体の反復です。 このモデルはepochsで与えられた反復回数の訓練をするわけではなく,単にepochsという指標に試行が達するまで訓練します。
verbose: 0, 1または2、詳細表示モード。0とすると標準出力にログを出力しません。1の場合はログをプログレスバーで標準出力、2の場合はエポックごとに1行のログを出力します。
全体的な流れはなんとなくつかめました。最後の学習部分の変数inputsとtargetsが大事なところだと思います。
本日はここまで。次回からは棒を安定させるためにどこがおかしいか探っていきたいと思います。
参考サイト
保存ファイル
lesson49.py
文責:Luke