強化學習是代理面臨的學習問題,它經過與動態環境反覆交互試驗從而學習到某種行爲。它是機器學習的主要學習方法之一,智能體從環境到行爲的學習,也就是如何在環境中採起一些列行爲,才能使得回報信號函數的值最大,即得到的累積回報最大。mysql
如今強化學習與深度學習結合的深度強化學習更增強大。git
在理解強化學習以前,咱們先了解咱們要解決什麼樣的問題。其實強化學習過程就是優化馬爾科夫決策過程,它由一個數學模型組成,該模型在代理的控制下對隨機結果進行決策。github
代理能夠執行某些動做,例如上下左右移動,這些動做可能會獲得一個回報,回報能夠是正數也能夠是負數,它會致使總分數變更。同時動做能夠改變環境並致使一個新的狀態,而後代理能夠執行另一個動做。狀態、動做和回報的集合、轉換規則等,構成了馬爾科夫決策過程。sql
強化學習訓練主要就是計算各個狀態下不一樣動做的回報,並不是瞬間完成的,而是要通過大量嘗試。下一個狀態取決於當前狀態和動做,而且狀態不依賴於先前的狀態,沒有記憶,符合馬爾可夫性。數組
強化學習是agent與環境之間的迭代交互,須要考慮幾點:bash
Q學習便是學習不一樣狀態下各個動做的質量,它定義爲網絡
它一樣能夠變換成Bellman Equation形態,併發
最優動做價值函數,app
能夠看到最大化當前的動做價值函數就是最大化當前回報和下一時刻狀態的最優動做價值函數。dom
動做價值函數雖然能直接計算出Q值,但實際學習時並無直接使用該Q值來更新,而是經過漸進的方式來更新。學習的方法可用以下僞代碼說明,首先初始化Q學習的狀態集和動做集組成的數組,而後觀察初始狀態,接着不斷重複執行:選擇一個動做,觀察回報並轉移到新狀態,更新Q學習數組值,涉及迭代方式更新,因爲咱們不能知道下一刻狀態的Q值,因此更新時用以前迭代的Q值來更新這次迭代的Q值,其中α表示學習率。
initialize Q[numstates,numactions] arbitrarily
observe initial state s
repeat
select and carry out an action a
observe reward R and new state s' Q[s,a] = Q[s,a] + α(R + γmaxa'Q[s',a'] - Q[s,a])
s = s' until terminated 複製代碼
有個小遊戲,以下圖,進入入口後初始位置爲A,陰影部分表示大炕,踩進去就沒命了得重來,操做能夠上下左右,最終走到H位置就算勝利。
先定義地圖的大小,以及大坑的位置、入口和出口。
ROWS = 5
COLUMNS = 6
ENTRANCE = (0, 0)
EXIT = (4, 5)
BARRIERS = list()
BARRIERS.append((1, 1))
BARRIERS.append((2, 1))
BARRIERS.append((3, 1))
BARRIERS.append((4, 1))
BARRIERS.append((0, 3))
BARRIERS.append((1, 3))
BARRIERS.append((3, 3))
BARRIERS.append((4, 3))
BARRIERS.append((3, 4))
BARRIERS.append((1, 5))
複製代碼
定義Q學習的一些參數設置,TIMES爲嘗試次數,R爲隨機因子,ALPHA爲學習率,GAMMA爲折扣因子,q_values爲q值表,results爲最終結果。
TIMES = 200
R = 0.05
ALPHA = 0.1
GAMMA = 0.9
q_values = dict()
results = list()
複製代碼
初始化q值表,按照行數列數和動做初始化全部q值。
def init_q_values():
for row in range(0, ROWS):
for col in range(0, COLUMNS):
state = State(row, col)
for action in Actions:
q = (state.row, state.col, action)
q_values[q] = 0
複製代碼
定義某個狀態執行某個動做後獲得的新狀態,其中要考慮到地圖的邊緣。
def move(curr_state, action):
new_state = State(curr_state.row, curr_state.col)
# check borders
if action == Actions.up:
if (new_state.row - 1) >= 0:
new_state.row -= 1
elif action == Actions.down:
if (new_state.row + 1) <= (ROWS - 1):
new_state.row += 1
elif action == Actions.left:
if (new_state.col - 1) >= 0:
new_state.col -= 1
elif action == Actions.right:
if (new_state.col + 1) <= (COLUMNS - 1):
new_state.col += 1
return new_state
複製代碼
定義每一步的探索方法,分別執行不一樣動做找到最優的動做,此外還須要有必定機率的隨機動做選擇。
def explore(curr_state):
rand = random.random()
if rand <= R:
return random.choice(list(Actions))
else:
best = list()
best_action = Actions.up
best_value = -10000000
for action in Actions:
q = (curr_state.row, curr_state.col, action)
if q_values[q] > best_value:
best_action = action
best_value = q_values[q]
best.append(best_action)
# perhaps it has not only one best action
for action in Actions:
q = (curr_state.row, curr_state.col, action)
if action != best_action:
if q_values[q] == best_value:
best.append(action)
return random.choice(best)
複製代碼
定義更新狀態操做,一旦選出最優的動做後將進行狀態的更新,也就是更新q值表,若是到達出口則回報爲0,若是掉入大坑則回報爲-100。
def update(curr_state, last_action):
q = (curr_state.row, curr_state.col, last_action)
new_state = move(curr_state, last_action)
position = (new_state.row, new_state.col)
reward = -1
if position == EXIT:
reward = 0
elif position in BARRIERS:
reward = -100
old_value = q_values[q]
max_new = max([q_values[(new_state.row, new_state.col, a)] for a in Actions])
q_values[q] = old_value + ALPHA * (reward + (GAMMA * max_new) - old_value)
curr_state.row = new_state.row
curr_state.col = new_state.col
複製代碼
好比咱們訓練200次後,最終根據q值表就能夠找到最佳的執行動做序列以下,說明通過這些動做操做後能成功到達出口。
Actions.right
Actions.right
Actions.down
Actions.down
Actions.right
Actions.right
Actions.right
Actions.down
Actions.down
Actions.down
複製代碼
-------------推薦閱讀------------
個人開源項目彙總(機器&深度學習、NLP、網絡IO、AIML、mysql協議、chatbot)
跟我交流,向我提問:
歡迎關注: