强化学习分类:基于价值、基于策略、Actor-Critic
一句话概述
强化学习算法可以分为三大流派:基于价值(Value-based)的方法学习Q函数然后选最优动作,代表是Q-learning和DQN;基于策略(Policy-based)的方法直接优化策略参数,代表是REINFORCE和PPO;Actor-Critic方法结合两者——Actor负责决策,Critic负责评价,代表是A2C、A3C、SAC。理解这三类方法的关系,你就掌握了强化学习算法的全景图。
💡 核心要点:①基于价值的方法间接学习策略(通过Q函数),适合离散动作空间;②基于策略的方法直接优化策略,能处理连续动作和随机策略;③Actor-Critic融合两者优点,Actor更新策略,Critic评估价值,收敛更快更稳定;④现代RL算法大多属于Actor-Critic家族(PPO、SAC、TD3)。
教学与演示
一、基于价值的方法——学Q函数,选最优动作
是什么(定义):基于价值(Value-based)的方法通过估计最优动作价值函数Q*(s,a),然后隐式地定义策略:π(s) = argmax_a Q(s,a)。代表性算法包括:Q-learning、SARSA、DQN及其变体(Double DQN、Dueling DQN、Rainbow)。
大白话 基于价值的方法就像"评分系统"——给每个动作打分(Q值),然后选分数最高的那个。它不直接告诉你"该做什么",而是告诉你"每个动作有多好",让你自己选最好的。就像点菜时看评分——哪个菜评分高就点哪个。
为什么(原理):基于价值的方法的理论基础是贝尔曼最优方程。Q-learning的目标是学习Q*(s,a),使得Q值满足最优贝尔曼方程。这类方法的核心是TD学习——用实际获得的奖励来修正Q值估计。在离散动作空间中,argmax操作可以直接实现;在连续动作空间中,需要额外的优化步骤。
怎么做(实现):
import numpy as np
# ==================== Q-learning:基于价值的方法 ====================
n_states = 9
n_actions = 4
actions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
def step(state, action):
row, col = state // 3, state % 3
dr, dc = actions[action]
nr = max(0, min(2, row + dr))
nc = max(0, min(2, col + dc))
next_state = nr * 3 + nc
if next_state == 8: r = 10.0
elif next_state == 7: r = -5.0
else: r = -0.1
return next_state, r
def q_learning(n_episodes=500, alpha=0.1, gamma=0.9, epsilon=0.2):
"""Q-learning:基于价值的经典算法"""
Q = np.zeros((n_states, n_actions)) # Q表
rewards_history = []
for episode in range(n_episodes):
state = 0
total_reward = 0
while state != 8 and state != 7:
# ε-greedy选择动作
if np.random.random() < epsilon:
action = np.random.randint(n_actions)
else:
action = np.argmax(Q[state])
next_state, reward = step(state, action)
# Q-learning核心更新:用max计算目标
best_next = np.max(Q[next_state]) # 基于价值的关键:max操作
Q[state][action] += alpha * (reward + gamma * best_next - Q[state][action])
total_reward += reward
state = next_state
rewards_history.append(total_reward)
# 提取策略:π(s) = argmax_a Q(s,a)
policy = np.argmax(Q, axis=1)
return Q, policy, rewards_history
np.random.seed(42)
Q, policy, rewards = q_learning()
print("=== Q-learning(基于价值)===")
print("学习的Q函数(部分):")
for s in [0, 4]:
print(f" 状态{s}: Q={[f'{q:.2f}' for q in Q[s]]}, 最优动作={policy[s]}")
print(f"\n提取的策略:")
for i in range(3):
for j in range(3):
s = i * 3 + j
action_names = ["上", "下", "左", "右"]
if s == 8: print("目标", end=" ")
elif s == 7: print("陷阱", end=" ")
else: print(action_names[policy[s]], end=" ")
print()
print(f"\n基于价值的方法特点:")
print(f" 1. 学习Q函数,策略由argmax Q隐式定义")
print(f" 2. 适合离散动作空间(需要argmax操作)")
print(f" 3. 理论基础是贝尔曼最优方程")什么用(应用):基于价值的方法在离散动作空间中表现优异。DQN在Atari 2600游戏上达到人类水平;AlphaGo的价值网络是基于价值方法在围棋中的应用;在推荐系统中,Q-learning可以学习"推荐什么物品能最大化长期用户参与度"。
哪些坑(缺点):不适合连续动作空间(argmax在连续空间中不可行);max操作导致Q值过估计(Double DQN缓解);策略是确定性的,不能表示随机策略;在策略空间中只能间接优化,收敛可能较慢。
二、基于策略的方法——直接优化策略
是什么(定义):基于策略(Policy-based)的方法直接参数化策略π_θ(a|s),并通过梯度上升来优化累积奖励的期望。代表性算法包括:REINFORCE(蒙特卡洛策略梯度)、PPO(近端策略优化)、TRPO(信赖域策略优化)。
大白话 基于策略的方法就像"直接训练"——不绕弯子通过评分来选动作,而是直接告诉神经网络"看到这个情况该做什么"。它输出的是一个动作的概率分布,然后按照"能获得更多奖励的动作应该增加概率"的原则来更新参数。
为什么(原理):基于策略的方法的核心是策略梯度定理(Policy Gradient Theorem):∇_θ J(θ) = E_π[∇_θ log π_θ(a|s) · Q^π(s,a)]。梯度方向是"增加好动作的概率,减少坏动作的概率"。这种方法可以直接处理连续动作空间(输出高斯分布的均值和方差),也可以自然地表示随机策略。
怎么做(实现):
import numpy as np
# ==================== REINFORCE:基于策略的方法 ====================
# 使用softmax策略参数化
n_states = 9
n_actions = 4
actions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
def step(state, action):
row, col = state // 3, state % 3
dr, dc = actions[action]
nr = max(0, min(2, row + dr))
nc = max(0, min(2, col + dc))
next_state = nr * 3 + nc
if next_state == 8: r = 10.0
elif next_state == 7: r = -5.0
else: r = -0.1
return next_state, r
def reinforce(n_episodes=1000, alpha=0.01, gamma=0.9):
"""REINFORCE:蒙特卡洛策略梯度"""
# 策略参数:每个状态-动作对的偏好值
theta = np.zeros((n_states, n_actions)) # 策略参数
rewards_history = []
for episode in range(n_episodes):
# 收集一条完整的轨迹
state = 0
trajectory = [] # (状态, 动作, 奖励)
while state != 8 and state != 7:
# 基于策略的方法:从策略分布中采样动作
logits = theta[state] # 偏好值
# softmax转为概率
exp_logits = np.exp(logits - np.max(logits)) # 数值稳定
probs = exp_logits / exp_logits.sum()
# 采样动作
action = np.random.choice(n_actions, p=probs)
next_state, reward = step(state, action)
trajectory.append((state, action, reward))
state = next_state
# 计算回报(从后往前)
G = 0
returns = []
for _, _, r in reversed(trajectory):
G = r + gamma * G
returns.append(G)
returns.reverse()
# 策略梯度更新
total_reward = sum(r for _, _, r in trajectory)
for (s, a, _), G_t in zip(trajectory, returns):
# 计算softmax梯度
logits = theta[s]
exp_logits = np.exp(logits - np.max(logits))
probs = exp_logits / exp_logits.sum()
# 梯度:对于选中的动作a,梯度 = alpha * G_t * (1 - prob[a])
# 对于其他动作,梯度 = alpha * G_t * (0 - prob[other])
grad = -probs.copy()
grad[a] += 1 # 简化的softmax梯度
theta[s] += alpha * G_t * grad # 策略梯度更新
rewards_history.append(total_reward)
# 提取策略
policy = np.zeros(n_states, dtype=int)
for s in range(n_states):
policy[s] = np.argmax(theta[s]) # 取偏好值最大的动作
return theta, policy, rewards_history
np.random.seed(42)
theta, policy, rewards = reinforce()
print("=== REINFORCE(基于策略)===")
print(f"学习的策略参数(部分):")
for s in [0, 4]:
probs = np.exp(theta[s] - np.max(theta[s]))
probs = probs / probs.sum()
print(f" 状态{s}: probs={[f'{p:.2f}' for p in probs]}")
print(f"\n提取的策略:")
action_names = ["上", "下", "左", "右"]
for i in range(3):
for j in range(3):
s = i * 3 + j
if s == 8: print("目标", end=" ")
elif s == 7: print("陷阱", end=" ")
else: print(action_names[policy[s]], end=" ")
print()
print(f"\n基于策略的方法特点:")
print(f" 1. 直接输出动作概率分布,不需要argmax")
print(f" 2. 可以处理连续动作和随机策略")
print(f" 3. 收敛到局部最优,学习过程可能波动大")什么用(应用):基于策略的方法在连续控制(机器人、自动驾驶)中占主导地位。PPO是OpenAI的默认RL算法,用于训练OpenAI Five(Dota 2)和dexterous hand manipulation;TRPO和PPO在机器人控制中广泛应用;策略梯度方法也是ChatGPT中RLHF(人类反馈强化学习)的核心。
哪些坑(缺点):梯度估计方差大(需要大量样本);容易收敛到局部最优而非全局最优;样本效率低,每次更新后旧数据就"过时"了;策略更新步长难以选择——太大导致策略崩溃,太小导致学习缓慢。
三、Actor-Critic——强强联合
是什么(定义):Actor-Critic方法结合了基于价值和基于策略的优点。Actor(演员)是策略网络π_θ(a|s),负责决策;Critic(评论家)是价值网络V_φ(s)或Q_φ(s,a),负责评估Actor的表现。Critic的评估结果用于指导Actor的更新,降低了策略梯度的方差。
大白话 Actor-Critic就像"演员和导演"——Actor是演员,在舞台上表演(做动作);Critic是导演,在台下点评(给反馈)。演员根据导演的评价来改进表演,导演根据实际效果来调整评价标准。两者互相配合,比单独一个演员(纯策略)或单独一个评分系统(纯价值)更高效。
为什么(原理):Actor-Critic的核心优势在于用Critic的估计替代了蒙特卡洛回报G_t,从而降低了策略梯度估计的方差。Actor使用策略梯度更新:θ ← θ + α ∇_θ log π_θ(a|s) · A(s,a),其中A(s,a)=Q(s,a)-V(s)是优势函数。Critic使用TD学习更新:φ ← φ + β [r + γV(s') - V(s)] ∇_φ V(s)。
怎么做(实现):
import numpy as np
# ==================== Actor-Critic:结合策略和价值 ====================
n_states = 9
n_actions = 4
actions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
def step(state, action):
row, col = state // 3, state % 3
dr, dc = actions[action]
nr = max(0, min(2, row + dr))
nc = max(0, min(2, col + dc))
next_state = nr * 3 + nc
if next_state == 8: r = 10.0
elif next_state == 7: r = -5.0
else: r = -0.1
return next_state, r
def actor_critic(n_episodes=500, alpha_actor=0.01, alpha_critic=0.1, gamma=0.9):
"""Actor-Critic算法"""
# Actor:策略参数
theta = np.zeros((n_states, n_actions))
# Critic:状态价值函数V(s)
V = np.zeros(n_states)
rewards_history = []
for episode in range(n_episodes):
state = 0
total_reward = 0
while state != 8 and state != 7:
# Actor:根据策略选择动作
logits = theta[state]
exp_logits = np.exp(logits - np.max(logits))
probs = exp_logits / exp_logits.sum()
action = np.random.choice(n_actions, p=probs)
next_state, reward = step(state, action)
# Critic:计算TD误差
td_error = reward + gamma * V[next_state] - V[state]
# Critic:更新V(s)
V[state] += alpha_critic * td_error
# Actor:用TD误差(作为优势函数的近似)更新策略
grad = -probs.copy()
grad[action] += 1
theta[state] += alpha_actor * td_error * grad
total_reward += reward
state = next_state
rewards_history.append(total_reward)
# 提取策略
policy = np.zeros(n_states, dtype=int)
for s in range(n_states):
policy[s] = np.argmax(theta[s])
return theta, V, policy, rewards_history
np.random.seed(42)
theta, V, policy, rewards = actor_critic()
print("=== Actor-Critic ===")
print(f"Critic学习的V函数(部分):")
for s in [0, 4]:
print(f" 状态{s}: V={V[s]:.2f}")
print(f"\nActor学习的策略:")
action_names = ["上", "下", "左", "右"]
for i in range(3):
for j in range(3):
s = i * 3 + j
if s == 8: print("目标", end=" ")
elif s == 7: print("陷阱", end=" ")
else: print(action_names[policy[s]], end=" ")
print()
print(f"\nActor-Critic的特点:")
print(f" 1. Actor负责决策(策略),Critic负责评估(价值)")
print(f" 2. Critic的TD误差降低Actor梯度估计的方差")
print(f" 3. 比纯策略梯度更稳定,比纯价值方法更灵活")什么用(应用):Actor-Critic是现代RL的主流架构。A2C/A3C用于Atari游戏和机器人控制;PPO是OpenAI的首选算法;SAC(Soft Actor-Critic)在连续控制任务中表现优异;TD3(Twin Delayed DDPG)是DDPG的改进版本。ChatGPT的RLHF实质上也是Actor-Critic。
哪些坑(缺点):需要同时训练两个网络,计算成本更高;Actor和Critic的训练步调需要协调;Critic的估计误差会影响Actor的更新方向;两个网络共享底层时,梯度冲突可能导致训练不稳定。
四、三类方法的对比——选择正确的工具
是什么(定义):三种RL方法各有优劣,选择取决于具体问题:动作空间类型(离散/连续)、是否需要随机策略、样本效率要求、实现复杂度。下表总结了它们的核心区别。
大白话 选方法就像选工具——拧螺丝用螺丝刀(离散动作用Q-learning),钉钉子用锤子(连续动作用策略梯度),精细活用电钻(复杂任务用Actor-Critic)。没有最好的方法,只有最合适的方法。
为什么(原理):方法选择的底层逻辑是:基于价值的方法在离散空间中通过max操作高效隐式定义策略,但在连续空间中max不可行;基于策略的方法直接输出分布参数,天然适合连续空间,但方差大;Actor-Critic用Critic降低方差,用Actor保持灵活性,是当前最通用的方案。
怎么做(实现):
import numpy as np
# ==================== 三类方法对比总结 ====================
print("=" * 60)
print("强化学习三大方法对比")
print("=" * 60)
comparison = {
"维度": ["价值方法", "策略方法", "Actor-Critic"],
"核心思想": [
"学Q函数,选最优动作",
"直接优化策略参数",
"Actor决策+Critic评价"
],
"策略表示": [
"隐式(argmax Q)",
"显式(概率分布)",
"显式(Actor输出)"
],
"动作空间": [
"离散(需要argmax)",
"连续+离散",
"连续+离散"
],
"随机策略": [
"需要额外机制(ε-greedy)",
"天然支持",
"天然支持"
],
"代表算法": [
"Q-learning, DQN, Double DQN",
"REINFORCE, PPO, TRPO",
"A2C, A3C, SAC, TD3"
],
"方差": [
"低(TD学习)",
"高(蒙特卡洛)",
"中(Critic降低方差)"
],
"样本效率": [
"高(经验回放)",
"低(on-policy)",
"中-高(取决于算法)"
],
"收敛性": [
"较稳定",
"可能波动大",
"较稳定"
]
}
for key in comparison:
print(f"\n{key}:")
for i, val in enumerate(comparison[key]):
print(f" {['价值方法','策略方法','Actor-Critic'][i]}: {val}")
print(f"\n选择指南:")
print(f" 离散动作 + 简单任务 → Q-learning / DQN")
print(f" 连续动作 + 简单任务 → REINFORCE / PPO")
print(f" 复杂任务 + 需要稳定 → Actor-Critic (PPO, SAC)")
print(f" 高维离散动作 + 需要效率 → Rainbow DQN")
print(f" 机器人控制 + 连续动作 → SAC / TD3")什么用(应用):理解三类方法的区别有助于在实际项目中做出正确的算法选择。在游戏AI中,离散动作用DQN系,连续控制用PPO/SAC;在推荐系统中,离散物品推荐用DQN,连续出价策略用PPO;在机器人控制中,几乎全部使用Actor-Critic系方法。
哪些坑(缺点):没有一种方法在所有场景下都最优;方法选择需要权衡多个因素(动作空间、样本效率、稳定性、实现复杂度);实际应用中,往往需要尝试多种方法才能找到最优方案。
五、On-Policy vs Off-Policy——另一个重要维度
是什么(定义):除了价值/策略/Actor-Critic的分类,RL算法还有一个重要维度:On-Policy(同策略)和Off-Policy(异策略)。On-Policy方法使用当前策略采集的数据来更新当前策略(如SARSA、PPO);Off-Policy方法可以使用任何策略(包括旧策略)采集的数据来更新(如Q-learning、DQN)。
大白话 On-Policy就像"自己反思自己"——你只能从自己最近的经历中学习,旧经历作废。Off-Policy就像"向前辈学习"——你可以从任何人(包括过去的自己)的经验中学习,数据可以复用。Off-Policy更高效(可以重复使用经验),但On-Policy更稳定(策略和数据的分布一致)。
为什么(原理):On-Policy和Off-Policy的区别在于更新公式中的期望是对哪个策略取的。Q-learning的更新使用max Q(s',a'),这对应的是贪心策略(目标策略),而数据采集使用的是ε-greedy(行为策略),两者不同→Off-Policy。SARSA的更新使用Q(s',a')(下一步实际执行的动作),数据采集和更新目标使用同一策略→On-Policy。
怎么做(实现):
import numpy as np
# 对比SARSA(On-Policy)和Q-learning(Off-Policy)
n_states = 9
n_actions = 4
actions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
def step(state, action):
row, col = state // 3, state % 3
dr, dc = actions[action]
nr = max(0, min(2, row + dr))
nc = max(0, min(2, col + dc))
next_state = nr * 3 + nc
if next_state == 8: r = 10.0
elif next_state == 7: r = -5.0
else: r = -0.1
return next_state, r
def sarsa(n_episodes=500, alpha=0.1, gamma=0.9, epsilon=0.2):
"""SARSA:On-Policy"""
Q = np.zeros((n_states, n_actions))
for episode in range(n_episodes):
state = 0
# SARSA:先选动作
action = (np.random.randint(n_actions) if np.random.random() < epsilon
else np.argmax(Q[state]))
while state != 8 and state != 7:
next_state, reward = step(state, action)
# 选下一个动作(使用同一ε-greedy策略)
next_action = (np.random.randint(n_actions) if np.random.random() < epsilon
else np.argmax(Q[next_state]))
# SARSA更新:使用实际执行的下一个动作的Q值
Q[state][action] += alpha * (reward + gamma * Q[next_state][next_action] - Q[state][action])
state, action = next_state, next_action
return Q
def q_learning_off(n_episodes=500, alpha=0.1, gamma=0.9, epsilon=0.2):
"""Q-learning:Off-Policy"""
Q = np.zeros((n_states, n_actions))
for episode in range(n_episodes):
state = 0
while state != 8 and state != 7:
action = (np.random.randint(n_actions) if np.random.random() < epsilon
else np.argmax(Q[state]))
next_state, reward = step(state, action)
# Q-learning更新:使用max(贪心策略),而非实际执行的动作
Q[state][action] += alpha * (reward + gamma * np.max(Q[next_state]) - Q[state][action])
state = next_state
return Q
np.random.seed(42)
Q_sarsa = sarsa()
Q_ql = q_learning_off()
print("=== SARSA (On-Policy) vs Q-learning (Off-Policy) ===")
print("关键区别:")
print(f" SARSA更新: Q(s,a) ← Q(s,a) + α[r + γ·Q(s',a') - Q(s,a)]")
print(f" a'是实际执行的下一个动作(ε-greedy)")
print(f" Q-learn更新: Q(s,a) ← Q(s,a) + α[r + γ·max Q(s',a') - Q(s,a)]")
print(f" 使用max(贪心),而非实际执行的动作")
print(f"\nSARSA更保守(考虑探索的风险),Q-learning更乐观(假设最优)")什么用(应用):Off-Policy方法(DQN、SAC)可以使用经验回放,样本效率高,适合数据收集成本高的场景。On-Policy方法(PPO、TRPO、A3C)更稳定,策略更新更安全,适合高风险场景(如机器人控制、自动驾驶)。SAC虽然使用Off-Policy数据,但结合了最大熵探索,在连续控制中表现优异。
哪些坑(缺点):Off-Policy方法中,行为策略和目标策略的分布不匹配可能导致学习不稳定(重要性采样可以缓解);On-Policy方法每次更新都需要新数据,样本效率低;经验回放需要大量内存存储经验;Off-Policy方法在函数近似下可能不收敛。
六、实战:三种方法对比实验
是什么(定义):在同一网格世界上运行Q-learning(价值)、REINFORCE(策略)和Actor-Critic三种方法,对比它们的收敛速度、稳定性和最终表现。
怎么做(实现):
import numpy as np
# 在网格世界上对比三种方法
n_states = 9; n_actions = 4
actions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
def step(state, action):
row, col = state // 3, state % 3
dr, dc = actions[action]
nr = max(0, min(2, row + dr))
nc = max(0, min(2, col + dc))
next_state = nr * 3 + nc
if next_state == 8: r = 10.0
elif next_state == 7: r = -5.0
else: r = -0.1
return next_state, r
def q_learning(n_episodes=500):
Q = np.zeros((n_states, n_actions))
rewards = []
for ep in range(n_episodes):
state = 0; ep_r = 0
while state != 8 and state != 7:
action = np.random.randint(n_actions) if np.random.random() < 0.2 else np.argmax(Q[state])
next_s, r = step(state, action)
Q[state][action] += 0.1 * (r + 0.9 * np.max(Q[next_s]) - Q[state][action])
ep_r += r; state = next_s
rewards.append(ep_r)
return rewards
def reinforce(n_episodes=500):
theta = np.zeros((n_states, n_actions))
rewards = []
for ep in range(n_episodes):
state = 0; traj = []
while state != 8 and state != 7:
logits = theta[state]; exp_l = np.exp(logits - np.max(logits))
probs = exp_l / exp_l.sum()
action = np.random.choice(n_actions, p=probs)
next_s, r = step(state, action)
traj.append((state, action, r)); state = next_s
G = 0; returns = []
for _, _, r in reversed(traj): G = r + 0.9*G; returns.append(G)
returns.reverse()
for (s, a, _), G_t in zip(traj, returns):
logits = theta[s]; exp_l = np.exp(logits - np.max(logits))
probs = exp_l / exp_l.sum()
grad = -probs.copy(); grad[a] += 1
theta[s] += 0.01 * G_t * grad
rewards.append(sum(r for _,_,r in traj))
return rewards
def actor_critic(n_episodes=500):
theta = np.zeros((n_states, n_actions))
V = np.zeros(n_states)
rewards = []
for ep in range(n_episodes):
state = 0; ep_r = 0
while state != 8 and state != 7:
logits = theta[state]; exp_l = np.exp(logits - np.max(logits))
probs = exp_l / exp_l.sum()
action = np.random.choice(n_actions, p=probs)
next_s, r = step(state, action)
td_err = r + 0.9*V[next_s] - V[state]
V[state] += 0.1 * td_err
grad = -probs.copy(); grad[action] += 1
theta[state] += 0.01 * td_err * grad
ep_r += r; state = next_s
rewards.append(ep_r)
return rewards
np.random.seed(42)
r_ql = q_learning()
r_rf = reinforce()
r_ac = actor_critic()
print("=== 三种方法对比实验 ===")
print(f"前10个episode奖励:")
print(f"{'Ep':<5} {'Q-learning':<12} {'REINFORCE':<12} {'Actor-Critic':<12}")
for i in range(10):
print(f"{i+1:<5} {r_ql[i]:>8.1f} {r_rf[i]:>8.1f} {r_ac[i]:>8.1f}")
print(f"\n最后100个episode平均奖励:")
print(f" Q-learning: {np.mean(r_ql[-100:]):.2f}")
print(f" REINFORCE: {np.mean(r_rf[-100:]):.2f}")
print(f" Actor-Critic: {np.mean(r_ac[-100:]):.2f}")
print(f"\n收敛速度排序:Q-learning > Actor-Critic > REINFORCE")
print(f"稳定性排序:Q-learning ≈ Actor-Critic > REINFORCE")什么用(应用):通过对比实验,你可以直观地理解不同方法的特点,为实际项目选择算法提供依据。对于离散动作的简单问题,Q-learning最简单高效;对于需要探索或连续动作的问题,Actor-Critic更合适。
哪些坑(缺点):实验结果的泛化性有限,不同任务上方法的相对表现可能不同;超参数(学习率、探索率)对结果影响很大,需要仔细调参。
概念关系图谱
| 概念 | 上位概念 | 核心思想 | 关键公式/方法 | 代表算法 |
|---|---|---|---|---|
| 基于价值 | RL方法 | 学Q函数,选最优动作 | Q(s,a)←Q+α[r+γmaxQ-Q] | Q-learning, DQN |
| 基于策略 | RL方法 | 直接优化策略参数 | ∇J=E[∇logπ·Q] | REINFORCE, PPO |
| Actor-Critic | RL方法 | Actor决策+Critic评价 | θ←θ+α∇logπ·A | A2C, A3C, SAC |
| On-Policy | 学习范式 | 行为策略=目标策略 | 数据采集策略=更新目标策略 | SARSA, PPO |
| Off-Policy | 学习范式 | 行为策略≠目标策略 | 数据采集策略≠更新目标策略 | Q-learning, DQN |
| 经验回放 | 数据利用 | 存储并复用历史经验 | 从经验池随机采样训练 | DQN, SAC |
| 策略梯度 | 优化方法 | 沿梯度方向更新策略 | ∇_θ J(θ) | REINFORCE |
| 优势函数 | 价值度量 | 动作比平均好多少 | A(s,a)=Q(s,a)-V(s) | A2C, PPO |
重点答疑
Q1: 什么时候用基于价值的方法,什么时候用基于策略的方法?
- 离散动作空间 → 基于价值(DQN系列),因为argmax操作简单高效。
- 连续动作空间 → 基于策略或Actor-Critic(PPO、SAC),因为argmax在连续空间中不可行。
- 需要随机策略 → 基于策略(博弈、对抗场景),基于价值的方法天然是确定性的。
- 样本效率优先 → 基于价值(Off-Policy + 经验回放)。
解答:动作空间类型是首要考虑因素——离散用价值,连续用策略。其他因素(样本效率、稳定性)是次要考虑。
Q2: Actor-Critic中的Actor和Critic可以共享网络吗?
可以,而且共享网络是现代Actor-Critic方法的标准做法。Actor和Critic共享底层的特征提取网络(如CNN处理图像),然后各自有不同的输出头(Actor输出动作分布,Critic输出V值)。共享的好处是:减少参数量、共享特征表示、加速训练。坏处是:两个目标可能冲突,需要仔细平衡学习率。
解答:在A3C、PPO等实际实现中,Actor和Critic通常共享底层网络。A3C的经典论文就使用了共享网络架构。
Q3: 为什么Q-learning是Off-Policy而SARSA是On-Policy?
关键在更新公式中"下一个动作的Q值"如何处理:
- Q-learning:Q(s,a) ← Q(s,a) + α[r + γ·max_{a'} Q(s',a') - Q(s,a)],使用max(贪心策略),这是目标策略。
- SARSA:Q(s,a) ← Q(s,a) + α[r + γ·Q(s',a') - Q(s,a)],使用实际执行的下一个动作a'(来自ε-greedy),这是行为策略。
Q-learning中,目标策略(贪心)和行为策略(ε-greedy)不同 → Off-Policy。SARSA中,两者相同 → On-Policy。
解答:一句话——Q-learning用max(假设最优),SARSA用实际动作(执行什么就用什么)。max是贪心策略,实际执行是ε-greedy,所以Q-learning是Off-Policy。
Q4: 为什么策略梯度方法的方差比价值方法高?
策略梯度需要估计Q^π(s,a)或G_t,这些估计来自采样轨迹。轨迹越长,累积奖励的方差越大(每个奖励的随机性被累积)。此外,策略梯度涉及log概率的梯度,其幅度可能很大。相比之下,价值方法使用TD学习,只需要一对(s,a,r,s')的奖励,方差小得多。
Actor-Critic通过用Critic的估计替代G_t来降低方差,这正是它被广泛使用的原因。
解答:策略梯度用"整个轨迹的累积奖励"来算梯度,方差大;价值方法用"一步TD误差"来更新,方差小。Actor-Critic取两者之长。
Q5: On-Policy和Off-Policy哪种更好?
没有绝对的好坏,取决于场景:
- On-Policy(PPO、TRPO)更稳定、更安全,适合高风险场景(机器人、自动驾驶),但样本效率低。
- Off-Policy(DQN、SAC)样本效率高,可以复用历史数据,适合数据收集成本高的场景,但可能不稳定。
现代趋势:SAC(Off-Policy)在连续控制中表现优异,PPO(On-Policy)在通用RL中应用广泛。
解答:On-Policy安全但浪费,Off-Policy高效但冒险。PPO和SAC分别是两个阵营的王者。
Q6: 为什么现代RL算法大多属于Actor-Critic?
因为Actor-Critic结合了两者的优点:
- Actor可以直接处理连续动作和随机策略(策略方法的优势)。
- Critic用TD学习降低方差(价值方法的优势)。
- 可以共享网络,减少参数量。
- 框架灵活,可以加入各种改进(如PPO的裁剪、SAC的熵正则化)。
纯价值方法(DQN)在离散动作中仍然很棒,纯策略方法(REINFORCE)现在主要用于教学。实际工程中,Actor-Critic是主流。
解答:Actor-Critic = 策略方法的灵活性 + 价值方法的稳定性。这就是为什么PPO、SAC、A3C都是Actor-Critic。
章节单词汇总
| 英文 | 音标 | 中文 |
|---|---|---|
| value-based | /ˈvæljuː beɪst/ | 基于价值的 |
| policy-based | /ˈpɑːləsi beɪst/ | 基于策略的 |
| Actor-Critic | /ˈæktər ˈkrɪtɪk/ | 演员-评论家 |
| on-policy | /ɒn ˈpɑːləsi/ | 同策略 |
| off-policy | /ɒf ˈpɑːləsi/ | 异策略 |
| Q-learning | /kjuː ˈlɜːrnɪŋ/ | Q学习 |
| SARSA | /ˈsɑːrsə/ | 状态-动作-奖励-状态-动作 |
| policy gradient | /ˈpɑːləsi ˈɡreɪdiənt/ | 策略梯度 |
| REINFORCE | /ˌriːɪnˈfɔːrs/ | 强化(算法名) |
| PPO | /piː piː oʊ/ | 近端策略优化 |
| TRPO | /tiː ɑːr piː oʊ/ | 信赖域策略优化 |
| SAC | /es eɪ siː/ | 软演员-评论家 |
| DDPG | /diː diː piː dʒiː/ | 深度确定性策略梯度 |
| TD3 | /tiː diː θriː/ | 双延迟深度确定性策略梯度 |
| experience replay | /ɪkˈspɪriəns ˈriːpleɪ/ | 经验回放 |
| target network | /ˈtɑːrɡɪt ˈnetwɜːrk/ | 目标网络 |
| importance sampling | /ɪmˈpɔːrtns ˈsæmplɪŋ/ | 重要性采样 |
| entropy | /ˈentrəpi/ | 熵 |
面试练习
Q1 [单选] 以下哪个算法不属于基于价值的方法?
- A. Q-learning
- B. DQN
- C. REINFORCE
- D. SARSA
解答:REINFORCE是基于策略的方法(策略梯度),其他三个都是基于价值的方法。Q-learning和DQN学习Q函数,SARSA也学习Q函数但使用On-Policy更新。
Q2 [单选] Actor-Critic方法中,Actor和Critic分别负责什么?
- A. Actor评估价值,Critic选择动作
- B. Actor选择动作,Critic评估价值
- C. Actor和Critic都选择动作
- D. Actor和Critic都评估价值
解答:Actor(演员)负责决策——选择动作;Critic(评论家)负责评估——评估当前状态或动作的价值。Actor根据Critic的反馈来改进策略。
Q3 [多选] 以下关于Q-learning和SARSA的说法,哪些是正确的?
- A. Q-learning是Off-Policy,SARSA是On-Policy
- B. Q-learning使用max操作,SARSA使用实际执行的动作
- C. Q-learning和SARSA的更新公式完全相同
- D. SARSA更保守,因为它考虑了探索的风险
解答:A正确,Q-learning用max(贪心目标),SARSA用实际动作(同一策略)。B正确。C错误,Q-learning用max,SARSA用实际Q值。D正确,SARSA的更新考虑了ε-greedy可能选到的不好的动作。
Q4 [单选] 策略梯度定理中,梯度的计算不依赖于什么?
- A. 策略参数
- B. 动作价值函数
- C. 环境转移概率模型
- D. 策略的对数概率
解答:策略梯度定理的巧妙之处在于∇_θ J(θ) = E[∇_θ log π_θ(a|s) · Q^π(s,a)],这个公式不包含环境转移概率P(s'|s,a)。这意味着策略梯度是"无模型"的——不需要知道环境模型就能计算梯度。
Q5 [多选] 以下哪些是Actor-Critic方法的优势?
- A. 比纯策略梯度方法方差更低
- B. 可以处理连续动作空间
- C. 一定比纯价值方法收敛更快
- D. Actor和Critic可以共享特征提取网络
解答:A正确,Critic的TD学习降低了策略梯度的方差。B正确,Actor可以输出连续动作的参数(如高斯分布均值和方差)。C错误,收敛速度取决于具体任务和超参数。D正确,在A3C、PPO中Actor和Critic通常共享底层网络。
Q6 [单选] 以下哪个算法是On-Policy的?
- A. Q-learning
- B. DQN
- C. PPO
- D. SAC
解答:PPO是On-Policy的——它使用当前策略采集的数据来更新策略,更新后旧数据不能再用。Q-learning和DQN是Off-Policy(使用经验回放)。SAC虽然是Off-Policy,但使用了最大熵框架。
Q7 [单选] 基于价值的方法在连续动作空间中的主要挑战是什么?
- A. 无法表示Q函数
- B. argmax操作在连续空间中不可行
- C. Q函数无法学习
- D. 奖励函数无法定义
解答:基于价值的方法需要argmax_a Q(s,a)来选择动作,这在离散空间中很简单(遍历所有动作),但在连续空间中需要求解一个优化问题,计算成本高且可能不精确。这是DDPG等算法引入Actor网络的原因——用Actor来近似argmax。
Q8 [多选] 以下哪些是Off-Policy方法的优势?
- A. 可以使用经验回放,提高样本效率
- B. 可以使用任意策略(包括旧策略)采集的数据
- C. 总是比On-Policy方法更稳定
- D. 可以从演示数据中学习
解答:A正确,经验回放是Off-Policy的核心优势。B正确,Off-Policy不要求数据来自当前策略。C错误,Off-Policy通常不如On-Policy稳定。D正确,可以从人类演示或其他智能体的数据中学习,这是Off-Policy的独特优势。
Q9 [单选] REINFORCE算法中,用于更新策略的权重是什么?
- A. TD误差
- B. 即时奖励
- C. 累积折扣奖励(Return)G_t
- D. 优势函数
解答:REINFORCE使用蒙特卡洛回报G_t作为策略梯度中的权重。这是它方差大的原因——G_t包含整个轨迹的随机性。Actor-Critic用优势函数(基于TD误差)替代G_t来降低方差。
Q10 [多选] 以下哪些是选择RL算法时需要考虑的因素?
- A. 动作空间的类型(离散/连续)
- B. 样本效率要求
- C. 是否需要随机策略
- D. 实现的复杂度
解答:以上所有都是选择RL算法时需要考虑的因素。动作空间决定基本方法类型,样本效率影响On/Off-Policy选择,随机策略需求影响价值/策略方法选择,实现复杂度影响工程决策。