↓ Skip to main content
  1. Posts/

从 Return 到 Q-Function:强化学习如何评价一个尚未发生的决策

·7406 words·15 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

上一篇结尾留了一个问题:

如果一个动作的长期回报要等到几十步甚至更多步之后才能知道,那 Agent 在当前状态下,如何判断不同动作的长期价值?

Return 可以衡量一条轨迹的累计收益。但做决策的时候,未来还没有发生——不存在一条可以直接计算的轨迹。那在当前时刻,怎么评价一个 State 甚至一个具体 Action 的长期价值?

这篇继续跟着 MIT 6.S191 Lecture 5 往下走。我发现回答这个问题的过程比预期要曲折——中间踩了好几个看起来合理但实际上不准确的直觉。

Reward 到底是谁定义的
#

上一篇介绍了 Reward(奖励):Agent 执行一个动作后,Environment 返回的标量反馈。当时为了讲清楚 Reward 和 Label 的区别,直接用了网格世界的设定——到达终点 +10,踩到陷阱 -10,每移动一步 -1。

但我学到这里时产生了一个困惑:

一个游戏本身并没有天然的 Reward = +10 或 -10。为什么强化学习可以直接使用这些数值?Reward 是人为定义的吗?

在很多情况下,确实如此。

拿最简单的棋类游戏来说。游戏本身的规则定义了输赢判定,但"赢了 +1、输了 -1、其他步骤 0"——这套数值映射是设计者选择的。游戏提供的是胜负判定规则,把判定结果转换成 Agent 可以优化的数值信号,是人的设计决策。

这个设计并不唯一。同一个游戏,可以把获胜设为 +100、失败设为 -1;也可以让每多走一步额外扣分来鼓励快速结束。不同的 Reward 定义,可能诱导 Agent 学出不同的行为。

这里有几个值得明确的点。

中间步骤 Reward = 0,不代表中间动作没有贡献。它只是说环境在这一步没有给出即时反馈。但那一步的选择仍然决定了后续走向,影响最终结果。这种大部分时间 Reward 为 0、只有终局才给反馈的情况叫 Sparse Reward(稀疏奖励),在实际问题中很常见。

有时候为了让 Agent 更容易学习,会给中间步骤也设计一些 Reward——比如离终点每近一格就加一点分。这叫 Reward Shaping(奖励塑形)。它可能加速学习,但也可能引入错误的优化目标。如果中间奖励设计得不好,Agent 可能学会追求中间奖励而不是真正完成任务。

从量化交易的角度也能感受到这一点。Reward 可以定义为最终的 PnL,也可以定义为每一步扣除交易成本后的 PnL,还可以加入风险惩罚项。不同的定义对应不同的优化目标,可能让模型学出完全不同的交易策略。

Reward 是定义 Agent 优化目标的机制。它不一定来自环境的物理规律,而可能来自设计者对"什么是好的行为"的编码。 但 Reward 定义了目标,不等于 Agent 已经知道每个 Action 的长期价值——要弄清后者,还需要更多工具。

Return 和 Value 到底差在哪里
#

继续看 6.S191 的 slide,下一个出场的概念是 Value Function(价值函数)。

我当时的第一个问题是:

Return 是从某一步开始的累计 Reward,Value 是 Return 的期望。这两个概念是不是本质上非常相似?

想了一阵,发现确实如此——但"相似"不等于"可以互换"。

先回顾 Return。上一篇给出了定义:

$$ G_t = r_{t+1} + \gamma \, r_{t+2} + \gamma^2 \, r_{t+3} + \cdots = \sum_{k=0}^{\infty} \gamma^k \, r_{t+k+1} $$

\(G_t\) 描述的是从时刻 \(t\) 开始,后续所有 Reward 的折扣累加。

这里有一个容易滑过去的细节。\(G_t\) 本身是一个随机变量——因为未来的 Reward 取决于 Agent 后续选择什么动作、环境给出什么响应,而这些都可能包含随机性。某条具体轨迹上算出来的 \(G_t\) 值,是这个随机变量的一次实现(realization),不是它本身。

