Python(強化学習の試し03_過去の試行3つ分で学習2)
■学習するコードの改善。
何となく学習されているようだけど結果が芳しくなかったので、学習するコードを改善する。
条件は下のもの。
・ボタン(0と1)がある状態で、どちらかを押す想定。
・0を押した後に1を押すと報酬として1が追加される。
・試行は10回。これを1エピソードとする。
過去3つ分の結果を強化学習の環境として取得する場合、8つの状況がある。3つ前、2つ前、1つ前で押した値を2進数と見なして、0~7のラベルを付ける。
前回の学習コードでは、ε-greedy法を省略していたしQ値の更新部分も正しくなかった。改善したコードが下の通り。
class GenAction():
def __init__(self):
self._Qtable = np.zeros((8, 2))
def getAction(self, history, epsilon):
val = 0
action = 0
if (len(history) >= 3):
if epsilon > np.random.uniform(0, 1):
action = np.random.choice([0, 1])
else:
for i in range(len(history)):
if len(history) - i <= 3:
val = val + (history[i] * 2 ** ((len(history) - i - 1)))
a = np.where(self._Qtable[val] == self._Qtable[val].max())[0]
action = np.random.choice(a)
else:
action = np.random.choice([0, 1])
return action
def updateSelectAction(self, curhistory, action, reward, history):
gamma = 0.9
alpha = 0.7
val = 0
next_val = 0
if (len(curhistory) >= 3):
for i in range(len(curhistory)):
if len(curhistory) - i <= 3:
val = val + (curhistory[i] * 2 ** ((len(curhistory) - i - 1)))
for i in range(len(history)):
if len(history) - i <= 3:
next_val = next_val + (history[i] * 2 ** ((len(history) - i - 1)))
next_maxQ = max(self._Qtable[next_val])
self._Qtable[val, action] = (1 - alpha) * self._Qtable[val, action] + alpha * (
reward + gamma * next_maxQ)
return self._Qtable
ここでは、ε-greedy法として1.0から0までの直線を使う。一番初めは1.0で、0~1.0からランダムな値を取得し、この閾値以下ならランダムなActionをとる。閾値以上なら、Q値に基づいたActionをとる。後の試行の方がQ値に基づいたActionとなる確率が高くなる。Q値は、縦(状況8通り)x 横(Action2通り)の行列であり、Q値に基づいたActionをとる際に、ある状況に対してQ値が高い方のActionが選択されるよう。この値は都度更新されていく。
200エピソード行い、Q値を更新した結果が下のもの。縦8×横2の行列で、左側が0を押すAction、右側が1を押すAction、上から上の表のVal 0~7 に対応する。ここで、Val が0、2、4、6の時に5.2631と1を押すActionを取る。1、3、5、7では、4.7368と0を押すActionを取る。
200分のエピソードとそれぞれのRewardの結果をグラフにすると下のようになった。0, 1の組み合わせでRewardが1追加されるので、最大は[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] の5となる。Q値に基づくActionの選択は試行回数が3以上でなければできなくしているので、必ず5になるわけではないが、学習が進むにつれてRewardの成績が良くなっている。
ちなみに完全にランダムでActionを選択すると、下のグラフになった。ランダムでRewardが5になる確率は、2^8 = 256 分の1 なので、200エピソードであれば1度も出ないことは不思議ではない。
試行回数やRewardが出る条件を変えてもう少し試してみる。