91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用actor-critic方法來控制CartPole-V0游戲

發布時間:2023-04-18 17:47:43 來源:億速云 閱讀:107 作者:iii 欄目:開發技術

本篇內容主要講解“怎么使用actor-critic方法來控制CartPole-V0游戲”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么使用actor-critic方法來控制CartPole-V0游戲”吧!

CartPole 介紹

在一個光滑的軌道上有個推車,桿子垂直微置在推車上,隨時有倒的風險。系統每次對推車施加向左或者向右的力,但我們的目標是讓桿子保持直立。桿子保持直立的每個時間單位都會獲得 +1 的獎勵。但是當桿子與垂直方向成 15 度以上的位置,或者推車偏離中心點超過 2.4 個單位后,這一輪局游戲結束。因此我們可以獲得的最高回報等于 200 。我們這里就是要通過使用 PPO 算法來訓練一個強化學習模型 actor-critic ,通過對比模型訓練前后的游戲運行 gif 圖,可以看出來我們訓練好的模型能長時間保持桿子處于垂直狀態。

Actor Critic 介紹

當 agent 采取行動并在環境中移動時,它在觀察到的環境狀態的情況下,學習兩個可能的輸出:

  • 接下來最合適的一個操作,actor 負責此部分輸出。

  • 未來可能獲得的獎勵總和,critic 負責此部分的輸出。

actor 和 critic 通過不斷地學習,以便使得 agent 在游戲中最終獲得的獎勵最大,這里的 agent 就是那個小車。

庫準備

tensorflow-gpu==2.10.0
imageio==2.26.1
keras==2.10,0
gym==0.20.0
pyglet==1.5.20
scipy==1.10.1

設置超參數

這部分代碼主要有:

(1)導入所需的Python庫:gym、numpy、tensorflow 和 keras。

(2)設置整個環境的超參數:種子、折扣因子和每個回合的最大步數。

(3)創建 CartPole-v0 環境,并設置種子。

(4)定義一個非常小的值 eps ,表示的機器兩個不同的數字之間的最小差值,用于檢驗數值穩定性。

import gym # 導入Gym庫,用于開發和比較強化學習算法
import numpy as np # 導入NumPy庫,用于進行科學計算
import tensorflow as tf # 導入TensorFlow庫
from tensorflow import keras # 導入keras模塊,這是一個高級神經網絡API
from tensorflow.keras import layers # 導入keras中的layers模塊,用于創建神經網絡層
seed = 42 # 設定隨機種子,用于復現實驗結果
gamma = 0.99 # 定義折扣率,用于計算未來獎勵的現值
max_steps_per_episode = 10000 # 設定每個 episode 的最大步數
env = gym.make("CartPole-v0") # 創建 CartPole-v0 環境實例
env.seed(seed) # 設定環境的隨機種子
eps = np.finfo(np.float32).eps.item() # 獲取 float32 數據類型的誤差最小值 epsilon

Actor Critic 結構搭建

(1)Actor:將環境的狀態作為輸入,返回操作空間中每個操作及其概率值,其實總共只有兩個操作,往左和往右。

(2)Critic:將環境的狀態作為輸入,返回未來獎勵綜合的估計。

(3)在這里網絡結構中我們在一開始接收 inputs 之后,我們的 Actor 和 Critic 共用了中間的部分隱藏層 common 層,然后在一個輸出分支上連接了一個全連接進行動作分類作為 action ,另一個分支上連接了一個全連接層進行未來獎勵計算作為 critic 。

num_inputs = 4 # 狀態空間的維度,即輸入層的節點數
num_actions = 2 # 行為空間的維度,即輸出層的節點數
num_hidden = 128 # 隱藏層的節點數
inputs = layers.Input(shape=(num_inputs,)) # 創建輸入層,指定輸入的形狀
common = layers.Dense(num_hidden, activation="relu")(inputs) # 創建一個全連接層,包含num_hidden 個神經元,使用 ReLU 作為激活函數
action = layers.Dense(num_actions, activation="softmax")(common) # 創建一個全連接層,包含 num_actions 個神經元,使用 softmax 作為激活函數
critic = layers.Dense(1)(common) # 創建一個全連接層,包含1個神經元
model = keras.Model(inputs=inputs, outputs=[action, critic]) # 創建一個 Keras 模型,包含輸入層、共享的隱藏層和兩個輸出層

訓練前的樣子

import imageio
start = env.reset() 
frames = []
for t in range(max_steps_per_episode):
    frames.append(env.render(mode='rgb_array'))
    start = start.reshape(1, -1)
    start, reward, done, _ = env.step(np.random.choice(num_actions, p=np.squeeze(action_probs)))
    if done:
        break
with imageio.get_writer('未訓練前的樣子.gif', mode='I') as writer:
    for frame in frames:
        writer.append_data(frame)

模型訓練

設置訓練所需要的優化器,以及各種參數來記錄每個時間步上的數據。

optimizer = keras.optimizers.Adam(learning_rate=0.01) # 創建 Adam 優化器實例,設置學習率為 0.01
huber_loss = keras.losses.Huber() # 創建損失函數實例
action_probs_history = [] # 創建一個列表,用于保存 action 網絡在每個步驟中采取各個行動的概率
critic_value_history = [] # 創建一個列表,用于保存 critic 網絡在每個步驟中對應的值
rewards_history = [] # 創建一個列表,用于保存每個步驟的獎勵值
running_reward = 0 # 初始化運行過程中的每輪獎勵
episode_count = 0 # 初始化 episode 計數器

