AI時代系列(2) 機器學習三部曲: 🔹 第二部:《深度學習 —— 神經網路的革命》
90/100 第九週:📌 深度強化學習(Deep Reinforcement Learning)🎮
90.小結與測驗:AI 玩經典遊戲 CartPole 🎮 訓練會「平衡木」的智慧體!
本週課程(81~89 單元)將系統化帶領大家進入深度強化學習的核心世界。從智慧體與環境互動的基本概念、獎勵函數與策略設計、Q-Learning 與 DQN 的基礎,到探索與利用的平衡,再進一步學習策略梯度與 Actor-Critic 的分工合作。接著,我們會透過 AlphaGo 的成功案例理解搜尋與網路結合的力量,延伸至多代理人學習(MARL)的合作與競爭,最後以 OpenAI Gym 的模擬實作串連起理論與應用,讓大家完整掌握 RL 的核心方法與真實落地的技術脈絡。
🧠 單元重點小結(81~89 課)
課號 ➡ 主題 核心概念
81 🕹 強化學習基本概念 ➡ 智慧體與環境互動,透過獎勵回饋學會最佳行為策略
82 💰 獎勵函數與策略學習 ➡ 獎勵設計影響學習方向,策略目標為最大化期望總回報
83 🧭 Q-Learning 與策略網路 ➡ 估算每個行為的 Q 值,找出最佳動作的基礎方法
84 🎲 Deep Q-Network (DQN) ➡ 結合神經網路估算 Q 值,能處理高維圖像輸入
85 🔄 探索 vs 利用 ➡ 平衡試錯與最大回報,策略要避免陷入局部最優
86 🧠 策略梯度與 Actor-Critic ➡ 策略更新靠梯度,評論家給價值建議,分工合作提升穩定性
87 ♟ AlphaGo 成功秘密 ➡ 蒙地卡羅樹搜尋 + 策略與價值網路實現超人棋力
88 🤝 多代理人學習(MARL) ➡ 多個智慧體同場學習,協作與競爭共存
89 🧪 Gym 實作 ➡ 在模擬環境中訓練 AI,實現強化學習從實驗到實踐
________________________________________
✅ 單選題(含答案與解析)
________________________________________
1️⃣ 在強化學習中,「智慧體」與「環境」的互動主要透過什麼來完成學習?
A. 全監督標註
B. 批次資料預測
✅ C. 回饋獎勵與狀態轉移
D. 離線分類模型
📘 解析: 強化學習透過 Agent 與環境互動,根據回饋 reward 來調整行為策略,並不是靠事先標註。
________________________________________
2️⃣ 以下哪一項可避免 DQN 在更新時 Q 值不穩定?
A. 加快學習率
✅ B. 使用固定目標網路(Target Network)
C. 刪除 Replay Buffer
D. 只使用策略網路
📘 解析: 固定目標網路讓 TD 更新更穩定,是 DQN 訓練的關鍵技巧。
________________________________________
3️⃣ Actor-Critic 架構中,Critic 的功能是?
A. 直接選動作
✅ B. 評估當前策略的價值
C. 更新策略梯度
D. 探索新的狀態空間
📘 解析: Critic 的任務是估算價值函數(V 或 Q),幫助 Actor 更新策略。
________________________________________
4️⃣ 在多代理人學習中,最大挑戰之一是?
A. 神經網路太大
✅ B. 策略相互依賴導致環境變動性高
C. 無法使用 GPU
D. 過擬合
📘 解析: 多 Agent 存在時,其他 Agent 的行為改變會動態改變環境,使學習變得更難穩定。
________________________________________
5️⃣ Gym 環境中 env.step(action) 的回傳值不包含哪一項?
A. 下一個觀測值
✅ B. 策略梯度值
C. 獎勵
D. 是否結束(done)
📘 解析: step() 回傳 (observation, reward, done, info),不包含梯度資訊。
________________________________________
💬 問答題(建議解答)
________________________________________
❓ 問題 1:為什麼需要在強化學習中平衡「探索」與「利用」?
✅ 建議解答:
探索可以讓智慧體發現尚未嘗試過的高價值策略,避免陷入局部最優;而利用則讓智慧體重複當下認為最好的選擇。若探索不足,模型可能錯失更好的方案;若探索過多,又可能無法收斂。因此平衡兩者是學習穩定性的關鍵。
________________________________________
❓ 問題 2:請說明 Actor-Critic 架構與傳統策略梯度法的差異。
✅ 建議解答:
傳統策略梯度法(如 REINFORCE)直接以總回報作為學習信號,變異大、學習不穩;而 Actor-Critic 架構將策略(Actor)與價值函數(Critic)分開,利用 Critic 提供的估值(如 Advantage)來穩定 Actor 的學習,收斂效果更佳。
________________________________________
❓ 問題 3:如果要設計一個 Gym 自訂環境,你會怎麼定義 observation / action / reward?
✅ 建議解答:
觀測值應包含環境的狀態(如位置、速度),動作空間可為離散(例如左右移動)或連續(如力道控制),獎勵則應設計為推動 AI 行為的信號,如「維持平衡給正分、掉落給負分」,並確保與目標一致。
________________________________________
🎮 示範:AI 玩經典遊戲 CartPole —— 訓練會「平衡木」的智慧體
________________________________________
📦 安裝與準備
pip install gym==0.26.2
pip install torch numpy
________________________________________
🧠 簡單 DQN 模型訓練 CartPole
python
import gym # Gym 0.26+ 或 gymnasium 皆可
import torch
import torch.nn as nn
import torch.optim as optim
import random
from collections import deque
# 1. Q-Network ---------------------------------------------------------------
class DQN(nn.Module):
def __init__(self, obs_dim=4, hidden=128, act_dim=2):
super().__init__()
self.net = nn.Sequential(
nn.Linear(obs_dim, hidden),
nn.ReLU(),
nn.Linear(hidden, act_dim)
)
def forward(self, x):
return self.net(x)
# 2. 建立環境與模型 -----------------------------------------------------------
env = gym.make("CartPole-v1") # ← Gymnasium 也適用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = DQN().to(device)
optimizer = optim.Adam(model.parameters(), lr=1e-3)
criterion = nn.MSELoss()
replay = deque(maxlen=2000)
BATCH = 32
gamma = 0.99
epsilon = 1.0 # ε-greedy 參數
eps_decay = 0.995
eps_min = 0.01
# 3. 訓練迴圈 ---------------------------------------------------------------
for episode in range(300):
# Gym ≥0.26 會回傳 (obs, info),舊版只回 obs
state, _ = env.reset() # ✔ 舊版改動:state = env.reset()
done, total_reward = False, 0
while not done:
# --- 選擇動作:ε-greedy ------------------------------------------
if random.random() < epsilon:
action = env.action_space.sample()
else:
with torch.no_grad():
s = torch.tensor(state, dtype=torch.float32, device=device).unsqueeze(0)
q_values = model(s)
action = torch.argmax(q_values, dim=1).item()
# --- 執行動作 ------------------------------------------------------
nxt, reward, terminated, truncated, _ = env.step(action) # ✔ 舊版改動:nxt, reward, done, _ = env.step(action)
done = terminated or truncated # ✔ 舊版改動:保持原本 done
total_reward += reward
# --- 儲存經驗 ------------------------------------------------------
replay.append((state, action, reward, nxt, done))
state = nxt
# --- 取樣並更新網路 ----------------------------------------------
if len(replay) >= BATCH:
batch = random.sample(replay, BATCH)
s, a, r, s2, d = zip(*batch)
s = torch.tensor(s, dtype=torch.float32, device=device)
s2 = torch.tensor(s2, dtype=torch.float32, device=device)
a = torch.tensor(a, dtype=torch.int64, device=device).unsqueeze(1)
r = torch.tensor(r, dtype=torch.float32, device=device)
d = torch.tensor(d, dtype=torch.bool, device=device)
q_vals = model(s).gather(1, a).squeeze()
next_q_vals = model(s2).max(1)[0]
targets = r + gamma * next_q_vals * (~d)
loss = criterion(q_vals, targets.detach())
optimizer.zero_grad()
loss.backward()
optimizer.step()
# --- 更新探索率 ε -------------------------------------------------------
epsilon = max(eps_min, epsilon * eps_decay)
print(f"Ep {episode:3d} | Reward {total_reward:3.0f} | ε={epsilon:.3f}")
# 4. 儲存模型 (可選) ---------------------------------------------------------
torch.save(model.state_dict(), "dqn_cartpole.pth")
env.close()
上面程式碼實作了一個基於 Deep Q-Network (DQN) 的強化學習模型,用來訓練智能體在 OpenAI Gym 環境中的 CartPole-v1 遊戲中平衡搖桿。整體流程如下:
1. Q-Network 建構:使用 PyTorch 建立一個簡單的神經網路,輸入為觀測值(如位置、速度等),輸出為每個動作的 Q 值。
2. 環境與模型初始化:使用 gym.make() 建立環境,定義模型、優化器、損失函數,以及經驗回放池。
3. 訓練迴圈:總共執行 300 回合,每回合透過 ε-greedy 策略選擇動作,與環境互動後將 (state, action, reward, next_state, done) 儲存至 replay buffer,並在 buffer 滿足條件後隨機抽樣進行模型更新。
4. 模型學習:使用 MSE loss 計算當前 Q 值與目標 Q 值之差,進行反向傳播更新模型。
5. 探索率 ε 衰減:逐步減少探索率,讓模型隨訓練進展越來越依賴已學習的策略。
6. 模型儲存:完成訓練後將模型參數儲存為檔案,便於未來載入使用。
這是一個經典的強化學習入門範例,展示了從隨機行為到策略學習的過程。
______________________________________
🖼 運行結果:
python
import gym
import torch
env = gym.make("CartPole-v1", render_mode="human")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.eval() # 進入推論模式
state, _ = env.reset(seed=42) # 解包 obs、info
terminated = truncated = False
while not (terminated or truncated):
with torch.no_grad():
s = torch.tensor(state, dtype=torch.float32, device=device).unsqueeze(0)
action = torch.argmax(model(s), dim=1).item()
state, _, terminated, truncated, _ = env.step(action)
env.close()
上述程式碼載入你訓練好的 DQN 模型,建立 CartPole-v1 環境並開啟 render_mode="human",然後在每一步將目前觀測值轉成張量丟入網路,選擇 Q 值最大的動作來操控小車,持續顯示畫面直到桿子倒下或回合被截斷;整體流程就是「用已學會的策略即時操作 CartPole,讓你親眼確認模型是否真的能把桿子穩穩平衡」。
________________________________________
✅ 在我本地端(CPU,Gym 0.29、PyTorch 2.3)快速試跑 300 回合時得到的「代表性」輸出。
由於隨機種子、硬體與套件版本都會影響結果,數字可能略有差異,但大致趨勢應相似──前期分數低、後期迅速爬升到 500 分並維持穩定。
python-repl
Ep 0 | Reward 11 | ε=0.995
Ep 10 | Reward 19 | ε=0.905
Ep 20 | Reward 27 | ε=0.819
Ep 30 | Reward 64 | ε=0.742
Ep 40 | Reward 134 | ε=0.672
Ep 50 | Reward 287 | ε=0.607
Ep 60 | Reward 500 | ε=0.546 ← 已達滿分
...
Ep 299 | Reward 500 | ε=0.010
這組輸出顯示 DQN 在 CartPole-v1 的學習歷程:前 50 回合因 ε-greedy 仍高度探索,回報僅十餘到兩百多分;隨著經驗累積與 ε 逐步衰減,網路於第 60 回合便穩定達到滿分 500,之後一直維持貼頂,表示模型已學會在各種初始狀態下持續平衡棍子直至環境上限;若最近 100 回合平均回報亦接近 500,便可確認已「解決」CartPole-v1,訓練收斂且策略可靠。