这就像"掷一枚骰子的点数"是一个随机变量,而"这次掷出了 4"是一次具体的实现值。

我以前把 Return 简单理解成"已经发生的收益"。在讨论某条已经采样到的轨迹时这个说法可以接受,但用到推导里就不够准确了。

理解了这一层,Value 的出场就变得自然了。

假设某个 State 下,Agent 后续可能遇到三种情况:

结果概率Return
大胜20%+100
小胜50%+20
失败30%-40

期望值:

$$ 0.2 \times 100 + 0.5 \times 20 + 0.3 \times (-40) = 20 + 10 - 12 = 18 $$

这个 18 就是 Value。更正式地写:

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

\(V^\pi(s)\) 表示:从 State \(s\) 出发,后续遵循 Policy \(\pi\) 的情况下,Return 的条件期望。

几个容易模糊的地方。

Value = 18 是什么意思? 它不是说 Agent 从这个 State 出发一定能拿到 18 的收益。实际走一次可能拿 +100,也可能亏 -40。18 是概率加权后的平均预期。期望不代表保证。

为什么需要求期望? 因为未来有随机性——Policy 可能是随机的,环境转移也可能是随机的。只看一条轨迹的实际 Return,运气好可能很高、运气差可能很低。期望消除了单次运气的影响,给出的是"平均而言能期待多少"的评估。

为什么 Value 依赖 Policy? 上标 \(\pi\) 说明了这一点。同一个 State,如果 Agent 后续采取激进策略,大胜和失败的概率都会变化;如果换成保守策略,概率分布又不同。Value 不是 State 的固有属性,而是 State 和 Policy 联合决定的。

Value 不是与 Return 完全不同的一套评价体系。它就是 Return 的条件期望。 它把"未来可能发生的各种情况"综合成一个数值,用来评价当前 State 在给定 Policy 下的长期前景。

中间步骤都是 0 分,为什么还能评价它们
#

紧接着我遇到了一个更具体的疑问:

就算 Agent 反复与环境交互,也没办法知道每个阶段的 Reward 吧?如果只知道最后赢了还是输了,怎么评价中间每个步骤?

设计一个三步就结束的简单游戏:

$$ S_0 \xrightarrow{r_1=0} S_1 \xrightarrow{r_2=0} S_2 \xrightarrow{r_3=+10} \text{Terminal} $$

假设 \(\gamma = 0.9\)。从后往前算每个 State 的 Return:

$$ G_2 = r_3 = 10 $$$$ G_1 = r_2 + \gamma \cdot r_3 = 0 + 0.9 \times 10 = 9 $$$$ G_0 = r_1 + \gamma \cdot r_2 + \gamma^2 \cdot r_3 = 0 + 0 + 0.81 \times 10 = 8.1 $$

虽然 \(S_0\) 和 \(S_1\) 的即时 Reward 都是 0,但它们的 Return 不为 0。距终局越近的 State,Return 越高——这正是 Discount Factor 在起作用。

Reward 时间线与从后往前计算的 Return

但上面只是一条轨迹。真实的游戏通常不会每次都赢。

进一步假设这个游戏有两种可能结局:获胜(终局 Reward = +10)和失败(终局 Reward = -10)。固定某个 Policy,让 Agent 反复玩这个游戏。每次游戏结束后,可以从后往前为轨迹中每个经过的 State 算出那次的 Return。

如果 \(S_0\) 在 100 局里被经过了 100 次,每次的 Return 各不相同。把这些 Return 的平均值当作 \(V^\pi(S_0)\) 的估计——这就是 Monte Carlo(蒙特卡洛)方法的基本思想。

不需要事先知道每个动作的真实贡献,也不需要环境告诉我们中间步骤值多少分。只要能反复运行游戏、事后计算各 State 的 Return、然后统计平均,就可以估计 Value。

