第一次接触强化学习的时候会有一种很明显的割裂感:监督学习看起来很正常,输入一个东西,输出一个标签;强化学习则是智能体和环境反复交互,奖励还经常不是立刻给的,因此很容易一开始就被各种符号和算法名字绕进去。这里还是先把最基础的框架串起来,目标是先想明白:强化学习到底在解决什么问题,价值函数和 Bellman 方程在干什么,以及 DQN、Policy Gradient、PPO 这些方法之间到底是什么关系。

强化学习在做什么

如果说监督学习是在学:

$$ f_{\theta}(x) \approx y $$

那么强化学习更像是在学一个决策规则:

$$ \pi(a \mid s) $$

也就是在状态 $s$ 下应该采取什么动作 $a$。

它和监督学习最大的不同不只是“没有现成标签”,而是:

  • 数据是智能体自己和环境交互得到的
  • 当前动作会影响未来看到的数据分布
  • 奖励往往是延迟到未来才体现的

因此强化学习的核心问题不是“这道题的正确答案是什么”,而是:

如果我现在这样做,未来一连串结果加起来到底值不值。

这也是为什么强化学习里“长期回报”会比“当前一步对不对”更重要。

马尔可夫决策过程

强化学习最常见的形式化框架是 MDP(Markov Decision Process,马尔可夫决策过程)。

