強化学習 探索と利用のジレンマを解決する ε-greedyアルゴリズムとは?
こんにちは!
ぷもんです。
以前、強化学習 Q学習をコードにすると?というnoteで
Q学習をできるようにしてやっと強化学習を始めることができました。
ただ、Q学習だけでは学ぶ仕組みはできたけど
なかなか学習が進まず、学習を進めるためにさらに工夫していく必要があります。
うまくいかない1つの原因が
探索と利用のジレンマ(exploration-exploitation dilemma)
と呼ばれるものです。
探索とは「色々やってみること」
利用とは「探索で得た知識を使って行動すること」です。
前回までの状態だと
利用する機能は作れたのですが探索が足りません。
探索が足りないと初めの選択肢が狭まったまま利用してしまうので
狭い範囲からしか選択肢が選べず
最適な行動にたどり着くことができないのです。
これを解決するのがε-greedyアルゴリズムと呼ばれるものです。
どんなものなのかはコードを理解しながら理解します。
今回はこちらのコードをやります。
def get_action(state, action, observation, reward):
next_state = digitize_state(observation)
epsilon = 0.2
if epsilon <= np.random.uniform(0, 1):
next_action = np.argmax(q_table[next_state])
else:
next_action = np.random.choice([0, 1])
alpha = 0.2
gamma = 0.99
q_table[state, action] = (1 - alpha) * q_table[state, action] +\
alpha * (reward + gamma * q_table[next_state, next_action])
return next_action, next_state
前回やったQ学習のコードがこちらです。
def get_action(state, action, observation, reward):
next_state = digitize_state(observation)
next_action = np.argmax(q_table[next_state])
alpha = 0.2
gamma = 0.99
q_table[state, action] = (1 - alpha) * q_table[state, action] +\
alpha * (reward + gamma * q_table[next_state, next_action])
return next_action, next_state
比較してみると半分ぐらいは同じですが
next_actionを決める部分が追加されていることがわかります。
つまり、ここの部分が分かればいいわけです。
epsilon = 0.2
if epsilon <= np.random.uniform(0, 1):
next_action = np.argmax(q_table[next_state])
else:
next_action = np.random.choice([0, 1])
・if elseってなんや?
if elseは
if 条件式:
条件式を満たす時に行う行動
else:
条件式を満たさない時に行う行動
のように書いて条件で行動を分岐させる時に使います。
今回の場合
条件式→epsilon <= np.random.uniform(0, 1)
条件を満たす時に行う行動→next_action = np.argmax(q_table[next_state])
条件式を満たさない時に行う行動→next_action = np.random.choice([0, 1])
となります。
・以前やったことのある部分
np.random.uniformは以前
強化学習に必要な「Qテーブル」と「離散値で表す関数」をつくるには?
でも使ったことがありますが
np.random.uniform(low, high)で
low以上high未満の一様乱数(ランダムな数)をつくる関数です。
(ちなみに以前使った時はsizeの項目もあって
何個作るかという指定もしていました。)
next_action = np.argmax(q_table[next_state])
は以前の強化学習 Q学習をコードにすると?でやったコードのままで
Qテーブル(表みたいなもの)の中から
状態が1番いいものが何番目の要素なのか?を
出していることがわかります。
・np.random.choiceってなんや?
np.random.uniformと似ていますが少し違うのが
np.random.choiceです。
np.random.choice([ ])は([ ])の中の値から
ランダムで数を選ぶもので
今回の場合は([0, 1])となっているので
0と1からランダムに数を選びます。
・つまり...
epsilon = 0.2
if epsilon <= np.random.uniform(0, 1):
next_action = np.argmax(q_table[next_state])
else:
next_action = np.random.choice([0, 1])
では
epsilon(今回は0.2)よりも
0以上1未満の一様乱数(ランダムな数)が大きい場合
next_actionは
Qテーブル(表みたいなもの)の中から
状態が1番いいものを使い
epsilon(今回は0.2)よりも
0以上1未満の一様乱数(ランダムな数)が大きくない場合
next_actionは
0と1からランダムに選ぶ。
今回扱っているCartPoleでは0と1で左右を扱っているので
ランダムに左右どちらに進むのかを選んでいることがわかります。
・さらに...
初めに書いた探索と利用のジレンマの話と合わせて理解すると
Qテーブル(表みたいなもの)の中から状態が1番いいものを使う
のが利用の行動
ランダムに左右どちらに進むのかを選ぶ
のが探索の行動になっているのがわかります。
どちらの行動をするのか決めるのが
epsilon <= np.random.uniform(0, 1)
というεの値をもとにする条件式で
ε-greedyアルゴリズムと呼ばれるのも理解できると思います。
今回は強化学習を改善するために解決しないといけない
探索と利用のジレンマと
それを解決するためのε-greedyアルゴリズム
について書きました。
初めは難しそうだなと思いましたが
1つずつ理解していくと意外と簡単でしたね!
参考にしたサイトはこちらです!
最後まで読んでいただきありがとうございました。
ぷもんでした!