Deep Q-Network(DQN)エラーが大量に起こって安定しない
Deep Q-Network(DQN)による倒立振子 第1回
はじめに
今回からDeep Q-Network(DQN)を勉強します。ざっとコードを見た感じでは絶望的にまったくわかりません。
一日二日では終わりそうにないのでその日に進んだ分だけ載せていきます。十分に理解できるのには数か月もしくは理解できることはないのかもしれませんがいけるとこまでいってみます。
プログラムのコードは
CartPoleでDQN(deep Q-learning)、DDQNを実装・解説【Phythonで強化学習:第2回】
こちらからそのまま使わせていただきました。
まずはコピペで動作確認
200試行を過ぎても安定しません。
「WARNING:tensorflow:From C:Users.condaenvsstart_pythonlibsite-packageskerasackend ensorflow_backend.py:174: The name tf.get_default_session is deprecated. Please use tf.compat.v1.get_default_session instead.」
こんなのがずらっと出てましたのでどこかでエラーが出てそうです。
298試行で自動終了しましたが最後まで安定しなかったです。
モジュールとは?
関数(def)とは?
クラスとは?
メソッドとは?
プログラムのコードの解読
# [0]必要なライブラリのインポート import gym # 倒立振子(cartpole)の実行環境 import numpy as np import time from keras.models import Sequential from keras.layers import Dense from keras.optimizers import Adam from keras.utils import plot_model from collections import deque from gym import wrappers # gymの画像保存 from keras import backend as K # [1]損失関数の定義 # 損失関数に関数を使用します def huberloss(y_true, y_pred): return K.mean(K.minimum(0.5*K.square(y_pred-y_true), K.abs(y_pred-y_true)-0.5), axis=1) # [2]Q関数をディープラーニングのネットワークをクラスとして定義 class QNetwork: def __init__(self, learning_rate=0.01, state_size=4, action_size=2, hidden_size=10): self.model = Sequential() self.model.add(Dense(hidden_size, activation='relu', input_dim=state_size)) self.model.add(Dense(hidden_size, activation='relu')) self.model.add(Dense(action_size, activation='linear')) self.optimizer = Adam(lr=learning_rate) # 誤差を減らす学習方法はAdam # self.model.compile(loss='mse', optimizer=self.optimizer) self.model.compile(loss=huberloss, optimizer=self.optimizer) # 重みの学習 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は表示なしの設定 # [3]Experience ReplayとFixed Target Q-Networkを実現するメモリクラス class Memory: def __init__(self, max_size=1000): self.buffer = deque(maxlen=max_size) def add(self, experience): self.buffer.append(experience) def sample(self, batch_size): idx = np.random.choice(np.arange(len(self.buffer)), size=batch_size, replace=False) return [self.buffer[ii] for ii in idx] def len(self): return len(self.buffer) # [4]カートの状態に応じて、行動を決定するクラス class Actor: def get_action(self, state, episode, targetQN): # [C]t+1での行動を返す # 徐々に最適行動のみをとる、ε-greedy法 epsilon = 0.001 + 0.9 / (1.0+episode) if epsilon <= np.random.uniform(0, 1): retTargetQs = targetQN.model.predict(state)[0] action = np.argmax(retTargetQs) # 最大の報酬を返す行動を選択する else: action = np.random.choice([0, 1]) # ランダムに行動する return action
# [5] メイン関数開始---------------------------------------------------- # [5.1] 初期設定-------------------------------------------------------- DQN_MODE = 1 # 1がDQN、0がDDQNです LENDER_MODE = 1 # 0は学習後も描画なし、1は学習終了後に描画する env = gym.make('CartPole-v0') num_episodes = 299 # 総試行回数 max_number_of_steps = 200 # 1試行のstep数 goal_average_reward = 195 # この報酬を超えると学習終了 num_consecutive_iterations = 10 # 学習完了評価の平均計算を行う試行回数 total_reward_vec = np.zeros(num_consecutive_iterations) # 各試行の報酬を格納 gamma = 0.99 # 割引係数 islearned = 0 # 学習が終わったフラグ isrender = 0 # 描画フラグ # --- hidden_size = 16 # Q-networkの隠れ層のニューロンの数 learning_rate = 0.00001 # Q-networkの学習係数 memory_size = 10000 # バッファーメモリの大きさ batch_size = 32 # Q-networkを更新するバッチの大記載
# [5.2]Qネットワークとメモリ、Actorの生成-------------------------------------------------------- mainQN = QNetwork(hidden_size=hidden_size, learning_rate=learning_rate) # メインのQネットワーク targetQN = QNetwork(hidden_size=hidden_size, learning_rate=learning_rate) # 価値を計算するQネットワーク # plot_model(mainQN.model, to_file='Qnetwork.png', show_shapes=True) # Qネットワークの可視化 memory = Memory(max_size=memory_size) actor = Actor()
解説
実際に使用されるまではdefの関数定義とクラスの定義はサクッと流します。
huberloss(関数の定義)
・ネットワークの重み
・二乗誤差と絶対誤差の小さい方を使用
・Huber損失関数を定義
・tensorflowのwhere関数を使用
QNetwork(クラスの定義)
・入力層+中間層2層+出力層
・replayメソッドで重みの学習
Memory(クラスの定義)
・学習する内容を保存しておく記憶クラス
・addメソッドで追加
・sampleメソッドでランダムに引数分だけ保存内容を取り出す
・lenメソッドで現在保存されている量を返す
Actor(クラスの定義)
・get_actionメソッドでCartを右に押すか左に押すかを決める
変数の初期設定
今はこんな変数があるのかと頭に入れておきます。実際使われたときにまた見返します。
Qネットワーク、メモリ、Actorの生成
「mainQN = QNetwork(hidden_size=hidden_size, learning_rate=learning_rate) # メインのQネットワーク」
調べていくとここでエラーが起こっていることがわかりました。詳しくエラーの原因を調べていきます。
本日はここまで。次回に続きます。
参考サイト
保存ファイル
lesson49.py
文責:Luke