2019.12.09

2019.12.09

一、動態規劃 之 策略迭代

看懂值迭代的代碼之後,策略迭代變得簡單了許多,策略迭代主要包括:策略評估策略改進

策略迭代的步驟如下:
1.初始化隨機策略。
2.求得隨機策略下的值函數,並判斷其是否爲當下策略的最優,直到得到當下策略的最優值函數。
3.根據得到的當下策略的最優值函數,得到新的策略。
4.判斷新的策略是否爲最優(即判斷新舊策略是否相同)。(2.3.4步爲策略評估
5.如果不是最優,不斷進行迭代。(策略改進
6.重複2~5步,直到找到最優策略。

詳細代碼及細節如下:

import numpy as np
import gym

env = gym.make('FrozenLake-v0')

env.render()

# 根據給定的策略Π計算值函數V(s)
def compute_value_function(policy, gamma = 1.0):

    # initialize value table with zeros
    value_table = np.zeros(env.nS)

    # 設置學習速率
    threshold = 1e-10

    while True:

        # copy the value table to the updated_value_table
        updated_value_table = np.copy(value_table)

        # 對每一個狀態s,根據給定的策略計算值函數
        for state in range(env.nS):
            action = policy[state]

            # 計算某個確定狀態s下,策略所選定的確定的動作a的值
            value_table[state] = sum([trans_prob * (reward_prob + gamma * updated_value_table[next_state])
                                      for trans_prob, next_state, reward_prob, _ in env.P[state][action]])

        if (np.sum(np.fabs(updated_value_table - value_table)) <= threshold):
            break

    return value_table


# 根據給定的值函數V(s)計算策略Π
# 根據值函數V(s),計算出每個狀態s下的每個行爲a∈A的Q value,並選擇具有最大Q value的行爲作爲s的策略。
def extract_policy(value_table, gamma = 1.0):

    # initialize the policy with zeros
    policy = np.zeros(env.observation_space.n)

    # 計算每個狀態s∈S
    for state in range(env.observation_space.n):

        # initialize the Q table for a state
        Q_table = np.zeros(env.action_space.n)

        # 計算具體某個狀態s的每個a∈A
        for action in range(env.action_space.n):

            # 計算具體某個a的每個s'∈S
            for next_sr in env.P[state][action]:

                # 獲取具體(s, a)的,各個s'∈S的概率、獎勵以及下個狀態s'是什麼
                trans_prob, next_state, reward_prob, _ = next_sr
                Q_table[action] += (trans_prob * (reward_prob + gamma * value_table[next_state]))

        # 把Q value的最大值的索引(即代表某個動作或策略)賦給policy
        policy[state] = np.argmax(Q_table)

    return policy


# 執行整體策略迭代
# 判斷是否達到最佳策略
def policy_iteration(env, gamma = 1.0):

    #initial policy with zeros
    old_policy = np.zeros(env.observation_space.n)
    no_of_iterations = 200000

    for i in range(no_of_iterations):

        # 計算新的值函數
        new_value_function = compute_value_function(old_policy, gamma)

        # 根據新的值函數得到新的策略
        new_policy = extract_policy(new_value_function, gamma)

        # 判斷是否達到最佳策略
        if (np.all(old_policy == new_policy)):
            print('到第 %d 步達到最優' %(i+1))
            break
        old_policy = new_policy

    return new_policy


print(policy_iteration(env))



針對以上代碼,有如下筆記:
1.python中sum()的用法
2.經實測,一下兩段代碼效果相同:

# 對每一個狀態s,根據給定的策略計算值函數
for state in range(env.nS):
    action = policy[state]

    #計算某個確定狀態s下,策略所選定的確定的動作a的值
    value_table[state] = sum([trans_prob * (reward_prob + gamma * updated_value_table[next_state])
                              for trans_prob, next_state, reward_prob, _ in env.P[state][action]])
# 對每一個狀態s,根據給定的策略計算值函數
for state in range(env.nS):
    action = policy[state]
    next_states_rewards = []

    # 對具體某次循環的某個具體的(s, a),對每個s'∈S進行循環。
    for next_sr in env.P[state][action]:
    
        # 獲取具體(s, a)的,各個s'∈S的概率、獎勵以及下個狀態s'是什麼
        trans_prob, next_state, reward_prob, _ = next_sr
        next_states_rewards.append((trans_prob * (reward_prob + gamma * updated_value_table[next_state])))

    value_table[state] = np.sum([next_states_rewards])

對值DP算法的值迭代和策略迭代,有以下說明:
以上兩段算法的代碼是以冰凍湖爲例,是在狀態轉移概率p和獎勵r已知的前提下編寫的。這也是動態規劃算法的缺點之一,必須要事先知道轉移概率和獎勵

二、MDP建模示例

將冰凍湖問題建模爲MDP:(可參考《python強化學習實戰》)
1.定義狀態、行爲、轉移概率、獎勵、策略函數、值函數和Q函數。
2.利用Bellman最優方程,表示值函數和Q函數,求解該方程即可得到最優策略。
3.採用動態規劃的方法來求解Bellman最優方程。

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