強化學習-Q-learning
原文:https://www.jianshu.com/p/29db50000e3f?utm_medium=hao.caibaojian.com&utm_source=hao.caibaojian.com
1、Q-learning例子
假設有這樣的房間
如果將房間表示成點,然後用房間之間的連通關係表示成線,如下圖所示:
這就是房間對應的圖。我們首先將agent(機器人)處於任何一個位置,讓他自己走動,直到走到5房間,表示成功。為了能夠走出去,我們將每個節點之間設定一定的權重,能夠直接到達5的邊設定為100,其他不能的設定為0,這樣網路的圖為:
Qlearning中,最重要的就是“狀態”和“動作”,狀態表示處於圖中的哪個節點,比如2節點,3節點等等,而動作則表示從一個節點到另一個節點的操作。
首先我們生成一個獎勵矩陣矩陣,矩陣中,-1表示不可以通過,0表示可以通過,100表示直接到達終點:
同時,我們建立一個Q表,表示學習到的經驗,與R表同階,初始化為0矩陣,表示從一個state到另一個state能獲得的總的獎勵的折現值。
image.png
Q表中的值根據如下的公式來進行更新:
在上面的公式中,S表示當前的狀態,a表示當前的動作,s表示下一個狀態,a表示下一個動作,λ為貪婪因子,0<λ<1,一般設定為0.8。Q表示的是,在狀態s下采取動作a能夠獲得的期望最大收益,R是立即獲得的收益,而未來一期的收益則取決於下一階段的動作。
所以,Q-learning的學習步驟可以歸結為如下:
在迭代到收斂之後,我們就可以根據Q-learning來選擇我們的路徑走出房間。
看一個實際的例子,首先設定λ=0.8,獎勵矩陣R和Q矩陣分別初始化為:
隨機選擇一個狀態,比如1,檢視狀態1所對應的R表,也就是1可以到達3或5,隨機地,我們選擇5,根據轉移方程:
於是,Q表為:
這樣,到達目標,一次嘗試結束。
接下來再選擇一個隨機狀態,比如3,3對應的下一個狀態有(1,2,4都是狀態3對應的非負狀態),隨機地,我們選擇1,這樣根據演算法更新:
這樣,Q表為:
經過不停的迭代,最終我們的Q表為:
我們不妨將Q表中的數轉移到我們一開始的示意圖中:
在得到Q表之後,我們可以根據如下的演算法來選擇我們的路徑:
舉例來說,假設我們的初始狀態為2,那麼根據Q表,我們選擇2-3的動作,然後到達狀態3之後,我們可以選擇1,2,4。但是根據Q表,我們到1可以達到最大的價值,所以選擇動作3-1,隨後在狀態1,我們按價值最大的選擇選擇動作1-5,所以路徑為2-3-1-5.
2、程式碼實現
上面的例子可以用下面的程式碼來實現,非常的簡單,直接貼上完整的程式碼吧:
import numpy as np
import random
r = np.array([[-1, -1, -1, -1, 0, -1], [-1, -1, -1, 0, -1, 100], [-1, -1, -1, 0, -1, -1], [-1, 0, 0, -1, 0, -1],
[0, -1, -1, 0, -1, 100], [-1, 0, -1, -1, 0, 100]])
q = np.zeros([6,6],dtype=np.float32)
gamma = 0.8
step = 0
while step < 1000:
state = random.randint(0,5)
if state != 5:
next_state_list=[]
for i in range(6):
if r[state,i] != -1:
next_state_list.append(i)
next_state = next_state_list[random.randint(0,len(next_state_list)-1)]
qval = r[state,next_state] + gamma * max(q[next_state])
q[state,next_state] = qval
print(q)
print(q)
# 驗證
for i in range(10):
print("第{}次驗證".format(i + 1))
state = random.randint(0, 5)
print('機器人處於{}'.format(state))
count = 0
while state != 5:
if count > 20:
print('fail')
break
# 選擇最大的q_max
q_max = q[state].max()
q_max_action = []
for action in range(6):
if q[state, action] == q_max:
q_max_action.append(action)
next_state = q_max_action[random.randint(0, len(q_max_action) - 1)]
print("the robot goes to " + str(next_state) + '.')
state = next_state
count += 1
程式碼的輸出為:
參考資料:
http://mnemstudio.org/path-finding-q-learning-tutorial.htm
https://www.zhihu.com/question/26408259
https://zhuanlan.zhihu.com/p/29213893