一个 MDP 通常由下面几部分组成:

  • $S$:状态空间
  • $A$:动作空间
  • $P(s' \mid s, a)$:状态转移概率
  • $R(s, a)$ 或 $R(s, a, s')$:奖励函数
  • $\gamma$:折扣因子

其中折扣因子 $\gamma \in [0, 1)$ 用来平衡“眼前收益”和“长期收益”。

如果 $\gamma$ 很小,那么模型更看重眼前; 如果 $\gamma$ 很大,那么模型会更在意未来。

为什么叫马尔可夫

所谓马尔可夫性,意思是:

当前状态已经包含了做决策所需的全部信息,未来只和当前状态以及当前动作有关,而和更久远的历史无关。

也就是说:

$$ P(s_{t+1} \mid s_t, a_t, s_{t-1}, a_{t-1}, \dots) = P(s_{t+1} \mid s_t, a_t) $$

现实问题里这个假设不一定总是严格成立,但它是强化学习建模中非常核心的起点。

回报

强化学习不会只盯着一步奖励,而是更关心一条轨迹上的累计收益。

从时间步 $t$ 开始的回报一般定义为:

$$ G_t = r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \cdots $$

也可以写成:

$$ G_t = \sum_{k=0}^{\infty} \gamma^k r_{t+k} $$

这个量的含义很直接:越靠后的奖励,权重越小,但仍然会被考虑进去。

所以强化学习本质上是在做:

$$ \max_{\pi} \mathbb{E}[G_t] $$

也就是寻找一条策略,使得长期期望回报尽可能大。

策略、价值函数与 Q 函数

策略

策略(policy)就是智能体的行为规则。

  • 确定性策略:给定状态,动作唯一确定
  • 随机策略:给定状态,动作按照某个概率分布采样

随机策略通常写成:

$$ \pi(a \mid s) $$

状态价值函数

状态价值函数表示:在状态 $s$ 下,如果后面都按照策略 $\pi$ 行动,那么期望回报是多少。

$$ V^{\pi}(s) = \mathbb{E}_{\pi}[G_t \mid s_t = s] $$

它回答的是:这个状态本身值多少钱。

动作价值函数

动作价值函数表示:在状态 $s$ 下先做动作 $a$,然后后续都按照策略 $\pi$ 行动,期望回报是多少。

$$ Q^{\pi}(s, a) = \mathbb{E}_{\pi}[G_t \mid s_t = s, a_t = a] $$

它回答的是:在这个状态下,某个动作值多少钱。

很多强化学习算法本质上都在围绕 $V$ 或 $Q$ 做文章。

价值函数为什么重要

因为如果我们真的知道了最优动作价值函数 $Q^*(s, a)$,那么决策就变得非常简单:

$$ \pi^*(s) = \arg\max_a Q^*(s, a) $$

也就是说,在每个状态下直接选价值最高的动作就行。

所以很多算法其实都可以理解成在做两件事中的一件:

  1. 想办法估计价值函数
  2. 根据价值函数改进策略

Bellman 方程

Bellman 方程是强化学习里最核心的递推关系之一。它的思想其实很朴素:

一个状态的价值,等于当前一步奖励 + 下一状态的折扣价值。

Bellman 期望方程

对于给定策略 $\pi$,状态价值函数满足:

$$ V^{\pi}(s)= \sum_a \pi(a \mid s)\sum_{s', r} p(s', r \mid s, a)\left[r + \gamma V^{\pi}(s')\right] $$

动作价值函数满足:

$$ Q^{\pi}(s, a)= \sum_{s', r} p(s', r \mid s, a)\left[r + \gamma \sum_{a'}\pi(a' \mid s')Q^{\pi}(s', a')\right] $$

这两个式子本质上都在表达“当前价值可以通过下一步递推出来”。

Bellman 最优方程

最优状态价值函数满足:

$$ V^*(s) = \max_a \sum_{s', r} p(s', r \mid s, a)\left[r + \gamma V^*(s')\right] $$

最优动作价值函数满足:

$$ Q^*(s, a)= \sum_{s', r} p(s', r \mid s, a)\left[r + \gamma \max_{a'}Q^*(s', a')\right] $$

这个式子非常关键,因为很多经典方法,例如 Q-learning,本质上就是在逼近这个关系。

探索与利用

强化学习里一个永恒的问题是 exploration 和 exploitation 的平衡。

  • exploration:去尝试没怎么试过的动作,看看会不会更好
  • exploitation:优先选择当前已知最优的动作

如果只利用,不探索,就可能永远停留在一个局部还行但不够好的策略上; 如果只探索,不利用,训练效率又会很差。

最常见的例子是 $\epsilon$-greedy:

  • 以 $1-\epsilon$ 的概率选择当前价值最高的动作
  • 以 $\epsilon$ 的概率随机探索

这其实是一种非常朴素但有效的折中方案。

几条经典方法主线

强化学习里算法看起来很多,但从脉络上大致可以分成下面几条线:

  1. Dynamic Programming
  2. Monte Carlo
  3. Temporal Difference
  4. Value-based
  5. Policy-based
  6. Actor-Critic

Dynamic Programming

动态规划方法默认环境模型已知,也就是转移概率和奖励函数都能拿到。

例如:

  • Policy Evaluation:在策略固定时计算 $V^{\pi}$
  • Policy Improvement:根据当前价值函数改进策略
  • Policy Iteration:交替做 evaluation 和 improvement
  • Value Iteration:直接对最优价值函数做迭代

这条线更像理论出发点,因为现实里很多环境模型并不知道。

Monte Carlo

Monte Carlo 方法不依赖环境模型,它直接通过完整轨迹的实际回报来估计价值。

优点:

  • 思想直接
  • 无偏

缺点:

  • 必须等一整局结束才能更新
  • 方差比较大

所以它适合当作理解强化学习的一个中间站,但在很多实际问题里不够高效。

Temporal Difference

TD 方法结合了动态规划和 Monte Carlo 的特点。

它不必等一整条轨迹结束,而是一步一步更新:

$$ V(s_t) \leftarrow V(s_t) + \alpha \left[r_t + \gamma V(s_{t+1}) - V(s_t)\right] $$

其中:

$$ \delta_t = r_t + \gamma V(s_{t+1}) - V(s_t) $$

被称为 TD error。

这个量可以理解成“现实反馈和当前估计之间的差值”。很多后续算法都会围绕这个量展开。

Value-based 方法

这条线的核心思路是:先学动作价值函数,再由价值函数导出策略。

Q-learning

Q-learning 是最经典的无模型强化学习算法之一,其更新公式是:

$$ Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left[r_t + \gamma \max_{a'}Q(s_{t+1}, a') - Q(s_t, a_t)\right] $$

这里的目标值:

$$ r_t + \gamma \max_{a'}Q(s_{t+1}, a') $$

就是在用 Bellman 最优方程做一步逼近。

Q-learning 是 off-policy 的,意思是:

  • 采样动作时可以用带探索的行为策略
  • 更新目标时指向的是贪心最优策略

因此它学习的是“最优策略的价值”,而不是“当前采样策略的价值”。

SARSA

SARSA 的更新公式是:

$$ Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left[r_t + \gamma Q(s_{t+1}, a_{t+1}) - Q(s_t, a_t)\right] $$

和 Q-learning 最大的区别在于,Q-learning 用的是下一状态的最优动作价值,而 SARSA 用的是当前行为策略真实选出来的 $a_{t+1}$。

因此 SARSA 是 on-policy 的。

如果说得更直白一点:

  • Q-learning 学的是“理论上最优该怎么走”
  • SARSA 学的是“我现在这套带探索的策略实际上会怎么走”

DQN

传统 Q-learning 在状态空间小的时候可以直接维护一张 Q 表,但状态一旦很大,比如图像输入,就不可能再用表来存了。

这时候可以用神经网络去近似:

$$ Q_{\theta}(s, a) $$

这就是 DQN 的基本想法。

DQN 之所以重要,是因为它把“强化学习 + 深度神经网络”真正结合起来了。

经典 DQN 为了稳定训练,引入了两个关键技巧:

  1. Experience Replay
  2. Target Network

Experience Replay

把交互得到的 $(s, a, r, s')$ 存进经验池,再随机采样小批量数据训练。

这样做的好处是:

  • 打破样本之间的强相关性
  • 提高数据利用率

Target Network

训练目标中的下一状态价值不要每一步都用当前网络自己立刻算,而是用一个延迟更新的目标网络:

$$ y = r + \gamma \max_{a'}Q_{\theta^-}(s', a') $$

这样能让训练目标相对稳定一些,不至于“边追边跑”。

Policy-based 方法

这条线的核心思路是:不再绕一圈去学价值函数,而是直接优化策略本身。

Policy Gradient

如果策略参数化为 $\pi_{\theta}(a \mid s)$,那么我们想最大化目标函数:

$$ J(\theta) = \mathbb{E}_{\pi_{\theta}}[G_t] $$

策略梯度定理告诉我们,可以沿着下面的方向更新参数:

$$ \nabla_{\theta} J(\theta)= \mathbb{E}_{\pi_{\theta}} \left[ \sum_t \nabla_{\theta}\log \pi_{\theta}(a_t \mid s_t) G_t \right] $$

这个式子的直觉很重要:

  • 如果某个动作最后带来了高回报,就提高它出现的概率
  • 如果某个动作最后效果很差,就降低它出现的概率

REINFORCE

REINFORCE 可以看作最经典的 Policy Gradient 算法。

它直接使用整条轨迹的回报作为权重更新策略,思路非常干净,但缺点也很明显:

  • 方差大
  • 收敛慢

所以它更像是很多策略梯度方法的起点,而不是最终最好用的方法。

Actor-Critic

Actor-Critic 可以理解成把 value-based 和 policy-based 的思路揉在一起。

  • Actor:负责输出策略
  • Critic:负责评估当前动作或状态到底好不好

比较典型的做法是让 critic 去估计价值函数,再用这个估计结果帮助 actor 更新。

为什么这样做?

因为纯策略梯度虽然直接,但方差通常太大;引入 critic 之后,相当于给策略更新提供了一个更稳定的参考。

Advantage

一个很常见的量是 advantage:

$$ A(s, a) = Q(s, a) - V(s) $$

它表示“这个动作比当前状态的平均水平到底好多少”。

如果 $A(s, a) > 0$,说明这个动作比平均更好; 如果 $A(s, a) < 0$,说明这个动作不太行。

很多 actor-critic 方法都在估计这个量。

A2C / A3C

这类方法本质上还是 actor-critic,只是工程形式和并行方式不同。它们的重点在于:

  • 用 critic 降低方差
  • 用多步回报或并行采样提高训练效率

PPO

PPO(Proximal Policy Optimization)是现在实践里非常常见的一类方法。

它的核心动机不是“让策略改得越快越好”,而是:

每次更新都别走太大步,避免策略突然崩掉。

PPO 常见的 clipped objective 可以写成:

$$ L^{CLIP}(\theta)= \mathbb{E} \left[ \min \left( r_t(\theta)\hat A_t, \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)\hat A_t \right) \right] $$

其中:

$$ r_t(\theta) = \frac{\pi_{\theta}(a_t \mid s_t)}{\pi_{\theta_{old}}(a_t \mid s_t)} $$

这个比值表示新旧策略在同一个动作上的概率变化。

PPO 的核心思想就是:如果更新过猛,就把它裁掉,不让策略跳得太离谱。

这也是它在工程上比较稳定、比较好用的原因之一。

一个最小的 Q-learning 例子

下面给一个非常小的 Q-learning 伪代码例子,主要是为了把更新流程串起来:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np

n_state = 10
n_action = 2
Q = np.zeros((n_state, n_action))

alpha = 0.1
gamma = 0.99
eps = 0.1

for episode in range(1000):
    s = reset()
    done = False

    while not done:
        if np.random.rand() < eps:
            a = np.random.randint(n_action)
        else:
            a = np.argmax(Q[s])

        s_next, r, done = step(a)

        td_target = r
        if not done:
            td_target += gamma * np.max(Q[s_next])

        Q[s, a] += alpha * (td_target - Q[s, a])
        s = s_next

这段代码里最关键的逻辑其实就两步:

  1. 用 $\epsilon$-greedy 去采样,解决探索问题
  2. 用 TD target 去更新 Q 值

如果把表格换成神经网络,再加上 replay buffer 和 target network,基本就走到 DQN 的思路上去了。

强化学习里经常踩的坑

奖励设计

很多时候模型学不会,不一定是算法不够强,而是 reward 本身就有问题。

例如:

  • 奖励过于稀疏,模型很难知道什么行为是好的
  • 奖励设计有漏洞,模型学会“刷分”但没学会真正目标
  • 奖励尺度变化太大,训练不稳定

这类问题在实际项目里非常常见。

样本效率低

监督学习里一份数据可以反复训练很多轮,但强化学习的数据分布会随着策略改变而变化,而且很多样本还得自己在线采。

因此强化学习经常面临一个大问题:太费交互。

这也是为什么:

  • replay buffer
  • model-based 方法
  • offline RL

这些方向都很重要。

训练不稳定

强化学习常常同时在做几件事:

  • 数据分布在变
  • 目标在变
  • 策略在变

所以比普通监督学习更容易震荡、发散或者突然退化。

这也是为什么 target network、advantage normalization、reward normalization、clipping 这些技巧会大量出现。

Credit Assignment

有时一个动作的好坏要过很久才体现出来,这就会带来 credit assignment problem:

最后拿到奖励之后,究竟应该把功劳或责任分配给前面哪一步动作。

这个问题其实就是强化学习困难的核心之一。

Exploration 很难

在一些复杂环境里,随机乱试根本试不到真正有用的行为。

比如需要很多步连续正确动作才能第一次拿到正奖励的任务,简单的 $\epsilon$-greedy 往往不太够,这时就会需要更强的探索机制。

强化学习和深度学习的关系

强化学习本身并不等于深度学习。

  • 强化学习:解决的是序列决策问题
  • 深度学习:提供的是强大的函数拟合能力

当状态空间和动作空间很大时,就会把深度神经网络拿来近似策略函数、价值函数或者环境模型,于是就有了深度强化学习(Deep RL)。

所以 DQN、DDPG、SAC、PPO 这些方法,本质上都是在强化学习框架里引入神经网络。

小结

如果把一堆术语先放下,强化学习的主线其实不算复杂:

  1. 用 MDP 去描述智能体和环境的交互
  2. 用回报去定义“长期来看好不好”
  3. 用价值函数或策略函数去表达决策规则
  4. 用 Bellman 方程或策略梯度去指导更新
  5. 在探索、稳定性和样本效率之间不断做权衡

后面看到各种算法时,也可以大致先问自己几个问题:

  • 它是在学 value,还是直接学 policy?
  • 它是 on-policy 还是 off-policy?
  • 它靠什么降低方差、提高稳定性?
  • 它的探索机制是什么?

把这些东西先理顺,再去看具体 paper 或代码会轻松很多。