3.5 从 Q 到 Q-Learning
本节导读
核心内容
- 只有 V 表不够用:没有环境模型时,知道局面好不好并不能帮你做决策。
- 把表扩展一维(Q 表):给"每个状态-动作对"单独存一个分数。
- 从价值到策略(贪婪):控制问题要的是策略 ,而不是一张评分表;贪婪规则把 直接转成可执行的动作选择。
- 贝尔曼最优方程:完美的 Q 表前后两步之间必须满足的递推关系。
- Q-Learning:走一步,算一下 TD Target,改一次表。
- Off-policy 与探索:一边允许自己随机试错,一边在心里学习最理智的走法。
上一节我们介绍了 DP、MC、TD 三种价值估计方法。它们的共同目标是估计一张状态价值表 :每个状态存一个数,表示从这里继续走下去,未来平均能得到多少回报。
这张表已经比只看即时奖励前进了一大步。它不再问"这一步拿几分",而是问"从这个局面出发,长期来看值多少分"。然而,控制问题还差最后一步:智能体最终必须选择动作。只知道一个状态整体值多少分,并不一定能告诉我们在这个状态下应该向左、向右、跳跃还是停止。
先看一个具体情形。假设 CartPole 当前局面价值很高,说明"如果接下来做得合适,杆子大概率还能保持平衡"。但这句话本身没有说明现在应该向左推还是向右推。要回答这个问题,我们需要比较:
- 在同一个状态 下,先做动作 ,后面继续按某个策略行动,平均回报是多少;
- 先做另一个动作 ,后面继续行动,平均回报又是多少。
也就是说,状态价值回答的是"这个局面好不好",而控制问题真正需要的是"在这个局面下,各个动作分别好不好"。这就是动作价值函数 要解决的问题。
如果环境模型已知,我们可以从 推出动作价值。给定策略 ,在状态 先执行动作 ,会得到即时奖励 ,随后以概率 到达下一状态 。从下一状态开始,未来价值仍然由 表示。因此有:
这个式子的含义很直接:动作价值等于"先做这个动作拿到的即时奖励",加上"动作造成的下一状态价值的折扣期望"。问题在于,现实任务中我们通常不知道 和 。智能体看不到完整的转移概率表,也不知道每个动作的期望奖励;它只能一次次试,看到自己实际拿到的 和实际到达的 。
于是,一个自然的想法出现了:既然模型未知时难以用 和 去计算动作价值,不如像学习 一样,直接学习每个状态-动作对的价值。我们把表格从"每个状态一格"扩展为"每个状态下的每个动作一格"。这张表就是动作价值表,也就是 表。
有了 ,策略就可以由每个状态下动作价值最大的动作直接给出:
核心概念
这里要先分清两个名字: 和 Q-Learning。
是动作价值函数,在表格问题中也可以看成一张动作价值表。它不再只给每个状态存一个 ,而是给每个状态下的每一个动作单独存一个 。因此, 回答的不是"这个状态好不好",而是"在这个状态下先做这个动作,此后继续行动,长期来看好不好"。
在经典论文中,Q-Learning(Watkins & Dayan, 1992)被定义为一种无模型、异策略(off-policy)的 TD 控制算法:它用一步经验不断更新 ,并用 作为下一状态的“最优动作价值”估计,从而迭代逼近最优动作价值函数 [1][2]。
在表格设定下,Q-Learning 的目标就是把这张 表学准。它每收集一条经验 ,就用"即时奖励 + 下一状态的最大 Q 值"构造一个新的学习目标;学完后,在每个状态选 Q 值最大的动作,就是由动作价值表诱导出的策略。
核心公式
三行公式的逻辑链:
- 第一行定义了 的含义:在状态 先执行动作 ,此后按策略 行动,未来回报的期望。
- 第二行给出了目标:最优 Q 表的每个元素必须满足贝尔曼最优方程,即"一步奖励 + 折扣后的下一步最优价值"的期望。
- 第三行给出了方法:将贝尔曼最优方程转化为一个更新规则,每次交互后用采样到的一步经验修正 Q 表,逐步逼近第二行的目标。
动作价值函数 Q(s,a)
辨析:动作(Action)与策略(Policy)
- 动作是孤立的、局部的执行指令。比如在状态 ,你决定“向右走”,这是一个动作。它只解决“眼下这一步迈哪只脚”的问题。
- 策略则是一本“全局指导手册”。强化学习的目标不仅是走好眼下这一步,而是要得到这本手册,使得智能体无论被扔到环境的哪一个角落(哪怕是之前没去过的状态),翻开手册就知道该怎么做。写成数学符号,策略 就是一个从任意状态映射到动作的完整规则。
如果只教机器一个动作,它换个位置就又不知道该怎么办了;只有给它一个策略,它才能实现真正的自主决策。
接下来我们将介绍动作价值函数 。它直接给每个“状态-动作对”打分,用来回答“在状态 下先做动作 ,长期来看值不值”。这样一来,我们不必先学出 ,再借助环境模型 去推动作优劣;在模型未知的设定下,也能直接通过动作价值表来做决策。
动作价值表
如果说状态价值表 是“每个状态一个分数”,那么动作价值表 就是在此基础上再细分一步:同一个状态里,不同动作分别记分。 也就是说, 表回答的是“这个局面整体好不好”,而 表回答的是“在这个局面下,先做哪个动作更好”。
对于有限状态、有限动作的问题, 可以写成下面这样的二维表:
| 状态 $s$ | 向上走 | 向右走 | 向下走 | 向左走 |
|---|---|---|---|---|
| $(0,0)$ | -5.1 | -4.6 | -4.6 | -5.2 |
| $(0,1)$ | -4.2 | -3.4 | -3.8 | -4.8 |
这张表的读法很简单:每一行看一个状态,每一列看一个动作,每一个格子看“先做这个动作,后面继续走下去,长期回报大约是多少”。 例如
表示:如果智能体现在位于 ,第一步选择向右走,那么从这一刻开始计算,未来总回报的期望大约是 。这里记的不是这一步的即时奖励,而是把后续影响也一起算进去的长期价值。
这样一来,控制问题就变得直接了。到了某个状态 ,我们不再只知道“这个局面值不值”,而是已经拿到了一整行动作分数。比较这一行里的几个数,就知道当前哪个动作更值得做。
例如在状态 ,四个动作的 值分别是:向上 、向右 、向下 、向左 。这说明,如果只比较长期回报,那么“向右”和“向下”都比“向上”和“向左”更好。
从 Q 到策略
这个式子的意思就是:在状态 下,查看所有动作的 值,然后选择其中最大的那个动作。也就是说, 负责给动作打分, 负责把这些分数变成一个实际选择。由此可见,动作价值表不只是一个评价工具,它本身就可以直接导出策略。
这种“每次都选分数最高动作”的规则,称为贪婪策略。这里先讲它,不是因为策略只有这一种,而是因为它最直接:既然 已经给每个动作打了分,那么最自然的做法就是先选分数最高的动作。
当然,实际中策略并不一定非得这样定义。比如训练时,为了探索没有充分尝试过的动作,往往还会在贪婪选择之外加入一定随机性。但从“如何把 Q 值变成动作选择”这个角度看,贪婪策略是最基本、最清楚的起点。
数学定义
为了严谨定义, 的数学形式如下:
这里的条件 表示:我们先把起点状态和第一步动作固定住。因此, 表示的是:在状态 下先做动作 ,然后继续按策略 行动时,未来回报的平均值。其中,这里的未来回报展开写就是
贝尔曼最优方程
定义 之后,我们还需要回答一个更强的问题:如果目标不是评价某个给定策略,而是直接寻找最优策略,那么动作价值表应该满足什么关系?
先回到直觉。最优动作价值 表示:在状态 先执行动作 ,从下一步开始都做得最优时,能够得到的期望回报。因此,第一步动作已经被指定,不能再改变;真正的"最优选择"发生在到达下一状态 以后。到了 ,如果我们已经拥有正确的最优 Q 表,就应该选择使 最大的动作。
于是, 必须满足下面的递推关系:
这个式子就是 的贝尔曼最优方程。等式右端由两部分组成:
- 是执行当前动作后观察到的即时奖励;
- 是下一状态的最优未来价值,并按折扣因子 折现到当前时刻。
这个递推关系揭示了 Q-Learning 的驱动力:一张正确的最优 Q 表必须是自洽的。表中某一格 ,应该等于"从这一格出发实际走一步,再查下一状态最优格子"所得到的期望结果。如果当前表格违反了这种关系,说明这张表还不正确;违反得越多,更新的方向就越明确。
Q-Learning 的目标,就是在不知道完整环境模型的情况下,通过一次次采样经验,让当前估计 逐步逼近这个自洽方程的解。
Q-Learning 更新规则
贝尔曼最优方程给出了目标,但它本身仍然包含一个期望。如果环境模型已知,可以对所有可能的 和奖励分支求平均;但在 Q-Learning 的典型设定中,模型未知。智能体真正拿到的是一条一步经验:
这条经验虽然只是一次采样,却给了我们一个局部线索:当前的 至少应该向"这次看到的一步奖励 + 下一状态当前看来最好的动作价值"靠近。于是,我们用当前 Q 表构造一个采样版的贝尔曼目标:
这里有两个值得注意的地方。第一,target 只用到了真实观察到的一步转移 ,因此不需要知道完整的转移概率 。第二,target 中的 仍然来自当前这张尚未学准的 Q 表。这种"用已有估计来构造新的学习目标"的做法称为自举(bootstrapping)。
现在有了旧估计,也有了新目标。两者的差值就是 Q-Learning 版本的 TD 误差:
如果 ,说明这次经验表明 低估了,应该把它调高;如果 ,说明当前估计过于乐观,应该调低。学习率 控制每次修正的幅度,因此更新规则写成:
将 target 和 TD 误差代入,就得到 Q-Learning 的标准更新公式:
这条公式可以看作三步过程的压缩写法:
- 走一步,得到经验 ;
- 用 估计"这一格现在应该是多少";
- 不一次性覆盖旧值,而是按学习率 向目标移动一小步。
和上一节的 TD 更新
相比,Q-Learning 的变化不只是把表从 换成 。更关键的是,target 中的 变成了 。这意味着 Q-Learning 在更新时,始终把下一状态解释为"从那里开始选择当前看来最好的动作"。它不是在忠实评价当前正在执行的探索策略,而是在用探索收集数据,同时学习一张指向贪婪最优策略的动作价值表。
GridWorld:从数值示例到代码实现
以 4×4 GridWorld 为例,每步奖励 ,折扣因子 ,Q 表初始全为 0。智能体在起点 向右走,到达 ,获得 。
Gymnasium 中的 FrozenLake-v1 也是 4×4 网格环境,下图为该环境的一次运行示例:

