iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
0
AI & Data

強化學習系列 第 22

強化學習筆記 Day 22

前言

昨天提到 TD learning 方法、介紹其思路,以及說明這個方法向之前介紹的兩個方法 (動態規劃、蒙地卡羅) 借鏡之處。今天我們將實作以 TD learning 方法估計狀態價值函數。

實作內容

模擬過程 (SimProc)

昨天提到與蒙地卡羅方法一樣,透過模擬並更新模擬中,所經狀態的狀態價值。以下是自訂的模擬函式:

def SimProc(init_state, init_action, state_value, steps, gamma, alpha, reward, trans_mat):
    state = init_state
    action = init_action
    for step in range(steps):
        # get next infromation
        next_state = np.argmax(trans_mat[:, state, action])
        next_action = np.random.randint(0,4)
        record = [state, next_state, action, reward[next_state]]
        # update state value
        state_value[state] = GetValue(state_value, record, gamma, alpha)
        # update infromation
        state = next_state
        action = next_action
        if state == 0 or state == 15:
            break
    return state_value

這裡有幾個地方值得注意:

  • 由於尚未說明與策略相關的內容,所以動作皆隨機產生。
  • 狀態價值在模擬過程中持續更新,與之相比,蒙地卡羅方法完成一個 episode 後更新狀態價值。
  • GetValue 為自訂函數,以下說明。

計算價值 (GetValue)

在計算價值的地方,TD learning 採用動態規劃方法的逼近方式,這邊使用昨天推論出的更新方法,更新狀態價值:

def GetValue(state_value, records, gamma, alpha):
    state = records[0]
    next_state = records[1]
    action = records[2]
    reward = records[3]
    value = state_value[state] + alpha*(reward + gamma*state_value[next_state] - state_value[state])
    return value

除了多了參數 https://chart.googleapis.com/chart?cht=tx&chl=%5Calpha 需要設定,這邊並沒有特別需要注意的地方。

主函式 (main)

最後我們設定 GridWorld 環境與模擬相關的參數,這裡新增一個 https://chart.googleapis.com/chart?cht=tx&chl=%5Calpha 參數,代表更新的比率,這邊我們設定 0.05。其餘的參數請見主函式:

def main(InitState, InitAction, Episodes):
    # environment setting
    StateValue = np.zeros([16])
    Reward = np.full(16, -1)
    Reward[0] = 0
    Reward[-1] = 0
    TransMat = np.load('./gridworld/T.npy')
    # parameters
    GAMMA = 0.99
    ALPHA = 0.05
    STEPS = 50

    # execute
    for episode in range(Episodes):
        StateValue = SimProc(InitState, InitAction, StateValue, STEPS, GAMMA, ALPHA, Reward, TransMat)
        PrintValue(StateValue, episode)
        #time.sleep(1)

如果想要有慢慢更新的感覺,請將最後一行的 '#time.sleep(1)' 中,去掉 '#'。
完整程式請見 GitHub

實驗結果

這邊進行模擬的結果如下:

============================================================
[State-Value]
Episode: 1000
[[  0.          -8.91641221 -14.0491088  -15.2773621 ]
 [ -9.67885868 -12.95041551 -14.37948861 -14.07001144]
 [-14.60779153 -14.85819826 -13.01810753  -7.45157775]
 [-16.86235211 -14.72329853  -9.31593479   0.        ]]
============================================================

我們可以觀察到,「狀態價值」與「該位置和終點的距離」,符合我們的期待與過去方法的結果。那麼,有了狀態價值後,我們就得開始考慮怎麼控制了。


上一篇
強化學習筆記 Day 21
下一篇
強化學習筆記 Day 23
系列文
強化學習30

尚未有邦友留言

立即登入留言