無意中發現了一個巨牛的人工智能教程,忍不住分享一下給大家。教程不僅是零基礎,通俗易懂,而且非常風趣幽默,像看小說一樣!覺得太牛了,所以分享給大家。點這裏可以跳轉到教程。人工智能教程
強化學習是一類算法,是讓計算機從什麼都不懂,腦袋裏一點想法都沒有,通過不斷地嘗試,從錯誤中學習,最後找到規律,學習到達到目標的方法。這就是一個完整的強化學習過程。
如爲了實現自走的路徑,並儘量避免障礙,設計一個路徑。
如圖所示,當機器人在圖中的任意網格中時,怎樣讓它明白周圍環境,最終到達目標位置。
Q-learning的想法
獎賞機制
在一個陌生的環境中,機器人首先的方向是隨機選擇的,當它從起點開始出發時,選擇了各種各樣的方法,完成路徑。但是在機器人碰到紅色方塊後,給予懲罰,則經過多次後,機器人會避開懲罰位置。當機器人碰到藍色方塊時,給予獎賞,經過多次後,機器人傾向於跑向藍色方塊的位置。
具體公式
完成獎賞和懲罰的過程表達,就是用值表示吧。
首先建立的表是空表的,就是說,如下這樣的表是空的,所有值都爲0:
在每次行動後,根據獎懲情況,更新該表,完成學習過程。在實現過程中,將獎懲情況也編製成一張表。表格式如上圖類似。
Q-table:
left right up down
0 0.000000 29.131876 0.000000 29.131876
1 27.218688 31.245833 0.000000 31.257640
2 29.131876 33.558380 0.000000 33.611442
3 30.892266 21.891451 0.000000 36.224813
4 23.744314 0.000000 0.000000 26.811900
5 0.000000 31.257640 27.218688 31.257640
6 29.131876 33.619599 29.131876 33.619600
7 31.257640 36.244000 30.919118 25.244000
8 33.618194 28.148718 33.038027 39.160000
9 35.168930 0.000000 18.353572 42.399996
10 5.375851 33.619600 29.131876 22.619600
11 31.257640 25.244000 31.257640 36.244000
12 33.619600 39.160000 33.618893 28.160000
13 25.244000 42.399998 36.243967 42.400000
14 39.159509 0.000000 28.143890 46.000000
15 0.000000 36.244000 31.257640 36.244000
16 22.619600 28.160000 33.619600 39.160000
17 36.244000 42.400000 25.244000 42.400000
18 28.160000 45.999999 39.160000 46.000000
19 42.399834 0.000000 40.733374 50.000000
20 0.000000 39.160000 22.619600 0.000000
21 36.244000 42.400000 36.244000 0.000000
22 39.160000 46.000000 37.160000 0.000000
23 42.400000 50.000000 42.400000 0.000000
24 0.000000 0.000000 0.000000 0.000000
而獎懲更新公式爲:
貝爾曼方程:
其中的 表示當前的Q表,就是上圖25行4列的表單。 表示學習率, 表示下一次行爲會得到的獎懲情況, 表示一個貪婪係數,在這裏的公式中,就是說,如果它的數值比較大,則更傾向於對遠方的未來獎賞。
實現代碼:
import numpy as np
import pandas as pd
import time
N_STATES = 25 # the length of the 2 dimensional world
ACTIONS = ['left', 'right','up','down'] # available actions
EPSILON = 0.3 # greedy police
ALPHA = 0.8 # learning rate
GAMMA = 0.9 # discount factor
MAX_EPISODES = 100 # maximum episodes
FRESH_TIME = 0.00001 # fresh time for one move
# 創建Q表
def build_q_table(n_states, actions):
table = pd.DataFrame(
np.zeros((n_states, len(actions))), # q_table initial values
columns=actions, # actions's name
)
return table
# 行爲選擇
def choose_action(state, q_table):
state_actions = q_table.iloc[state, :]
if (np.random.uniform() > EPSILON) or ((state_actions == 0).all()): # act non-greedy or state-action have no value
if state==0:
action_name=np.random.choice(['right','down'])
elif state>0 and state<4:
action_name=np.random.choice(['right','down','left'])
elif state==4:
action_name=np.random.choice(['left','down'])
elif state==5 or state==15 or state==10 :
action_name=np.random.choice(['right','up','down'])
elif state==9 or state==14 or state==19 :
action_name=np.random.choice(['left','up','down'])
elif state==20:
action_name=np.random.choice(['right','up'])
elif state>20 and state<24:
action_name=np.random.choice(['right','up','left'])
elif state==24:
action_name=np.random.choice(['left','up'])
else:
action_name=np.random.choice(ACTIONS)
else: # act greedy
action_name = state_actions.idxmax() # replace argmax to idxmax as argmax means a different function in newer version of pandas
return action_name
# 獎賞表達
def get_init_feedback_table(S,a):
tab=np.ones((25,4))
tab[8][1]=-10
tab[4][3]=-10
tab[14][2]=-10
tab[11][1]=-10
tab[13][0]=-10
tab[7][3]=-10
tab[17][2]=-10
tab[16][0]=-10
tab[20][2]=-10
tab[10][3]=-10
tab[18][0]=-10
tab[16][1]=-10
tab[22][2]=-1
tab[12][3]=-10
tab[23][1]=50
tab[19][3]=50
print(tab)
return tab[S,a]
# 獲取獎懲
def get_env_feedback(S, A):
action={'left':0,'right':1,'up':2,'down':3}
R=get_init_feedback_table(S,action[A])
if (S==19 and action[A]==3) or (S==23 and action[A]==1):
S = 'terminal'
return S,R
if action[A]==0:
S-=1
elif action[A]==1:
S+=1
elif action[A]==2:
S-=5
else:
S+=5
return S, R
def rl():
# main part of RL loop
q_table = build_q_table(N_STATES, ACTIONS)
# print(q_table)
for episode in range(MAX_EPISODES):
S = 0
is_terminated = False
while not is_terminated:
A = choose_action(S, q_table)
S_, R = get_env_feedback(S, A) # take action & get next state and reward
if S_ != 'terminal':
q_target = R + GAMMA * q_table.iloc[S_, :].max() # next state is not terminal
else:
# print(1)
q_target = R # next state is terminal
is_terminated = True # terminate this episode
q_table.loc[S, A] += ALPHA * (q_target - q_table.loc[S, A]) # update
S = S_ # move to next state
return q_table
if __name__ == "__main__":
q_table = rl()
print('\r\nQ-table:\n')
print(q_table)