但需要保持清醒。最终赢了,不等于前面每一步都做对了。如果 Agent 在 \(S_1\) 时做了一个很差的选择,但后来靠运气在 \(S_2\) 挽回了局面,那这次 \(S_1\) 的 Return 仍然是正的——但不能因此就说 \(S_1\) 那步的 Action 很好。

这就是 Credit Assignment Problem(贡献归因问题):最终结果好或坏的时候,很难准确识别每一个中间 Action 的因果贡献。Return 可以作为学习信号,但它不是对单步 Action 的精确评价。上一篇讨论过这个问题,这里只是再强调一次——因为它会在后面讨论 Q-Function 时变得更加重要。

还有一个边界要说清楚。如果同一个 State 在不同轨迹中被不同的 Policy 访问过,不能不加区分地把所有轨迹的 Return 平均到一起声称得到了某个 \(V^\pi\)。\(V^\pi\) 的上标 \(\pi\) 是定义的一部分——换了 Policy,Value 就不一样了。

我以为 Policy 就是一串动作
#

说到 Policy,这里需要纠正我自己的一个误解。

上一篇已经介绍了 Policy 的基本概念:给定当前 State,输出一个 Action 的概率分布。当时我觉得自己理解了。但继续学下去之后,我发现自己脑子里一直有个不太对的模型:

Policy 是不是就是由一系列 Action 组成的序列?比如先激进、再保守、再激进——任意一串 Action 的排列组合都可以叫一个 Policy?

这个直觉看起来合理——下棋不就是一连串走法嘛。但它把两个不同的东西混在一起了。

Action 是某一步执行的具体动作。Policy 是在给定 State 下决定如何选择 Action 的规则。

随机策略的数学形式是:

$$ \pi(a \mid s) = P(a_t = a \mid s_t = s) $$

给定一个 State,它输出一个 Action 的概率分布。

用量化交易的语境举个例子:

市场 State激进 A保守 B
上涨80%20%
震荡50%50%
下跌10%90%

这张表就是一个 Policy。它定义了在每种市场状态下,选择激进策略和保守策略各自的概率。

而 A → B → B → A 是一个 Action Sequence(动作序列)。它记录的是一连串已经执行的动作,但不告诉你这些选择是基于什么规则做出的。

Policy 与 Action Sequence 的区别

两者之间的区别还有这些。

同一个 Policy,因为包含随机性(以及环境转移的随机性),可以产生完全不同的 Trajectory(轨迹)。“上涨时 80% 选 A"意味着每次上涨时有 20% 的概率走出不同的路径。

Policy 可以是固定的查找表、一组 if-else 规则,也可以是一个神经网络。无论什么形式,核心是它根据当前 State 做决定,不是提前规划好一整条路线。

预先设定一个动作序列也可以视为某种特殊的决策方式——但那是依赖时间步的开环控制,和标准的 State-Dependent Policy 不是一回事。

Policy 不是已经发生的一串动作,而是能够在不同 State 下持续产生动作选择的规则。

知道了 State 的价值,还是选不了 Action
#

到这里,Reward 定义了优化目标,Return 衡量一条轨迹的累计收益,Value 在给定 Policy 下评价一个 State 的预期长期收益。

那下一个自然的问题是:知道了 Value,能不能直接用它做决策?

假设我知道当前 State 在某个 Policy 下的 Value 是 3.075。现在面前有两个 Action——A 和 B。我应该选哪个?

我最初的反应是"3.075 只是一个绝对数值,什么都说明不了。”

后来发现这个说法不够准确。更准确的修正是:

3.075 有意义——它评价的是当前 Policy 在这个 State 下的预期长期收益。但它不够用,因为它不告诉你 A 和 B 各自的长期价值是多少。

用一个具体的例子。假设:

  • Action A:第一步 Reward = 0,下一步 50% 概率获得 +10、50% 概率获得 -2,然后结束。
  • Action B:第一步 Reward = +2,下一步确定获得 +1,然后结束。
  • \(\gamma = 0.9\)。

分别算每个 Action 的长期预期 Return。

