質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

強化学習

強化学習とは、ある環境下のエージェントが現状を推測し行動を決定することで報酬を獲得するという見解から、その報酬を最大限に得る方策を学ぶ機械学習のことを指します。問題解決時に得る報酬が選択結果によって変化することで、より良い行動を選択しようと学習する点が特徴です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

0回答

360閲覧

DQNアルゴリズムの確認をお願いします (Open AI Gym_CartPoleのコードあり ※Keras使用)

maltiala

総合スコア10

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

強化学習

強化学習とは、ある環境下のエージェントが現状を推測し行動を決定することで報酬を獲得するという見解から、その報酬を最大限に得る方策を学ぶ機械学習のことを指します。問題解決時に得る報酬が選択結果によって変化することで、より良い行動を選択しようと学習する点が特徴です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2019/01/20 17:15

質問内容

Deep Q-Networkのアルゴリズムを用いて、Open AI GymのCartPoleで強化学習を実施しました。以下にコード全文を載せていますので、アルゴリズムが正しいのか確認をお願いします。
また、実はこのコードではうまくPoleを立たせることができません。500試行ほど動かしても10step程度ですぐに倒れてしまいます。
アルゴリズムに問題がなければ、以下の各パラメータ値に問題があると考えられます。

  • 学習係数
  • epsilonの値
  • 隠れ層の数
  • ニューロン (ノード) の数
  • batch_size

正直各パラメータの値の決め方は勉強不足な面があるため、もう少し調べてみようとも考えています。もし、アドバイスが御座いましたらお教えいただけると幸いです。
以下にソースコードを載せます。コメントについても間違っていたら指摘していただけると幸いです。
よろしくお願いします。

ソースコード全文 (Keras使用)

Python

