Q Learning 和SARSA算法

1 Q Learning算法

Q更新公式:

∈-greedy策略

在Q Learning的更新過程中,每一步都要根據當前的state以及Q函數確定一個合適的行動action。這裏有一個如何平衡“經驗”和“探索”的問題。如果完全按照經驗行動,即每次都在Q(state, :)中選擇對應值最大的action,那麼很有可能一直侷限在已有經驗中,難以發現更具價值的新的行爲。但如果智能體只專注於探索新的行爲,即完全隨機地行動,又可能因爲大多數行動都沒有價值,導致學習Q函數的速度很慢。
一種比較簡單的平衡“經驗”和“探索”的方法是採用∈-greedy策略選擇合適的行動。事先設置一個較小的∈值(如∈=0.1),智能體有1-∈的概率根據學習到的Q函數(已有經驗)行動,剩下∈的概率智能體會隨機行動,用於探索新的經驗。例如,∈=0.1時,在90%的情況下,智能體直接選擇使得Q(state, action)最大的action,剩下10%的情況,隨機選擇一個action。

 

2 SARSA(state-action-reward-state-action)

off-policy和on-policy

強化學習中的方法可以分爲off-policy和on-policy兩類。Q Learning算法是一個經典的off-policy方法,而SARSA算法則是on-policy方法。那麼,如何理解這裏的off-policy和on-policy呢?
      在Q Learning中,Q函數的更新和Q[new_state, :].max()有關。在Q[new_state, :]中選出使得Q函數最大的動作,以此來更新Q函數。設這個動作爲max_action。注意,智能體實際有可能並不會執行max_action。因爲在下一個過程中是根據epsilon-greedy方法來選擇策略的,有可能選擇max_action,也有可能並不會選到max_action。而SARSA算法則不同,它用Q[new_state, new_action]結合獎勵等信息更新Q函數。之後,在下一次循環時,智能體必然會執行new_action。
      說Q Learning是一種off-policy算法,是指它在更新Q函數時使用的動作(max_action)可能並不會被智能體用到。又稱SARSA是一種on-policy方法,是指它在更新Q函數時使用的動作(new_action)一定會被智能體所採用。這也是on-policy方法和off-policy方法的主要區別。

 

3 Q Learning和SARSA對比

相比Q Learning算法,SARSA算法更“膽小”。Q Learning算法會使用Q[new_state, :].max()來更新Q值,換句話說,它考慮的是新狀態下可以獲得的最大獎勵,而不去考慮新狀態會帶來的風險。因此,Q Learning算法會更加的激進。相比之下,SARSA算法只是使用Q[new_state, new_action]來更新Q值。在此處的迷宮問題中,SARSA算法會考慮到接近陷阱可能帶來的負收益,因此更傾向於待在原地不動,從而更加難以找到“寶藏”.

 

4 python 實現

q-learning

from __future__ import print_function
import numpy as np
import time
from env import Env


EPSILON = 0.1
ALPHA = 0.1
GAMMA = 0.9
MAX_STEP = 30

np.random.seed(0)

def epsilon_greedy(Q, state):
    if (np.random.uniform() > 1 - EPSILON) or ((Q[state, :] == 0).all()):
        action = np.random.randint(0, 4)  # 0~3
    else:
        action = Q[state, :].argmax()
    return action


e = Env()
Q = np.zeros((e.state_num, 4))

for i in range(200):
    e = Env()
    while (e.is_end is False) and (e.step < MAX_STEP):
        action = epsilon_greedy(Q, e.present_state)
        state = e.present_state
        reward = e.interact(action)
        new_state = e.present_state
        Q[state, action] = (1 - ALPHA) * Q[state, action] + \
            ALPHA * (reward + GAMMA * Q[new_state, :].max())
        e.print_map()
        time.sleep(0.1)
    print('Episode:', i, 'Total Step:', e.step, 'Total Reward:', e.total_reward)
    time.sleep(2)

SARSA

from __future__ import print_function
import numpy as np
import time
from env import Env


EPSILON = 0.1
ALPHA = 0.1
GAMMA = 0.9
MAX_STEP = 50

np.random.seed(1)

def epsilon_greedy(Q, state):
    if (np.random.uniform() > 1 - EPSILON) or ((Q[state, :] == 0).all()):
        action = np.random.randint(0, 4)  # 0~3
    else:
        action = Q[state, :].argmax()
    return action


e = Env()
Q = np.zeros((e.state_num, 4))

for i in range(200):
    e = Env()
    action = epsilon_greedy(Q, e.present_state)
    while (e.is_end is False) and (e.step < MAX_STEP):
        state = e.present_state
        reward = e.interact(action)
        new_state = e.present_state
        new_action = epsilon_greedy(Q, e.present_state)
        Q[state, action] = (1 - ALPHA) * Q[state, action] + \
            ALPHA * (reward + GAMMA * Q[new_state, new_action])
        action = new_action
        e.print_map()
        time.sleep(0.1)
    print('Episode:', i, 'Total Step:', e.step, 'Total Reward:', e.total_reward)
    time.sleep(2)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章