选 A 之后:50% 概率得到 \(0 + 0.9 \times 10 = 9\),50% 概率得到 \(0 + 0.9 \times (-2) = -1.8\)。期望:

$$ 0.5 \times 9 + 0.5 \times (-1.8) = 3.6 $$

选 B 之后:确定得到 \(2 + 0.9 \times 1 = 2.9\)。

这里有一个细节值得注意:因为指定 Action 之后,后续没有进一步的决策点(游戏直接结束了),所以后续 Policy 不影响这两个值。

如果当前 Policy 规定 \(\pi(A \mid S) = 0.25\),\(\pi(B \mid S) = 0.75\):

$$ V^\pi(S) = 0.25 \times 3.6 + 0.75 \times 2.9 = 0.9 + 2.175 = 3.075 $$

到这里 A 的预期 3.6 高于 B 的 2.9。如果只看这一组数字,似乎 A 更好。

但问题在于:相同的 \(V^\pi(S) = 3.075\) 和相同的 Policy 权重 \((0.25, 0.75)\),可以来自完全不同的 Action 价值分布。

另一种情况:A 的长期预期 Return = 0.6,B 的长期预期 Return = 3.9。

$$ V^\pi(S) = 0.25 \times 0.6 + 0.75 \times 3.9 = 0.15 + 2.925 = 3.075 $$

同样的 V = 3.075,但这次 B 远好于 A。

相同的 State Value 和 Policy 动作概率,不能唯一反推出各个 Action 的价值或优劣。

同一个 V 可以对应不同的 Action 价值分布

所以需要一个能直接评价"在这个 State 下选择特定 Action 的长期价值"的工具。这就是 Q-Function,也叫 Action-Value Function(动作价值函数):

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

它和 V 的定义几乎一样,多了一个条件:当前这一步的 Action 被指定为 \(a\)。之后的所有步骤仍然按 Policy \(\pi\) 行动。

我当时纠结了很久的一点:

\(Q^\pi(s, a)\) 的定义中,“当前强制执行 Action A,后续遵循 Policy"是什么意思?是不是 override 了原来 Policy 本应选择的动作?

是的,这是一种很合适的理解方式。 Q 在评价某个 Action 时,不管当前 Policy 本来会不会以正概率选这个 Action——它就是假设当前这一步执行了 \(a\),然后看后续按 \(\pi\) 行动能得到多少期望 Return。

Q 在抽象定义中可以评价任何指定的动作。它不局限于"原来的 Policy 以正概率选择的那些 Action”。

V 与 Q 的对比:当前 Action 的选择方式不同

从图上看,\(V^\pi(s)\) 和 \(Q^\pi(s, a)\) 的区别只有一步:当前 Action 是由 \(\pi\) 选择还是被指定。后续的决策流程完全一样。

有了 Q 和 V,它们之间的数学关系也很自然。\(V^\pi(s)\) 就是按 \(\pi\) 的动作概率对 Q 做加权平均:

$$ V^\pi(s) = \sum_a \pi(a \mid s) \, Q^\pi(s, a) $$

对于离散 Action Space 使用求和;如果动作空间是连续的,求和换成积分。

代入前面的例子验证:

$$ V^\pi(S) = 0.25 \times 3.6 + 0.75 \times 2.9 = 3.075 $$

完全吻合。这个关系也可以这样理解:V 是 Policy “还没有做出选择"时的平均预期——对所有可能的 Action 按各自概率加权。Q 是"已经做出某个选择"之后的预期。V 是 Q 的概率加权平均。

最后几个容易混的地方。

Q 评价的是长期 Return,不是即时 Reward。 Action B 的即时 Reward 是 +2(高于 A 的 0),但 \(Q^\pi(S, A) = 3.6\) 仍然大于 \(Q^\pi(S, B) = 2.9\)。即时 Reward 高不等于 Q 高。

Q 仍然依赖 Policy。 上标 \(\pi\) 说明了这一点。当前 Action 被指定了,但后续的每一步都由 \(\pi\) 决定。不同的 \(\pi\) 意味着不同的后续行为,从而不同的期望 Return。