图源:Gymnasium Documentation - Frozen Lake
先看这一步到底发生了什么:智能体站在 ,选择"向右",走到了 。环境告诉它:这一步的奖励是 。因此,Q-Learning 这次只会修改一个格子里的一个动作分数:。它不会修改 的"上"、"下"、"左",也不会修改其他格子的动作价值。
接下来要问:这个动作现在应该记多少分?Q-Learning 的想法是,先看这一步拿到了什么,再看下一格以后大概还能拿到什么。这里 Q 表刚开始全是 0,所以在下一格 ,无论选哪个动作,当前估计都还是 0:
于是,这一次看到的目标值就是:
这句话的意思很简单:这一步已经扣了 1 分,而下一格暂时还看不出好坏,所以先把"向右"这件事看作值 。
但 Q-Learning 不会一下子把旧值 0 改成 。它只往目标值移动一小步。若学习率 ,更新为:
也就是说,第一次试走以后,表格只记住一个很轻的教训:从 往右走,目前看起来比原来差一点。单次更新幅度很小;但经反复采样,负奖励路径的 Q 值持续下降,最优路径的 Q 值逐步上升。最优策略的信息从终点向起点反向传播,最终填满整张 Q 表。
代码实现
以下为不依赖外部 RL 库的 Q-Learning 核心实现。
import numpy as np
rng = np.random.default_rng(0)
N = 4
START = (0, 0)
GOAL = (3, 3)
ACTIONS = [(-1, 0), (0, 1), (1, 0), (0, -1)] # 上、右、下、左
ARROWS = np.array(["↑", "→", "↓", "←"])
def to_state(pos):
return pos[0] * N + pos[1]
def to_pos(state):
return divmod(state, N)
def step(state, action):
row, col = to_pos(state)
if (row, col) == GOAL:
return state, 0, True
dr, dc = ACTIONS[action]
next_row = min(max(row + dr, 0), N - 1)
next_col = min(max(col + dc, 0), N - 1)
next_state = to_state((next_row, next_col))
done = (next_row, next_col) == GOAL
return next_state, -1, done
Q = np.zeros((N * N, len(ACTIONS)))
alpha = 0.1
gamma = 0.9
epsilon0 = 0.3
for episode in range(2000):
state = to_state(START)
# 探索率逐渐衰减
epsilon = max(0.02, epsilon0 * (0.995**episode))
for _ in range(100):
# 1. 选动作(探索与利用)
if rng.random() < epsilon:
action = int(rng.integers(len(ACTIONS)))
else:
best_actions = np.flatnonzero(Q[state] == Q[state].max())
action = int(rng.choice(best_actions))
# 2. 和环境交互
next_state, reward, done = step(state, action)
# 3. 计算 TD Target 并更新 Q 表
bootstrap = 0 if done else Q[next_state].max()
target = reward + gamma * bootstrap
Q[state, action] += alpha * (target - Q[state, action])
state = next_state
if done:
break
print("起点四个动作的 Q 值:")
print(dict(zip(ARROWS, Q[to_state(START)].round(3))))
print("\n学到的一种贪婪策略:")
for row in range(N):
cells = []
for col in range(N):
if (row, col) == GOAL:
cells.append("G")
else:
state = to_state((row, col))
cells.append(ARROWS[int(Q[state].argmax())])
print(" ".join(cells))运行结果:
起点四个动作的 Q 值:
{'↑': -4.797, '→': -4.686, '↓': -4.686, '←': -4.919}学到的一种贪婪策略:
起点向右和向下的 Q 值均为 ,对应最短路径(6 步)的折扣回报:
Q-Learning 没有做任何全局路线规划。它只是每走一步改一次表,最终却拼凑出了全局最优解——和上一节 TD 更新 时的收敛过程一致。
训练时动作怎么选
上面的代码里有一个上一节没讨论过的问题:如果 Q 表初始全为 0,贪婪地选最大 Q 值的动作会让智能体永远在起点附近打转——所有动作的 Q 值相同,选哪个都一样。即使某个方向碰巧被选到并获得了负奖励,贪婪策略也不会主动去试别的方向。
这就是**探索(Exploration)**问题:必须让智能体有机会尝试尚未充分评估的动作,否则 Q 表的很多格子永远不会被更新。代码中使用了 -贪婪策略:以概率 选当前最优动作,以概率 随机选一个动作。 随训练逐步衰减,使早期充分探索、后期逐渐收敛到贪婪策略。
-贪婪策略带来一个重要性质:实际走的策略和 Q 表里假设的策略不一致。
- 行为策略:-贪婪,允许随机探索;
- 目标策略:完全贪婪,更新时取 ,假设未来始终选最优动作。
这种行为策略与目标策略分离的性质称为 Off-policy(异策略)。Q-Learning 在实际探索的同时,学习的是最优策略的价值,而非当前行为策略的价值。
悬崖行走:Q-Learning 与 SARSA
为了说明 Off-policy 和 On-policy 的实际影响,我们用一个经典环境:悬崖行走(Cliff Walking)。它是 Sutton & Barto 书中的标准示例,也是 Gymnasium 中的内置环境。
环境是一个 4 行 × 12 列的网格。智能体从左下角的 S 出发,目标是到达右下角的 G。每步可以向上、下、左、右移动一格。
| 规则 | 说明 |
|---|---|
| 起点 | 左下角 S(第 4 行第 1 列) |
| 终点 | 右下角 G(第 4 行第 12 列) |
| 普通步 | 奖励 $-1$ |
| 掉入悬崖 | 奖励 ,立刻回到起点 S,episode 不结束 |
| 撞墙 | 停在原地,奖励 $-1$ |
| 终止 | 到达 G 后 episode 结束 |
从 S 到 G 的最短路径是贴着悬崖边一直向右走,共 11 步。但这条路紧挨着悬崖——如果探索时碰巧向下走一步,就会掉入悬崖,扣 100 分。