1#必要なライブラリのインポート 2import gym 3import numpy as np 4from keras.models import Sequential 5from keras.layers import Dense 6from keras.optimizers import Adam 7from collections import deque 8from keras import backend as K 9import tensorflow as tf 10 11 12#損失関数の定義(KerasにはHuber関数は入っていないので自分で定義、またδ==1とする) 13def huberloss(y_true, y_pred): 14 err = y_true - y_pred #誤差を算出 15 cond = K.abs(err) < 1.0 #誤差が±1以内をcondに代入 16 L2 = 0.5 * K.square(err) #二乗誤差を表す(squareは二乗を表す) 17 L1 = (K.abs(err) - 0.5) #huber関数を表す(0.5についてはhuber関数の定義から) 18 #tf.where(条件, x, y) 条件に対してTrueならxから、Falseならyから要素の値を抽出 19 #今回の場合、誤差が±1以内が条件 20 loss = tf.where(cond, L2, L1) #Kerasはwhere関数を持っていない 21 return K.mean(loss) 22 23#Q関数として使用するディープニューラルネットワークをクラスとして定義 24class QNetwork: 25 def __init__(self, learning_rate=0.01, state_size=4, action_size=2, hidden_size=10): 26 self.model = Sequential() #前のノードと次のノード全てが繋がっているモデルを使用するという宣言 27 #hidden_sizeはその層のニューロン数、activationは活性化関数(伝達関数(今回はランプ関数を使用))、input_dimは入力層のノードの数 28 self.model.add(Dense(hidden_size, activation="relu", input_dim=state_size)) 29 self.model.add(Dense(hidden_size, activation="relu")) 30 self.model.add(Dense(action_size, activation="linear")) 31 self.optimizer = Adam(lr=learning_rate) # 誤差を減らす学習方法(最適化アルゴリズム)はAdam 32 self.model.compile(loss=huberloss, optimizer=self.optimizer) #学習モデルの設定 33 34 #重みの学習 35 def replay(self, memory, batch_size, gammma, targetQN): 36 inputs = np.zeros((batch_size, 4)) 37 targets = np.zeros((batch_size, 2)) 38 mini_batch = memory.sample(batch_size) #取得したデータを任意の数でランダムに抜き出す 39 40 for i, (state_b, action_b, reward_b, next_state_b) in enumerate(mini_batch): 41 inputs[i] = state_b 42 target = reward_b 43 #今の状態で予測されるQ値を代入する 44 targets[i] = self.model.predict(state_b) #[i]は行を表す 45 #価値計算 46 mainQs = self.model.predict(next_state_b)[0] #pridictでQ値を予測し取得(最後の[0]は要素として抜き出すことを意味する) 47 next_action = np.argmax(mainQs) #最大の報酬を返す行動を選択する 48 49 #next_state_bの列方向がすべて値を持っていれば(stepが終了した後の状態でなければ)、以下の処理を実行 50 if not (next_state_b == np.zeros(state_b.shape)).all(axis=1): 51 #次の状態において予測されるQ値をtargetQNを使って見積もる(違うモデルでも出力されるQ値の順番は同じ?) 52 target = reward_b + gamma * targetQN.model.predict(next_state_b)[0][next_action] #gammaは時間割引率を成している? 53 #教師データを代入する 54 targets[i][next_action] = target 55# else: 56# #next_state_bが0のとき、targetには教師データとしてreward_bの値をそのまま代入する(この処理は良いのだろうか...) 57# targets[i][next_action] = target #教師信号を代入する 58 59 #1ステップごとに重みをコピー 60 targetQN.model.set_weights(self.model.get_weights()) 61 62 #今の状態で予測されたQ値が、次の状態で予測される値(r(t)+γ・max[Q(s_{t+1},a_{t+1})])に近づくように重みを学習し更新する 63 self.model.fit(inputs, targets, epochs=1, verbose=0) #epochsは訓練データの反復回数、verbose=0は表示なしの設定 64 65#学習する内容を保存しておく記憶クラス 66class Memory: 67 def __init__(self, max_size=1000): 68 self.buffer = deque(maxlen=max_size) 69 70 def add(self, experience): 71 self.buffer.append(experience) 72 73 #取得したデータと同じ要素数のリストnp.arange(len(self.buffer))を用意し、 74 #ランダムにその要素を抜き出し、それを取得したデータのindexとして使うことで、 75 #取得したデータの要素をランダムに抜き出せる 76 def sample(self, batch_size): 77 idx = np.random.choice(np.arange(len(self.buffer)), size=batch_size, replace=False) 78 return [self.buffer[ii] for ii in idx] 79 80 def len(self): 81 return len(self.buffer) 82 83#カートの状態に応じて、行動を決定するクラス 84class Actor: 85 def get_action(self, state, episode, mainQN): #行動を返す 86 #徐々に最適行動のみをとる、ε-greedy法 87 epsilon = 0.005 * ( 1/(episode+1) ) 88 89 if epsilon <= np.random.uniform(0, 1): 90 Q_values = mainQN.model.predict(state)[0] #pridictでQ値を予測し取得(最後の[0]は要素として抜き出すことを意味する) 91 #最大の報酬を返す行動(インデックス(今回は行動は右か左なので0か1を返す))を選択する 92 action = np.argmax(Q_values) 93 94 else: 95 action = np.random.choice([0, 1]) #ランダムに行動する 96 97 return action 98 99 100#初期設定 101LENDER_MODE = 1 #0は学習後も描画なし、1は学習終了後に描画する 102 103env = gym.make("CartPole-v0") 104num_episodes = 1000 #総試行回数 105max_number_of_steps = 200 #1試行のstep数 106goal_average_reward = 1 #この報酬を超えると学習終了 107num_consecutive_iterations = 10 #学習完了評価の平均計算を行う試行回数 108total_reward_vec = np.zeros(num_consecutive_iterations) #各試行の報酬を格納するための空のリスト 109gamma = 0.9 #時間割引係数 110islearned = 0 #学習済みフラグ 111isrender = 0 #描画フラグ 112 113hidden_size = 16 #Q-networkの隠れ層のニューロンの数 114learning_rate = 0.00001 #Q-networkの学習係数 115memory_size = 10000 #バッファーメモリの大きさ 116batch_size = 32 #Q-networkを更新するときに用いるデータ数 117 118 119#Qネットワークとメモリ、Actorの生成 120mainQN = QNetwork(hidden_size=hidden_size, learning_rate=learning_rate) #メインのQネットワーク 121targetQN = QNetwork(hidden_size=hidden_size, learning_rate=learning_rate) #価値を計算するQネットワーク 122memory = Memory(max_size=memory_size) 123actor = Actor() 124 125#メイン 126for episode in range(num_episodes): #試行数分繰り返す 127 env.reset() #CartPoleの環境初期化 128 state, reward, done, info = env.step(env.action_space.sample()) #1step目は適当な行動をとる 129 state = np.reshape(state, (1, 4)) #list型のstateを、1行4列の行列に変換(model.pridictに対応するため) 130 episode_reward = 0 131 132 for t in range(max_number_of_steps): #1試行のループ 133 if (islearned == 1) and LENDER_MODE: #学習終了したらCartPoleを描画する 134 env.render() 135 136 action = actor.get_action(state, episode, mainQN) #今の状態に応じて次の行動を決定する 137 next_state, reward, done, info = env.step(action) #行動a_tの実行による、s_{t+1}、R{t}を計算する 138 next_state = np.reshape(next_state, (1, 4)) #list型のstateを、1行4列の行列に変換 139 140 # 報酬を設定し、与える 141 if done: 142 next_state = np.zeros(state.shape) #ステップ終了後、次の状態s_{t+1}はないとして0を代入する 143 if t < 200: 144 reward = -1 #200ステップ以前に倒れたら罰を与える 145 else: 146 reward = 1 #立ったまま200step超えて終了した場合は報酬を与える 147 else: 148 reward = 0 #各ステップで立ってたら報酬は与えない 149 150 episode_reward += reward #合計報酬を更新 151 152 memory.add((state, action, reward, next_state)) #メモリにデータを追加 153 state = next_state #状態更新 154 155 #Qネットワークの重みを学習・更新する 156 if (memory.len() > batch_size) and not islearned: 157 mainQN.replay(memory, batch_size, gamma, targetQN) #targetQNの重みを使ってmainQNの重みを更新 158 159 #1試行終了時の処理 160 if done: 161 total_reward_vec = np.hstack((total_reward_vec[1:], episode_reward)) #報酬を記録 162 print("%d Episode finished after %d time steps / mean %f" % (episode+1, t+1, total_reward_vec.mean())) 163 break 164 165 #複数試行の平均報酬で終了を判断 166 if total_reward_vec.mean() >= goal_average_reward: 167 print("Episode %d train agent successfuly!" % episode+1) 168 islearned = 1 #学習済みフラグを更新 169 isrender = 1 #描画フラグを更新

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問