数学上固定当前 Action 不意味着实际代码中需要修改什么。 Q 是一个数学定义——它描述的是一种假设性评价:如果在这个 State 执行这个 Action,然后按 \(\pi\) 走下去,期望收益是多少。

改了 Action 之后,原来的 Q 还能用吗
#

弄清 Q 的定义之后,我产生了另一个疑问:

如果我根据 Q 的评价选择了一个不同于原来 Policy 的 Action,那原来的 Q 是不是就不准确了?毕竟我现在执行的已经不是原 Policy 了。

这句话对了一部分。需要拆成两种情况。

只改变当前这一步的 Action
#

这恰恰是 \(Q^\pi(s, a)\) 设计来处理的场景。

它的定义就是:当前这一步指定为 \(a\),后续遵循 \(\pi\)。所以如果你只是在当前这一步选了一个不同的 Action,但后续仍然按原来的 \(\pi\) 行动,原来的 Q 仍然是准确的评价。

改变了后续 Policy
#

这时候情况不同了。

用一个两阶段的例子。游戏只有两步:

$$ S_0 \xrightarrow{A,\; r=0} S_1 $$

在 \(S_1\),有两个 Action 可选:B(Reward = +1)和 C(Reward = +5)。选完之后游戏结束。\(\gamma = 0.9\)。

原 Policy \(\pi\) 在 \(S_1\) 总选择 B:

$$ Q^\pi(S_0, A) = 0 + 0.9 \times 1 = 0.9 $$

