强化学习核心概念与demo
摘要:强化学习是一种通过与环境交互来优化长期累积收益的机器学习方法。Q-learning是一种经典强化学习算法,通过迭代更新Q值函数来学习最优策略。本文介绍了强化学习的基本概念和四元组模型,详细解释了Q-learning的迭代公式和参数含义,并提供了一个一维走迷宫的任务示例及配套Python代码实现。最后提到深度强化学习在游戏领域的应用,如DeepMind使用像素输入训练AI玩Atari游戏的研究
1. 简述
强化学习, Reinforcement Learning. 特点是通过 序列决策 追求 长期累积奖赏(比如走迷宫这样的多次决策). 该特点与 reinforcement 单词本意 “通过鼓励和奖赏的加强” 一致, 名字直观. 有监督学习不涉及多次决策, 通过Loss(单次预测, label) 指导学习.
RL 目标是为了得到 策略 π ( a ∣ s ) \pi(a|s) π(a∣s), 指导 agent 在指定的 s 下做出最优的 a.
1.1 常见分类
表1. 根据 π \pi π 的来源不同, 可以分为 Value / Policy based 两种类别, 对比如下:
| 对比维度 | Value-based(基于价值) | Policy-based(基于策略) |
|---|---|---|
| 核心思想 | 学习最优价值函数(如 Q(s,a)),策略通过 argmaxₐ Q(s,a) 导出 |
直接参数化策略 π_θ(a|s),优化期望回报目标函数 |
| 典型算法 | Q-Learning, DQN | REINFORCE, Policy Gradient, PPO, TRPO |
| 动作空间 | 离散 | 连续 |
| 样本效率 | ✅ 高(支持经验回放,可离线学习) | ❌ 较低(通常需在线交互) |
| 适用场景 | 游戏 AI、离散控制、高维状态 | 机器人控制、连续控制、需要探索的任务 |
| 代表应用 | DeepMind DQN(Atari) | OpenAI PPO(机器人、复杂模拟) |
还有 On/Off Policy 维度的分类:
- On-Plolicy 要求 数据来源 必须由当前正在学习的策略(target-policy) 生成.
- 反之, 数据来源 为旧策略, 随机策略 时, 属于 Off-Policy.
1.1 与 MDP 的关系
MDP 这种数学形式适合 RL 的问题建模.
agent 需要与环境不断地进行交互, 根据环境的反馈来获得知识.
强化学习任务对应了四元组 E = < X , A , P , R > E=<X,A,P,R> E=<X,A,P,R>
X: 状态空间 A: 动作空间 P: 转移函数 R: 奖赏函数.
2. Q-learning 与 DQN
二者联系密切, 属于 value-based, off-policy 的 时序差分控制算法.
得名中的Q, 来自 Quality, 表示 选择 action 的质量 (不如直接用 Value 这个词).
Q ( s , a ) Q(s,a) Q(s,a) 是核心, 表示在状态 s 下执行动作 a ,然后按照某种策略继续行动,所能获得的未来累积回报的期望值.
2.1 Q-learning
Q-learning was introduced by Watkins in 1989. wiki见参考[4] .
迭代公式为:
Q ( s t , a t ) ← Q ( s t , a t ) + α ⋅ δ t δ t = r t + γ max a ′ Q ( s t + 1 , a ′ ) − Q ( s t , a t ) (1) Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \cdot \delta_t \\[1em] \delta_t = r_{t} + \gamma \max_{a'} Q(s_{t+1}, a') - Q(s_t, a_t) \tag 1 Q(st,at)←Q(st,at)+α⋅δtδt=rt+γa′maxQ(st+1,a′)−Q(st,at)(1)
- δ t \delta_t δt:TD-error, Temporal Difference error, 时序差分误差.
- r t r_t rt: 从 s t s_t st 执行 a t a_t at 后进入 s t + 1 s_{t+1} st+1 时获得的即时奖励 (有些文献会记为 r t + 1 r_{t+1} rt+1, 本意相同)
- s t s_t st, 当前状态
- a t a_t at, 当前动作
- s t + 1 s_{t+1} st+1, 执行a后的下一个状态, 可简化记为 s ′ s' s′
- γ \gamma γ, 累积奖励的折扣因子
- α \alpha α, 学习率
2.1.1 任务与代码 demo (Grid World 一维走迷宫)
- 环境描述: 一条长度为 5 的直线格子(
S---E),位置 0 是起点,位置 4 是终点. 每一步 agent 可以向左或向右走, 走到终点则结束游戏. - 学习策略: 如何最快到达终点.
- 奖励设定: 只有走到终点奖励才为1,否则每步奖励为 0. 这属于 稀疏奖励, 即只奖励成功,不奖励尝试.
2.1.2 配套 code
import random
# 环境参数
n_states = 5
ACTIONS = ["left", "right"] # 明确动作标签
goal_state = 4
# Q表初始化:状态 × 动作
Q = {state: {action: 0.0 for action in ACTIONS} for state in range(n_states)}
# Q-learning 参数
alpha = 0.1 # 学习率
gamma = 0.9 # 折扣率
epsilon = 0.1 # 探索概率
# 环境函数
def take_action(state, action):
"""执行动作,返回(next_state, reward)"""
if action == "right":
next_state = min(state + 1, n_states - 1)
elif action == "left":
next_state = max(state - 1, 0)
else:
raise ValueError("未知动作")
reward = 1 if next_state == goal_state else 0
return next_state, reward
# 训练
for episode in range(100):
state = 0
while state != goal_state:
# ε-greedy 选择动作
if random.random() < epsilon:
action = random.choice(ACTIONS)
else:
# 选 Q值最大的动作
action = max(Q[state], key=Q[state].get)
# 在环境中执行动作
next_state, reward = take_action(state, action)
# Q 更新公式
best_next_action = max(Q[next_state], key=Q[next_state].get)
td_target = reward + gamma * Q[next_state][best_next_action]
td_error = td_target - Q[state][action]
Q[state][action] += alpha * td_error
state = next_state
# 查看学习结果
for s in range(n_states):
print(f"State {s}: {Q[s]}")
2.2 DQN
DQN 与 Q-Learning 关系密切, 是 Q-learning 在高维状态空间中的深度学习扩展.
它的 Q(·) 学习过程为:
δ t = T D _ t a r g e t − Q ( s t , a t ; θ ) T D _ t a r g e t = r t + γ max a ′ Q ( s t + 1 , a ′ ; θ − ) (2) \delta_t = TD_\_{target} - Q(s_t, a_t; \theta) \\[1em] TD_\_{target}=r_t + \gamma \max_{a'} Q(s_{t+1}, a'; \theta^-) \tag 2 δt=TD_target−Q(st,at;θ)TD_target=rt+γa′maxQ(st+1,a′;θ−)(2)
- 一些符号与 Q-Learning 一致, 不再重复
- θ − \theta^- θ−:目标网络参数(缓慢更新或定期复制)
- θ \theta θ:主网络可训练参数
L ( θ ) = E [ δ 2 ] L(\theta)=E[\delta^2] L(θ)=E[δ2], 通过最小化 TD-Target 与 Q-Value 的均方误差来最小化 TD-error. 列出表格为:
2.2.1 配套code
仍以上文的 一维走迷宫 为例, 给出 DQN 版本实现.
节省版面, 见 RL_grid_DQN.py
3. 发散与不稳定性
DQN 同时满足以下三点, 所以学习极易发散(Sutton & Barto, 2018):
- Function Approximation(函数逼近,如神经网络)
- Bootstrapping(自举,如 TD 目标使用当前估计值)
- Off-Policy Learning(异策略学习,如用 replay buffer 数据学习最优策略)
原始 DQN(无改进)在 Atari 等任务上几乎无法稳定训练.
3.1 Experience Replay(经验回放)
todo
3.2 Target Network(目标网络)
使用 θ − \theta^- θ− .
4. REINFORCE 与 PPO
它们都是 Policy Gradient 算法, 不涉及 Q() 价值, 直接优化策略 π_θ (a∣s) ,通过蒙特卡洛采样整条轨迹,用总回报作为信号来调整策略参数 θ .
4.1 理论基础
目标为最大化为期望回报:
J ( θ ) = E τ ∼ π θ [ R ( τ ) ] = ∫ π θ ( τ ) R ( τ ) d τ (1) J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} [ R(\tau) ] = \int \pi_\theta(\tau) R(\tau) \, d\tau \tag 1 J(θ)=Eτ∼πθ[R(τ)]=∫πθ(τ)R(τ)dτ(1)
- τ = ( s 0 , a 0 , s 1 , a 1 , . . . ) \tau=(s_0,a_0,s_1,a_1,...) τ=(s0,a0,s1,a1,...) 是一条轨迹 (trajectory)
- π θ ( τ ) \pi_\theta(\tau) πθ(τ) 是策略 θ \theta θ 生成该轨迹的 概率. 表达式为:
π θ ( τ ) = p ( s 0 ) ∏ t = 0 T π θ ( a t ∣ s t ) p ( s t + 1 ∣ s t , a t ) (2) \pi_\theta(\tau) = p(s_0) \prod_{t=0}^{T} \pi_\theta(a_t \mid s_t) \, p(s_{t+1} \mid s_t, a_t) \tag 2 πθ(τ)=p(s0)t=0∏Tπθ(at∣st)p(st+1∣st,at)(2) - R ( τ ) R(\tau) R(τ) 是该轨迹的总回报
4.2 计算方法
要计算梯度 ∇ θ \nabla_\theta ∇θ , 并用梯度上升更新策略参数 :
θ ← θ + α ∇ θ J ( π θ ) \theta \leftarrow \theta + \alpha \nabla_\theta J(\pi_\theta) θ←θ+α∇θJ(πθ)
直接计算 ∇ θ π θ ( τ ) \nabla_\theta \pi_\theta(\tau) ∇θπθ(τ) 较困难, 且无法对所有轨迹积分, 所以需要一个只依赖 采样轨迹 的梯度估计.
根据基本求导公式 [ l n ( x ) ] ′ = 1 x [ln(x)]'=\frac1x [ln(x)]′=x1
和 复合函数求导公式 d y d x = d y d u ⋅ d u d x \frac{dy}{dx} = \frac{dy}{du} \cdot \frac{du}{dx} dxdy=dudy⋅dxdu
可得
∇ θ log p ( x ) = 1 p ( x ) ⋅ ∇ θ p ( x ) , 可得 ∇ θ p ( x ) = p ( x ) ⋅ ∇ θ log p ( x ) \nabla_\theta \log p(x) = \frac{1}{p(x)}\cdot \nabla_\theta p(x) \\ ,可得 \nabla_\theta p(x) = p(x) \cdot \nabla_\theta \log p(x) ∇θlogp(x)=p(x)1⋅∇θp(x),可得∇θp(x)=p(x)⋅∇θlogp(x)
对应该任务中的记号, 将 p ( x ) = π θ ( τ ) p(x)=\pi_\theta(\tau) p(x)=πθ(τ) 代入得:
∇ θ π θ ( τ ) = π θ ( τ ) ⋅ ∇ θ log π θ ( τ ) (3) \nabla_\theta \pi_\theta(\tau)=\pi_\theta(\tau) \cdot \nabla_\theta \log \pi_\theta(\tau) \tag 3 ∇θπθ(τ)=πθ(τ)⋅∇θlogπθ(τ)(3)
然后对式(1)求梯度, 有:
∇ θ J ( θ ) = ∫ ∇ θ π θ ( τ ) ⋅ R ( τ ) d τ = ∫ π θ ( τ ) ⋅ ∇ θ log π θ ( τ ) ⋅ R ( τ ) d τ = E s t , a t ∼ π θ [ ∇ θ log π θ ( a t ∣ s t ) ⋅ G t ] (4) \begin{aligned} \nabla_\theta J(\theta) &= \int \nabla_\theta\pi_\theta(\tau) \cdot R(\tau) \, d\tau \\ &= \int \pi_\theta(\tau) \cdot \nabla_\theta \log \pi_\theta(\tau) \cdot R(\tau) d\tau \\ &=\mathbb{E}_{s_t, a_t \sim \pi_\theta}[\nabla_\theta \log \pi_\theta\left(a_t \mid s_t\right) \cdot G_t ] \end{aligned} \tag 4 ∇θJ(θ)=∫∇θπθ(τ)⋅R(τ)dτ=∫πθ(τ)⋅∇θlogπθ(τ)⋅R(τ)dτ=Est,at∼πθ[∇θlogπθ(at∣st)⋅Gt](4)
G t = r t + γ ⋅ G t + 1 G_t=r_t+\gamma \cdot G_{t+1} Gt=rt+γ⋅Gt+1, 表示 t 时刻的回报.
这是策略梯度中的数学基石.
4.3 REINFORCE
REINFORCE 是最基础、最经典的策略梯度(Policy Gradient)算法,也是理解 PPO、A2C 等更高级算法的基石.
算法流程(伪代码):
初始化策略网络 π_θ
for 每一轮 episode:
1. 用当前策略 π_θ 与环境交互,生成完整轨迹 τ:
s₀ → a₀ → r₀ → s₁ → a₁ → r₁ → ... → s_T
2. 计算每个时间步的回报 G_t = r_t + γ·r_{t+1} + γ²·r_{t+2} + ... + γ^{T-t} · r_T
3. 计算损失(torch 默认计算 min(loss), 而该任务求 max, 所以符号变号等价转换):
L(θ) = - (1/T) * Σ_{t=0}^{T-1} log π_θ(a_t | s_t) * G_t
4. 用梯度下降更新 θ: θ ← θ + α ∇_θ L(θ)
end.
4.4 PPO
PPO, Proximal Policy Optimization, 近端策略优化. 通过限制每次策略更新的幅度来保证训练稳定.
由 OpenAI 于 2017 年提出, 广泛应用于机器人控制、游戏 AI、推荐系统、对话系统等任务。它有两种实现:
- PPO-Clip: clip 函数将 r (θ) 限制在 [1−ϵ,1+ϵ] 区间内
- PPO-Penalty: 在目标函数中加入 KL 散度惩罚项
第一种使用 “裁剪概率比” 来实现约束, 简单实用, 更流行.
Q: 它与 SL(有监督学习) 中的 梯度剪裁(Gradient Clipping)有何差异?
A: PPO 中剪裁的不是梯度, 而是策略概率比 r t r_t rt. 解决的是分布偏移理论问题. 如果只裁剪梯度, 达不到这样的效果.
SL 中的梯度剪裁是为了解决 链式法则导致的梯度连乘数值过大问题, 属于数值计算的优化.
策略概率比 与 剪裁
新旧策略的概率比 (probability ratio) 记为 r t = π θ ( a t ∣ s t ) π θ − ( a t ∣ s t ) r_t=\frac{\pi_{\theta}(a_t|s_t)}{\pi_{\theta^-}(a_t|s_t)} rt=πθ−(at∣st)πθ(at∣st)
clip 将 r 限制在 (1−ϵ,1+ϵ) 之内, torch 中用 torch.clamp() 实现.
优势函数
At 是用旧策略估计的优势函数, 常用 Critic 网络估计,这里用标准化 G_t 简化.
优化目标
L C L I P ( θ ) = E t [ min ( r t ( θ ) ⋅ A t , clip ( r t ( θ ) , 1 − ϵ , 1 + ϵ ) ⋅ A t ) ] (5) L^{\mathrm{CLIP}}(\theta)=\mathbb{E}_t[\min (r_t(\theta)\cdot A_t, \, \,\operatorname{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) \cdot A_t)] \tag 5 LCLIP(θ)=Et[min(rt(θ)⋅At,clip(rt(θ),1−ϵ,1+ϵ)⋅At)](5)
Q: 为什么 在 clip 之后还要搭配外层的 min 呢?
A: 考虑到 A_t 的正负号的原因.
多次迭代
同一批数据(轨迹)用来多次更新网络,提高样本利用率.
4.4.1 伪代码
伪代码如下:
初始化策略网络 π_θ
for 每一轮 episode:
1. 用当前策略 π_θ 与环境交互,生成完整轨迹 τ:
s₀ → a₀ → r₀ → s₁ → a₁ → r₁ → ... → s_T
同时存储旧策略的动作 log 概率 log π_θ_old(a_t | s_t)
2. 计算每个时间步的回报:
G_t = r_t + γ·r_{t+1} + γ²·r_{t+2} + ... + γ^{T-t} · r_T
3. 计算优势估计 A_t (简单版本可直接用标准化后的 G_t 近似)
4. 对整个轨迹进行 K 次 PPO-Clip 更新:
(a)用当前策略 π_θ 重新计算 log π_θ(a_t | s_t)
(b)概率比率:
r_t(θ) = exp( log π_θ(a_t | s_t) - log π_θ_old(a_t | s_t) )
(c)两个裁剪目标:
surr1 = r_t(θ) · A_t
surr2 = clip(r_t(θ), 1 - ε, 1 + ε) · A_t
(d)PPO-Clip 损失(取最小值):
L_clip(θ) = - (1/T) * Σ_{t=0}^{T-1} min( surr1, surr2 )
(e)用梯度下降更新 θ: θ ← θ - α ∇_θ L_clip(θ)
- A_t:优势函数(常用 Critic 网络估计,这里用标准化 G_t 简化)
- 多次迭代 (K 次):同一批数据更新多次,提高样本利用率
5. Actor-Critic 方法
- Actor: 策略模型, 学习一个 策略函数 π ( a ∣ s ) π(a|s) π(a∣s):在状态 s 采取动作 a 的概率
- Critic: 估计 状态价值 V ( s ) V(s) V(s) 或 状态-动作价值 Q ( s , a ) Q(s,a) Q(s,a). 评估 Actor 当前选择的好坏. 训练时,Critic 的价值预测会反向指导 Actor 改善策略(梯度). 预测时则不需要 Critic.
为什么需要 Critic ?
如果只用 reward(例如 REINFORCE 无偏策略梯度算法),策略更新的方差很大,学习慢。Critic 能:
- 利用状态价值估计,减少梯度更新的方差。
- 利用未来累积回报的信息,使更新方向更精准。
Q: critic 需要学习 Q-value, 它和 Q-learning 是什么区别?
A: 虽然共同点都涉及 Q-value 和 TD 更新, 区别见下表.
| 对比项 | Actor-Critic (Q-based) | Q-learning |
|---|---|---|
| Q 的用途 | 指导 Actor 训练 | Q直接用于选动作 |
| 更新依据 | 一般 On-policy 更新:用当前 Actor 采样的动作 a’ 更新 | Off-policy 更新:用 m a x a ′ Q ( s ′ , a ′ ) max_{a'}Q(s',a') maxa′Q(s′,a′) 做目标 |
参考
- introduction-to-reinforcement-learning-implementation
- keras-rl
- deepmind 2013, Playing Atari with Deep Reinforcement Learning , 强化学习来打经典小游戏, 如"breakout 打砖块". 它的输入是原始的屏幕像素.
- wikipedia Q-learning
- 深度强化学习 ( DQN ) 初探
更多推荐

所有评论(0)