在上一篇的強韌學習中,可以看到行為 (action) 的主要還是依據 Q-Table 的最大數值來決定;而 Q-Table 中的數值是依照過去的行為經驗累積而來;在經驗累積的過程中,每次單純累計回饋 (reward) 的數值;所以,可以觀察到最後形成的 Q-Table 各個數值內容會逐漸地累計而出現離散而極端的差異;這樣的現象,會使得愈後面訓練的回饋數值相較於 Q-Table 的數值,影響力愈來愈小;因此,在建立 Q-Table 時,要儘量將不同時間加入的回饋值對 Q-Table 有一定的影響。
作法上可以除了回饋 (reword) 值以外,再將 Q-Table 中的最大值,作為加權相加;接下來,在建立 Q-Table 時,將以上的加權相加值打折後加入 Q-Table,作為數值平滑過濾,來減少 Q-Table 極端值產生,例如:
maxValue=1.0+0.8*np.max(qtable[observation,:])
qtable[observation,action]+=0.2*(maxValue-qtable[observation,action])
所以完整的訓練程式可以寫成:
import numpy as np
qtable=np.zeros((16,4))
#--------------
np.random.seed(13)
epochs=2000
for epoch in range(epochs):
state=env.reset()
path=[]
terminated=False
while (not terminated):
action=np.random.randint(4)
path.append(action)
observation, reward, terminated,_,_=env.step(action)
if(reward>0):
env.reset()
for j in range(len(path)):
action=path[j]
observation,_,_,_,_=env.step(action)
#----------------------
maxValue=1.0+0.8*np.max(qtable[observation,:])
qtable[observation,action]+=0.2*(maxValue-qtable[observation,action])
#----------------------
# print('successful path:',path)
print('table:',qtable)
#-------
np.save('qtable',qtable)
再用測試程式執行
qtable=np.load('qtable.npy')
np.random.seed(13)
epochs=400
for epoch in range(epochs):
env.reset()
observation=0
path=[]
terminated=False
while (not terminated):
dice=np.random.randint(6)
if(dice>2):
action=np.argmax(qtable[observation,:])
else:
action=np.random.randint(4)
path.append(action)
observation, reward, terminated,_,_=env.step(action)
if(reward>0):
print('successful path:',path)
我們可以發現,增加了訓練的學習能力之後,成功完成的次數又再增加;由原來 400 次的嘗試成功 8 次,增加到 12 次;約 50%的成功。
另一方面,如果可同時進行訓練及測試程式,每次的測試結果都可以不斷地進行學習,可以更進一步增加強韌學習的效率;因此可以將程式再更新如下:
import numpy as np
qtable=np.zeros((16,4))
#--------------
np.random.seed(13)
epochs=400
for epoch in range(epochs):
env.reset()
observation=0
path=[]
terminated=False
inDB=False
while (not terminated):
dice=np.random.randint(6)
if not inDB:
dice=0
if(dice>2):
action=np.argmax(qtable[observation,:])
else:
action=np.random.randint(4)
path.append(action)
observation, reward, terminated,_,_=env.step(action)
if(reward>0):
inDB=True
env.reset()
for j in range(len(path)):
action=path[j]
observation,_,_,_,_=env.step(action)
#----------------------
maxValue=1.0+0.8*np.max(qtable[observation,:])
qtable[observation,action]+=0.2*(maxValue-qtable[observation,action])
#----------------------
print('successful path:',path)
print('table:',qtable)
透過同步學習及測試的作法,既使只有 400 次的嘗試,也會由原來的僅有一次成功的結果,增加到 8 次成功結果;更重要的是,可以從原來累計學習成功的結果,加入成為學習的輸入,也就是「自我學習」的效果。