一直訓練下去,直到滿足獎勵大于 195 才會停下訓練過程。

while True:  
    state = env.reset()  # 新一輪游戲開始,重置環境
    episode_reward = 0  # 記錄本輪游戲的總獎勵值
    with tf.GradientTape() as tape:  # 構建 GradientTape 用于計算梯度
        for timestep in range(1, max_steps_per_episode): # 本輪游戲如果一切正常會進行 max_steps_per_episode 步
            state = tf.convert_to_tensor(state)  # 將狀態轉換為張量
            state = tf.expand_dims(state, 0)  # 擴展維度,以適應模型的輸入形狀
            action_probs, critic_value = model(state)  # 前向傳播,得到 action 網絡輸出的動作空間的概率分布,和 critic 網絡預測的獎勵值
            critic_value_history.append(critic_value[0, 0])  # 將上面 critic 預測的獎勵值記錄在 critic_value_history 列表中
            action = np.random.choice(num_actions, p=np.squeeze(action_probs))  # 依據概率分布抽樣某個動作,當然了某個動作概率越大越容易被抽中,同時也保留了一定的隨機性
            action_probs_history.append(tf.math.log(action_probs[0, action]))  # 將使用該動作的對數概率值記錄在 action_probs_history 列表中
            state, reward, done, _ = env.step(action)  # 游戲環境使用選中的動作去執行,得到下一個游戲狀態、獎勵、是否終止和其他信息
            rewards_history.append(reward)  # 將該時刻的獎勵記錄在 rewards_history 列表中
            episode_reward += reward  # 累加本輪游戲的總獎勵值
            if done:  # 如果到達終止狀態,則結束循環
                break
        running_reward = 0.05 * episode_reward + (1 - 0.05) * running_reward  # 計算平均獎勵
        returns = []  # 存儲折扣回報
        discounted_sum = 0
        for r in rewards_history[::-1]:  # 從后往前遍歷獎勵的歷史值
            discounted_sum = r + gamma * discounted_sum  # 計算折扣回報
            returns.insert(0, discounted_sum)  # 將折扣回報插入列表的開頭,最后形成的還是從前往后的折扣獎勵列表
        returns = np.array(returns)  # 將折扣回報轉換為數組
        returns = (returns - np.mean(returns)) / (np.std(returns) + eps)  # 歸一化折扣回報
        returns = returns.tolist()  # 將折扣回報轉換為列表形式
        history = zip(action_probs_history, critic_value_history, returns)  # 將三個列表進行 zip 壓縮
        actor_losses = []  # 存儲 action 網絡的損失
        critic_losses = []  # 存儲 critic 網絡的損失
        for log_prob, value, ret in history:
            diff = ret - value
            actor_losses.append(-log_prob * diff)  # 計算 actor 的損失函數
            critic_losses.append(
                huber_loss(tf.expand_dims(value, 0), tf.expand_dims(ret, 0)) # 計算 critic 的損失函數
            )
        loss_value = sum(actor_losses) + sum(critic_losses) # 計算總損失函數
        grads = tape.gradient(loss_value, model.trainable_variables) # 計算梯度
        optimizer.apply_gradients(zip(grads, model.trainable_variables)) # 更新模型參數
        action_probs_history.clear() # 清空之前的歷史記錄
        critic_value_history.clear() # 清空之前的歷史記錄
        rewards_history.clear() # 清空之前的歷史記錄
    episode_count += 1 # 當一輪游戲結束時, episode 加一
    if episode_count % 10 == 0: # 每訓練 10 個 episode ,輸出當前的平均獎勵
        template = "在第 {} 輪游戲中獲得獎勵: {:.2f} 分"
        print(template.format(episode_count, running_reward))
    if running_reward > 195:  # 如果平均獎勵超過195,視為任務已經解決
        print("獎勵超過 195 ,訓練結束")
        break

打印:

在第 10 輪游戲中獲得獎勵: 11.17 分
在第 20 輪游戲中獲得獎勵: 17.12 分
...
在第 170 輪游戲中獲得獎勵: 155.02 分
在第 180 輪游戲中獲得獎勵: 171.67 分
...
在第 220 輪游戲中獲得獎勵: 193.74 分
獎勵超過 195 ,訓練結束

訓練后的樣子

import imageio
start = env.reset() 
frames = []
for t in range(max_steps_per_episode):
    frames.append(env.render(mode='rgb_array'))
    start = start.reshape(1, -1)
    action_probs, _ = model(start)
    action = np.random.choice(num_actions, p=np.squeeze(action_probs))
    start, reward, done, _ = env.step(action)
    if done:
        break
with imageio.get_writer('訓練后的樣子.gif', mode='I') as writer:
    for frame in frames:
        writer.append_data(frame)

到此,相信大家對“怎么使用actor-critic方法來控制CartPole-V0游戲”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平罗县| 安陆市| 祁阳县| 修水县| 定南县| 绩溪县| 塔城市| 安陆市| 镇安县| 大余县| 马关县| 嘉义市| 睢宁县| 江永县| 黄陵县| 顺义区| 崇明县| 六安市| 万安县| 平昌县| 建水县| 洛川县| 江达县| 临桂县| 屏南县| 交城县| 客服| 四川省| 潢川县| 乳山市| 通榆县| 泸水县| 开封县| 江源县| 贵阳市| 渑池县| 全南县| 都匀市| 饶阳县| 田林县| 木里|