图源:Gymnasium Documentation - Cliff Walking,原环境改编自 Sutton and Barto, Reinforcement Learning: An Introduction, Example 6.6。
Q-Learning(Off-policy)更新时使用 ,假设未来始终采取最优动作,因此学到的策略是沿悬崖的最短路径。
SARSA(On-policy)的更新目标为 ,其中 由当前行为策略(-贪婪)实际选出。由于 SARSA 在更新中考虑了探索导致的失误风险,它倾向于学习远离悬崖的安全路径,即使路径更长。
两种算法的差异源于对"未来策略"的不同假设:
- Q-Learning 估计的是最优策略的价值,与当前行为策略的探索无关;
- SARSA 估计的是当前行为策略的价值,因此会规避探索带来的风险。
这不是谁更好的问题,而是它们回答的问题不同。Q-Learning 回答"如果抛开探索时的随机性,理想最优是什么";SARSA 回答"带着当前的探索噪声,怎么走最安全"。
表格方法的局限
到这里,Q-Learning 似乎已经解决了模型未知时的决策问题:不需要环境模型,不用等整局结束,每走一步就能更新,4×4 GridWorld 上的收敛结果也验证了这一点。
但它有一个根本前提:状态和动作的数量,必须能被表格装下。
4×4 GridWorld 只有 16 个状态 × 4 个动作 = 64 个 Q 值。可一旦换成控制机器人,状态包含无数种角度和速度组合,是连续的无限个状态。再换成打游戏,状态是一帧帧图像,像素组合的数量远超存储能力。表格根本存不下。
所以,Q-Learning 的核心更新思想没有过时——用 TD 目标迭代逼近贝尔曼最优方程——过时的是"每个状态-动作对都单独存一行"这件事。第 4 章要解决的正是这个问题:如果表格装不下,能不能用一个神经网络来"近似"整张 Q 表?答案就是深度 Q 网络(DQN)。
上一节:DP、MC 与 TD | 下一节:从价值到策略
小结
- 动作价值函数 为每个状态-动作对赋予价值估计,决策时直接选取最大 Q 值对应的动作,无需环境模型。
- Q-Learning 以 TD 目标 更新 Q 表,通过自举逐步逼近贝尔曼最优方程的解。
- -贪婪策略以概率 随机探索、以概率 选择当前最优动作,平衡探索与利用。
- Off-policy:Q-Learning 的行为策略(-贪婪)与目标策略(贪婪)分离,允许在探索的同时学习最优策略。
- 状态空间一旦变大,表格方法就会失效,必须引入函数逼近(深度强化学习)。
练习
- 在 4×4 GridWorld 中,如果 ,最短路径的回报是多少?如果走了 8 步才到终点,回报又是多少?
- 如果把奖励改成"到达终点 +10,每走一步 0",智能体还会偏好最短路吗?为什么?
- 在 Q-Learning 更新式中,把 换成所有动作的平均值,会产生怎样的策略倾向?
- 为什么 Q-Learning 可以用旧经验学习,而 SARSA 更依赖当前策略生成的新经验?
参考文献
Watkins, C. J. C. H., & Dayan, P. (1992). Q-learning. Machine Learning, 8(3-4), 279-292. DOI: https://doi.org/10.1007/BF00992698;作者页面:https://www.gatsby.ucl.ac.uk/~dayan/papers/wd92.html. ↩︎
Sutton, R. S., & Barto, A. G. (2018). Reinforcement Learning: An Introduction (2nd ed.). MIT Press. ↩︎