Start_python’s diary

ふたり暮らし

アラフィフ夫婦のフリーランスプラン

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行のログを出力します。

 

全体的な流れはなんとなくつかめました。最後の学習部分の変数inputstargetsが大事なところだと思います。

 

 

本日はここまで。次回からは棒を安定させるためにどこがおかしいか探っていきたいと思います。

 

 

参考サイト

neuro-educator.com

keras.io

marupeke296.com

 

 

保存ファイル

lesson49.py

 

 

文責:Luke