新 Policy \(\pi'\) 在 \(S_1\) 总选择 C:

$$ Q^{\pi'}(S_0, A) = 0 + 0.9 \times 5 = 4.5 $$

同一个 State-Action 对 \((S_0, A)\),换了后续 Policy,Q 从 0.9 变成了 4.5。

这里需要强调的是:原来的 \(Q^\pi(S_0, A) = 0.9\) 没有"变成错误的值”。 它仍然准确地评价了"在 \(S_0\) 选 A、后续按旧 Policy \(\pi\) 行动"的期望 Return。只是这个评价不再适用于新 Policy \(\pi'\)。

数学定义和适用范围的区别就在这里。\(Q^\pi\) 是关于 \(\pi\) 的条件定义。拿它去评价 \(\pi'\) 下的行为,就像拿上个月的市场模型预测这个月的行情——不是模型算错了,是适用条件变了。

这件事自然引出两个概念。

Policy Evaluation(策略评估):给定一个固定的 Policy \(\pi\),计算或估计它的 \(Q^\pi\) 或 \(V^\pi\)。

Policy Improvement(策略改进):根据当前的 Q 值评价,调整 Policy 使之更好。比如,如果发现 \(Q^\pi(S_0, A) = 3.6\) 而当前 Policy 只给 A 分配了 25% 的概率,那可以增加选 A 的概率。

实践中的思路往往是交替进行:先评价当前 Policy 的 Q,再根据 Q 改进 Policy,然后重新评价新 Policy 的 Q,如此循环。

Policy Evaluation 与 Improvement 的交替循环

需要说明一点。基于精确 Q 值的贪心策略改进,在标准适用条件下有理论保证——策略改进定理(Policy Improvement Theorem)保证改进后的 Policy 不会比原来差。但实际中 Q 通常是估计的、不精确的,这时候理论保证和工程实践之间有差距。这是后续算法设计要反复面对的问题,这篇不展开。

越来越像记忆化搜索
#

走到这里,我脑子里不断冒出一个联想:

Value Function 是不是就是在缓存每个 State 的"未来答案"?这和记忆化搜索也太像了。

仔细想想这个类比确实很有价值。

动态规划中的典型定义:\(f(s)\) = 从状态 \(s\) 出发,能获得的最优收益。

最优 Value Function 的定义:

$$ V^*(s) = \max_\pi V^\pi(s) $$

两者都在回答同一类问题——从某个状态出发,往后看能拿到多少。

记忆化搜索的做法是:第一次计算 \(f(s)\) 时把结果缓存起来,后续再遇到相同的 \(s\) 就直接查表。Value Function 做的事情类似——对每个 State 维护一个长期价值的评价。

但这个类比有几个重要的边界。

Value Function 是数学上的目标函数。 它定义了我们想知道什么。

记忆化搜索是计算方法。 它描述了怎么避免重复计算。

神经网络是近似器。 当 State 空间太大(比如围棋的状态数比宇宙中原子数还多)不可能逐一存储时,可以用神经网络去近似 \(V\) 或 \(Q\),并且对没见过的 State 做泛化。

三者处于不同的层面。

另一个更深层的联系:动态规划之所以能把大问题拆成子问题,是因为子问题之间存在递归关系。那 Value Function 之间是否也存在这种递归关系?答案是肯定的——但展开它需要引入 Bellman Equation,这是下一篇的内容。

在那之前,还有一个我学习时很在意的区分:

动态规划通常知道完整的 Reward 规则和 State Transition,而无模型强化学习通常不知道环境模型,只能根据经验学习。

这个说法大致对,但需要更准确地表达。

传统 DP(动态规划) 通常假设完整的环境模型已知——状态转移概率和奖励机制都可以直接用来计算。给定模型,可以精确求解。

Model-Free RL(无模型强化学习) 不掌握环境的转移概率,需要通过和环境交互获得的数据来学习 Value 或 Policy。

Model-Based RL(基于模型的强化学习) 尝试从数据中学习一个环境模型,然后在模型上做规划。

环境模型学习方式
DP已知直接基于模型计算
Model-Free RL未知从交互数据学习
Model-Based RL学习得到学模型 + 基于模型规划

几个容易出现的误解。

RL 并不总是"不知道 Reward 怎么定义"。Reward 定义可能是已知的,不知道的是环境在每种状态和动作下会如何响应。

RL 也不都是 Model-Free 的。Model-Based RL 是一个活跃的研究方向。

DP 可以处理随机转移,不要求状态转移是确定性的。核心区别不是"DP 确定、RL 随机",而是方法拥有的信息和求解方式不同。

Value Function 和动态规划之间的联系不是巧合。它们背后都指向同一个核心问题:能否把一个长期问题的答案,表达为后续子问题答案的组合?

写在最后
#

走到这里,整条链路大致清楚了。

Reward 定义了我们希望 Agent 优化什么。Return 描述一段未来轨迹的累计奖励。Value 在给定 Policy 下评价某个 State 的预期长期收益。Q 在此基础上进一步评价某个指定 Action 的长期价值。

其中我觉得最值得记住的两点:

V 和 Q 的区别只有一步。 V 是 Policy 还没选 Action 时的平均预期,Q 是已经指定当前 Action 之后的预期。后续流程完全相同。

改变当前 Action 和改变后续 Policy 是两件事。 前者正是 Q 设计来评价的场景,后者需要重新评估。

但有一个问题我一直在回避。从 \(S_0\) 出发算 \(V^\pi(S_0)\),需要知道后续 State 的 Value。从 \(S_1\) 出发算 \(V^\pi(S_1)\),又需要更后面的 Value。这些 Value 之间有没有一个递归关系——就像 DP 里 \(f(s)\) 可以用 \(f(s')\) 来表达那样?

如果有,怎么利用它?如果不知道完整的环境模型,又该怎么办?

下一篇:Bellman Equation。

参考资料
#

Related

9 年后重温 CNN:剥掉算子细节后,真正留下了什么

最近在重新过 MIT 6.S191 Lecture 3(卷积神经网络)。2017 年刚接触 CV 那会儿,CNN 算是吃饭的家伙,每天都在调。后来精力逐渐转到 ML Infra,成天跟 GPU 显存、通信拓扑和算子优化打交道,卷积网络的很多具体细节就慢慢生疏了——写个 nn.Conv2d 时 weight 的四维形状到底怎么排、Kaiming 初始化的方差怎么推、感受野怎么算,冷不丁被问到,还得在脑子里卡壳一下。