跳转到正文

3.3 V(s):价值函数与贝尔曼方程

本节导读

核心内容

  • Vπ(s)V^\pi(s):评价策略 π\pi 在状态 ss 下未来平均能拿多少分。
  • 贝尔曼方程:把“看完整个未来”改写成“眼前奖励 + 下一状态价值”。
  • 价值表:在有限状态问题中,把每个状态的 V(s)V(s) 存成一组可以更新的数字。
  • VVQQ:先评价策略,再比较动作,最终服务于找到更好的策略。

上一节我们建立了 RL 的形式化框架:MDP 描述环境规则,GtG_t 衡量一条轨迹的总回报,策略 π\pi 规定每一步怎么选动作。有了这些符号,我们已经能描述一个智能体如何和环境交互。但描述还不是求解。强化学习最终关心的是策略:在同一个状态下,换一种动作选择方式,未来可能完全不同。因此,在讨论“怎样找到好策略”之前,我们先要解决一个服务于策略改进的基础问题:怎样评价当前策略在各个状态下的表现?

状态价值函数 Vπ(s)V^\pi(s) 就是为这个问题准备的。它问的是:如果智能体现在站在状态 ss,并且从这一刻开始始终按照策略 π\pi 行动,那么未来平均能拿多少总回报?注意,Vπ(s)V^\pi(s) 不是状态天然自带的分数,而是策略 π\pi 在状态 ss 下的表现。同一个 CartPole 局面,错误策略可能很快让杆子倒下,好的策略却能把杆子稳定住;状态相同,策略不同,价值就不同。

直接计算 Vπ(s)V^\pi(s) 看起来需要枚举从 ss 出发的所有未来轨迹,这通常不可行。贝尔曼方程的作用,就是把这个长远评价拆成一步递推:先看眼前奖励,再把剩下的未来交给下一状态的价值。这样,评价策略不再需要一次看完整个未来,而可以通过相邻状态之间的关系逐步传播回来。

给定一个策略 π\pi,如何评价它在每个状态下的表现?进一步,如果我们想得到更好的策略,怎样从“评价状态”走向“选择动作”?

核心概念

贝尔曼方程连接“评价策略”和“改进策略”:先用 VπV^\pi 评价策略,再用 QQ 或最优方程比较动作,策略才有改进方向。

核心公式

Vπ(s)=Eπ[k=0γkrt+kst=s](状态价值函数定义:评估策略 π 在状态 s 下的长期回报)V^\pi(s)=\mathbb{E}_\pi\left[\sum_{k=0}^{\infty}\gamma^k r_{t+k}\mid s_t=s\right] \quad \text{(状态价值函数定义:评估策略 $\pi$ 在状态 $s$ 下的长期回报)}

Vπ(s)=aAπ(as)[R(s,a)+γsSP(ss,a)Vπ(s)](贝尔曼期望方程:固定策略下递归算价值)V^\pi(s)=\sum_{a\in\mathcal{A}}\pi(a\mid s)\left[R(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'\mid s,a)V^\pi(s')\right] \quad \text{(贝尔曼期望方程:固定策略下递归算价值)}

V(s)=maxa[R(s,a)+γsSP(ss,a)V(s)](贝尔曼最优方程:定义最优状态价值)V^*(s)=\max_a\left[R(s,a)+\gamma\sum_{s'\in\mathcal{S}}P(s'\mid s,a)V^*(s')\right] \quad \text{(贝尔曼最优方程:定义最优状态价值)}

状态价值与贝尔曼方程 (State Value and Bellman Equation):

  • Vπ(s)V^\pi(s):策略 π\pi 在状态 ss 下的价值(Value),即从 ss 开始按策略 π\pi 能拿到的平均总分。
  • rt+kr_{t+k}:未来第 kk 步拿到的单步奖励(Reward)。
  • γ\gamma:折扣因子(Gamma),控制对未来奖励的重视程度(010 \sim 1)。
  • A\mathcal{A}:动作空间,表示当前任务里所有可选动作的集合。例如 CartPole 里通常是“向左推”和“向右推”。
  • π(as)\pi(a\mid s):策略(Policy),在状态 ss 下选择动作 aa 的概率。
  • P(ss,a)P(s'\mid s,a):状态转移概率,在状态 ss 采取动作 aa 后,跳到下一个状态 ss' 的概率。

本节会反复使用下面这些符号。先明确它们各自表示什么:

符号可以先怎么理解
$s_t$tt 步的状态,比如棋盘局面、机器人姿态
$a_t$tt 步的动作,比如往左走、输出一个控制量
$\mathcal{A}$动作空间,所有可选动作的集合
$r_t$tt 步拿到的即时奖励
$\pi(a\mid s)$策略在状态 ss 下选择动作 aa 的概率
$\gamma$折扣因子,越远的奖励权重越小
$G_t$从第 tt 步开始往后累积的总回报
$V^\pi(s)$在状态 ss 开始,按策略 π\pi 行动的平均总回报

这里有一个很重要的区分:

  • rtr_t 是眼前这一步的即时奖励。它只看一步,走出这一步以后才知道。
  • GtG_t 是从第 tt 步开始,沿着某一条具体轨迹实际拿到的折扣总回报。它看的是一整条轨迹,所以不同轨迹会有不同的 GtG_t
  • Vπ(s)V^\pi(s) 不是某一条轨迹的分数,而是从状态 ss 出发、按策略 π\pi 行动时,对许多可能轨迹上的 GtG_t 取平均。
G 和 V 有什么区别?看一个数值例子

先写完整定义。折扣回报 GtG_t 的原始公式是:

Gt=k=0γkrt+kG_t = \sum_{k=0}^{\infty}\gamma^k r_{t+k}

把求和展开,就是:

Gt=rt+γrt+1+γ2rt+2+γ3rt+3+G_t = r_t+\gamma r_{t+1}+\gamma^2 r_{t+2} +\gamma^3 r_{t+3} +\cdots

现在为了演示,假设折扣因子 γ=0.9\gamma=0.9,从同一个状态 ss 出发,按同一个策略玩两次,并且每次只截取前三步奖励。也就是先看这个三步截断版本:

Gt=rt+γrt+1+γ2rt+2G_t = r_t+\gamma r_{t+1}+\gamma^2r_{t+2}

第一次比较顺利,三步奖励分别是 2,4,62,4,6。代入公式:

Gt(1)=2rt+0.9×4rt+1+0.92×6rt+2G_t^{(1)} = \underbrace{2}_{r_t} + 0.9\times \underbrace{4}_{r_{t+1}} + 0.9^2\times \underbrace{6}_{r_{t+2}}

计算得到:

Gt(1)=10.46G_t^{(1)} = 10.46

第二次后面遇到坏结果,三步奖励分别是 2,1,32,1,-3。同样代入公式:

Gt(2)=2rt+0.9×1rt+1+0.92×(3)rt+2G_t^{(2)} = \underbrace{2}_{r_t} + 0.9\times \underbrace{1}_{r_{t+1}} + 0.9^2\times \underbrace{(-3)}_{r_{t+2}}

计算得到:

Gt(2)=0.47G_t^{(2)} = 0.47

注意,两次的第一步即时奖励都是 rt=2r_t=2,但后面发生的事情不同,所以整条轨迹的 GtG_t 差很多。状态价值 Vπ(s)V^\pi(s) 是这些可能 GtG_t 的期望;如果现在只有这两次采样,可以先用它们的平均值做一个粗略估计:

Vπ(s)10.46+0.472=5.465V^\pi(s)\approx \frac{10.46+0.47}{2}=5.465

所以,rtr_t 是一步分数,GtG_t 是从某一刻开始沿着一条轨迹实际拿到的总分,而 Vπ(s)V^\pi(s) 要回答的是:如果很多次都从同一个状态 ss 出发,长期来看这些总分平均是多少。

状态价值函数:评价一个状态

上一节我们有了 MDP 五元组来描述游戏规则、GtG_t 来衡量从某一时刻开始、沿着一条实际轨迹拿到的总成绩,π\pi 来定义怎么选动作。但真正做决策时,你面对的不是“已经发生的一整局”,而是某个具体的中间局面。你需要的不是事后总结“这一次最后拿了多少分”,而是事前判断“如果我现在站在这个局面,未来大概有多好”。

这里的“平均”很重要。它不是对时间步平均,也不是把一局里的奖励简单除以步数;它是对从同一个状态 ss 出发、按照同一个策略 π\pi 继续行动时,可能发生的很多条未来轨迹取平均。因为策略可能随机,环境转移也可能随机,所以即使都从同一个状态 ss 出发,后面也可能走出不同轨迹,得到不同的 GtG_t

沿用上面的数字:同样从状态 ss 出发,一条未来轨迹的回报可能是 Gt=10.46G_t=10.46,另一条可能是 Gt=0.47G_t=0.47。这两个数都是“某一次真实发生后的总分”。如果在策略 π\pi 下,第一种未来出现的概率是 60%60\%,第二种未来出现的概率是 40%40\%,那么状态价值就是:

Vπ(s)=0.6×10.46+0.4×0.47=6.464V^\pi(s)=0.6\times 10.46+0.4\times 0.47=6.464

所以,GtG_t 像是“这一次实际跑出来的成绩单”,而 Vπ(s)V^\pi(s) 像是“还没开跑前,站在同一个状态 ss,对很多种可能成绩单做出的平均预测”。

这就自然引出了状态价值函数 Vπ(s)V^\pi(s):把 GtG_t 从“一次实际发生的总分”变成“站在状态 ss 时,未来总分的平均预测”。形式化地说,它就是 GtG_t 在条件 st=ss_t=s 下的期望:

状态价值函数的定义是:

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

如果把 GtG_t 展开,就是:

Vπ(s)=Eπ[k=0γkrt+kst=s]V^\pi(s) = \mathbb{E}_\pi \left[ \sum_{k=0}^{\infty}\gamma^k r_{t+k} \mid s_t=s \right]

这行公式可以按三层读:

  1. k=0γkrt+k\sum_{k=0}^{\infty}\gamma^k r_{t+k}:从现在开始,把未来奖励加起来。
  2. γk\gamma^k:越远的奖励打折越多。γ=0\gamma=0 只看眼前,γ\gamma 接近 1 更重视长期。
  3. Eπ[]\mathbb{E}_\pi[\cdot]:环境和策略可能有随机性,所以我们看很多次尝试的平均结果。

展开前几项看得更清楚:

Vπ(s)=Eπ[rt+γrt+1+γ2rt+2+γ3rt+3+st=s]V^\pi(s) = \mathbb{E}_\pi\big[r_t + \gamma\, r_{t+1} + \gamma^2\, r_{t+2} + \gamma^3\, r_{t+3} + \cdots \mid s_t=s\big]

每一项的含义:rtr_t 是马上拿到的奖励(不打折),γrt+1\gamma\, r_{t+1} 是下一步奖励打一次折,γ2rt+2\gamma^2\, r_{t+2} 是两步后的奖励打两次折……越远的奖励,折扣系数 γ\gamma 的幂次越高,贡献越小。用 CartPole 的数字感受:每步 r=+1r=+1γ=0.9\gamma=0.9,则 Vπ(s)1+0.9+0.81+0.729+=110.9=10V^\pi(s) \approx 1 + 0.9 + 0.81 + 0.729 + \cdots = \frac{1}{1-0.9} = 10(假设策略能永远活下去)。

一句话:Vπ(s)V^\pi(s) 是”从状态 ss 出发,按策略 π\pi 玩下去,平均能拿多少总分”。

为什么上标要写 π\pi?因为同一个状态,策略不同,价值也不同。在同一个棋局里,高手继续下和新手继续下,最终胜率当然不一样。好策略的 Vπ(s)V^\pi(s) 高,差策略的 Vπ(s)V^\pi(s) 低。RL 的目标,就是找到让价值最高的策略。

贝尔曼方程

现在回到计算本身。如果要评价策略 π\pi 在状态 ss 下的表现,最直接的办法似乎是把从 ss 出发的未来轨迹都算出来,再对回报取平均。但未来轨迹可能很长,也可能分叉很多。幸好,回报本身有一个递归结构:Gt=rt+γGt+1G_t = r_t + \gamma G_{t+1}。而状态价值又定义为 Vπ(s)=Eπ[Gtst=s]V^\pi(s) = \mathbb{E}_\pi[G_t \mid s_t = s]。把这两件事放在一起,自然产生一个问题:既然一条轨迹的回报 GtG_t 可以递归,那么评价策略用的 Vπ(s)V^\pi(s) 是否也能递归?

答案是肯定的。这就是贝尔曼方程。它不是凭空发明的概念,而是从 Vπ(s)V^\pi(s) 的定义出发,利用 GtG_t 的递归结构,把“评价策略”改写成“当前一步 + 下一状态评价”的结果。推导之前,先理解它为什么必要:

我们在前面已经定义了状态价值 Vπ(s)V^\pi(s):它是未来所有奖励的折现总和的期望。如果想知道一个状态的价值,最直观的想法就是:直接顺着策略往下走,把一条长长轨迹上的奖励加起来不就行了吗?

但这在现实中面临两个巨大的困难:

  1. 未来太长了:有些任务没有明确的终点(比如维持机器人的平衡),你要加到猴年马月?
  2. 可能性太多了:因为环境和策略都有随机性,状态会像树枝一样呈指数级分叉。要算出一个准确的期望,你需要遍历无数条轨迹。

面对这种无限视野和庞大状态树的问题,1950 年代,美国应用数学家理查德·贝尔曼(Richard Bellman) 在创立动态规划(Dynamic Programming)理论时,提出了大名鼎鼎的最优性原理(Principle of Optimality)。他发现:我们不需要一眼望穿整个未来,因为“今天的价值”里,必然包含着“明天的价值”

这就像是算退休金。你不需要现在就把未来 30 年每一天的利息都分别算清楚再相加,你只要知道:“今天的总资产 = 今天的收益 + 明天本金带来的未来总资产”。这种把一个无限期的大问题,精妙地拆解成“当前这一步”和“剩下所有步”的思想,就是动态规划的灵魂。

基于这个原理写出来的递推等式,就被称为贝尔曼方程(Bellman Equation)。它将策略评价从一个难以直接计算的“无限求和问题”,转化成只依赖相邻状态的递推关系。也正因为有这个递推关系,后续 DP、MC、TD 等方法才能通过迭代或采样来估计价值。

接下来,我们就来看看这个神奇的”递归圈”在数学上是如何从 Vπ(s)V^\pi(s) 的原始定义中严谨推导出来的。

推导过程

前面我们凭直觉理解了价值的递推关系,现在我们给出严谨的数学推导。贝尔曼方程的本质是揭示了当前状态价值与未来状态价值之间的递归关系。这一步推导的伟大之处在于:它在数学上严格证明了,我们完全可以把对未来的无限穷举遍历,等价替换成只看“眼前一步”的递归计算。

根据状态价值函数的定义,将其展开:

Vπ(s)=Eπ[Gtst=s]=Eπ[rt+γrt+1+γ2rt+2+st=s]=Eπ[rtst=s]+γEπ[rt+1+γrt+2+st=s]=rπ(s)+γEπ[Gt+1st=s]\begin{aligned} V^\pi(s) &= \mathbb{E}_\pi[G_t \mid s_t = s] \\ &= \mathbb{E}_\pi[r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \dots \mid s_t = s] \\ &= \mathbb{E}_\pi[r_t \mid s_t = s] + \gamma \mathbb{E}_\pi[r_{t+1} + \gamma r_{t+2} + \dots \mid s_t = s] \\ &= r_\pi(s) + \gamma \mathbb{E}_\pi[G_{t+1} \mid s_t = s] \end{aligned}

这里 rπ(s)r_\pi(s) 是固定策略 π\pi 后,在状态 ss 获得的期望即时奖励。它已经把动作的不确定性平均进去了:

rπ(s)=aπ(as)R(s,a)r_\pi(s)=\sum_a \pi(a\mid s)R(s,a)

接下来是最关键的一步:我们确实想把 Eπ[Gt+1st=s]\mathbb{E}_\pi[G_{t+1} \mid s_t = s] 改写成“下一状态价值”的形式,但这里不能直接写成 Vπ(st+1)V^\pi(s_{t+1})

这个直接等号在数学上是不对的。

我们打个比方来理解这种微妙的差别:

  • Eπ[Gt+1st=s]\mathbb{E}_\pi[G_{t+1} \mid s_t = s] 就像是:你今天(站在 sts_t 在预测明天开始(Gt+1G_{t+1} 能赚多少钱。因为明天可能会落到不同状态,所以这个数已经把“明天会去哪里”的不确定性平均掉了。
  • Vπ(st+1)V^\pi(s_{t+1}) 就像是:你明天(已经站在某个具体的 st+1s_{t+1} 再来算未来能赚多少钱。但在今天看来,st+1s_{t+1} 还没发生,所以 Vπ(st+1)V^\pi(s_{t+1}) 本身仍然是一个随机变量。

所以,真正不能直接写的是:

Eπ[Gt+1st=s]=Vπ(st+1)\mathbb{E}_\pi[G_{t+1} \mid s_t = s] = V^\pi(s_{t+1})

左边是一个已经在条件 st=ss_t=s 下取完平均的数,右边却还是依赖随机下一状态的量。正确的目标是把右边也放进同一个条件期望里:

Eπ[Gt+1st=s]=Eπ[Vπ(st+1)st=s]\mathbb{E}_\pi[G_{t+1} \mid s_t = s] = \mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t = s]

要把视角(也就是概率论里的条件)从 sts_t 顺利过渡到 st+1s_{t+1},我们其实不需要什么高深定理,只需要三个基础的数学工具:条件期望的定义概率论中的边缘化(Marginalization),以及强化学习最重要的物理假设——马尔可夫性(Markov Property)

补充证明:如何严谨地把条件从当前状态推到下一状态?

为了不引入让人眼花缭乱的新符号,我们全程只用 sts_t(当前状态)、st+1s_{t+1}(下一状态)和 Gt+1G_{t+1}(未来的总回报)这三个变量。 我们的终极目标是证明:Eπ[Gt+1st]=Eπ[Vπ(st+1)st]\mathbb{E}_\pi[G_{t+1} \mid s_t] = \mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t]

在推导之前,我们要先复习一个高中概率知识:什么是条件变量?期望(E\mathbb{E})到底怎么展开?

想象你在掷两枚骰子 XXYY。如果别人没告诉你任何信息,让你猜 XX 掷出来的点数平均会是多少(即期望),你会怎么算? 很简单:把骰子可能掷出的所有点数(1到6),分别乘以它们掷出的概率(1/6),然后全部加起来。写成公式就是:E[X]=xxP(x)\mathbb{E}[X] = \sum_x x \cdot P(x)。这就是最普通的期望。 但如果别人偷偷告诉你:“嘿,YY 掷出了个 6”。这时候,YY 就是一个已知条件(条件变量)。在已知 Y=6Y=6 的情况下去猜 XX,你的预测肯定会变,这就叫条件期望。写成公式就是把普通的概率换成条件概率:E[XY]=xxP(xY)\mathbb{E}[X \mid Y] = \sum_x x \cdot P(x \mid Y)

这个“把大写 E\mathbb{E} 拆成连加号 \sum 和条件概率 PP 相乘”的操作,是我们下面推导的核心武器。记住:竖线 | 后面的东西,就是我们站在当下已经确定的“既定事实”。

第一步:展开 Vπ(st+1)V^\pi(s_{t+1}) 的期望

根据定义,Vπ(st+1)V^\pi(s_{t+1}) 就是在给定 st+1s_{t+1} 且之后继续遵循策略 π\pi 的情况下,未来回报 Gt+1G_{t+1} 的期望。我们用上面复习的公式把它展开: Vπ(st+1)=Eπ[Gt+1st+1]=Gt+1Gt+1Pπ(Gt+1st+1)V^\pi(s_{t+1}) = \mathbb{E}_\pi[G_{t+1} \mid s_{t+1}] = \sum_{G_{t+1}} G_{t+1} \cdot P_\pi(G_{t+1} \mid s_{t+1})

所以,我们等式右边要算的式子 Eπ[Vπ(st+1)st]\mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t],其实就是在算一大串东西的期望:

Eπ[Vπ(st+1)st]=Eπ[Gt+1Gt+1Pπ(Gt+1st+1)  |  st]\mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t] = \mathbb{E}_\pi \left[ \sum_{G_{t+1}} G_{t+1} P_\pi(G_{t+1} \mid s_{t+1}) \;\middle|\; s_t \right]

第二步:对下一状态 st+1s_{t+1} 再次展开期望

上面那个式子最外层还有一个大写的 E[st]\mathbb{E}[\dots \mid s_t]。括号里的东西虽然长,但它本质上就是明天(st+1s_{t+1})的价值

因为“明天”会发生什么是随机的,所以 st+1s_{t+1} 是一个不确定的变量。我们怎么算这个随机变量的期望?还是用刚才那招:把每种可能出现的明天,乘以明天出现的概率,然后加起来

也就是说,外层的 Eπ[st]\mathbb{E}_\pi[\dots \mid s_t] 变成了 st+1()Pπ(st+1st)\sum_{s_{t+1}} (\dots) \cdot P_\pi(s_{t+1} \mid s_t)

Eπ[Vπ(st+1)st]=st+1(Gt+1Gt+1Pπ(Gt+1st+1))这就是 Vπ(st+1)Pπ(st+1st)明天出现的概率=st+1Gt+1Gt+1Pπ(Gt+1st+1)Pπ(st+1st)\begin{aligned} \mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t] &= \sum_{s_{t+1}} \underbrace{\left( \sum_{G_{t+1}} G_{t+1} P_\pi(G_{t+1} \mid s_{t+1}) \right)}_{\text{这就是 } V^\pi(s_{t+1})} \cdot \underbrace{P_\pi(s_{t+1} \mid s_t)}_{\text{明天出现的概率}} \\ &= \sum_{s_{t+1}} \sum_{G_{t+1}} G_{t+1} P_\pi(G_{t+1} \mid s_{t+1}) P_\pi(s_{t+1} \mid s_t) \end{aligned}

注:第二行只是把括号拆开,把外面的 Pπ(st+1st)P_\pi(s_{t+1} \mid s_t) 乘进去了。

第三步:注入马尔可夫性(最关键的一步!)

注意上面式子里的 Pπ(Gt+1st+1)P_\pi(G_{t+1} \mid s_{t+1})。根据马尔可夫性,在策略 π\pi 固定之后,未来的回报 Gt+1G_{t+1} 只和刚好发生的那一刻的状态 st+1s_{t+1} 有关,跟更早之前的状态 sts_t 没关系。 这就好比你掷骰子,第二把的结果只跟第二把怎么掷有关,跟第一把没关系。所以在数学上,我们可以在条件里强行塞进一个 sts_t,它并不会改变概率的值:Pπ(Gt+1st+1)=Pπ(Gt+1st+1,st)P_\pi(G_{t+1} \mid s_{t+1}) = P_\pi(G_{t+1} \mid s_{t+1}, s_t)。代入上式:

Eπ[Vπ(st+1)st]=st+1Gt+1Gt+1Pπ(Gt+1st+1,st)Pπ(st+1st)\mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t] = \sum_{s_{t+1}} \sum_{G_{t+1}} G_{t+1} P_\pi(G_{t+1} \mid s_{t+1}, s_t) P_\pi(s_{t+1} \mid s_t)

第四步:概率的乘法公式与边缘化

如果高中的概率知识忘了也没关系,我们可以简单推导一下条件概率的乘法公式。 最基础的条件概率公式是:P(AB)=P(A,B)P(B)P(A \mid B) = \frac{P(A, B)}{P(B)},也就是“在 B 发生的前提下,A 发生的概率”等于“A 和 B 同时发生的概率”除以“B 本身发生的概率”。 把分母乘过去,就得到了乘法公式P(A,B)=P(AB)P(B)P(A, B) = P(A \mid B) \cdot P(B)

如果我们在所有事件上都加一个额外的条件 CC 作为大前提,这个公式依然成立: P(A,BC)=P(AB,C)P(BC)P(A, B \mid C) = P(A \mid B, C) \cdot P(B \mid C)

现在,我们把 Gt+1G_{t+1} 看作 AAst+1s_{t+1} 看作 BBsts_t 看作 CC。所以式子后面的两个概率相乘可以合并:Pπ(Gt+1st+1,st)Pπ(st+1st)=Pπ(Gt+1,st+1st)P_\pi(G_{t+1} \mid s_{t+1}, s_t) \cdot P_\pi(s_{t+1} \mid s_t) = P_\pi(G_{t+1}, s_{t+1} \mid s_t)。 继续化简:

Eπ[Vπ(st+1)st]=st+1Gt+1Gt+1Pπ(Gt+1,st+1st)=Gt+1Gt+1st+1Pπ(Gt+1,st+1st)(把求和符号换个位置)=Gt+1Gt+1Pπ(Gt+1st)(把所有可能的 st+1 的概率加起来,也就是消掉 st+1)=Eπ[Gt+1st](这刚好就是条件期望的定义!)\begin{aligned} \mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t] &= \sum_{s_{t+1}} \sum_{G_{t+1}} G_{t+1} P_\pi(G_{t+1}, s_{t+1} \mid s_t) \\ &= \sum_{G_{t+1}} G_{t+1} \sum_{s_{t+1}} P_\pi(G_{t+1}, s_{t+1} \mid s_t) \quad \text{(把求和符号换个位置)} \\ &= \sum_{G_{t+1}} G_{t+1} P_\pi(G_{t+1} \mid s_t) \quad \text{(把所有可能的 $s_{t+1}$ 的概率加起来,也就是消掉 $s_{t+1}$)} \\ &= \mathbb{E}_\pi[G_{t+1} \mid s_t] \quad \text{(这刚好就是条件期望的定义!)} \end{aligned}

证毕!我们就这样一步步严谨地证明了:Eπ[Gt+1st]=Eπ[Vπ(st+1)st]\mathbb{E}_\pi[G_{t+1} \mid s_t] = \mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t]

将这个结论代回原式,我们就得到了贝尔曼方程的标准形式:

Vπ(s)=rπ(s)+γEπ[Vπ(st+1)st=s]=rπ(s)+γst+1Pπ(st+1st=s)Vπ(st+1)\begin{aligned} V^\pi(s) &= r_\pi(s) + \gamma \mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t = s] \\ &= r_\pi(s) + \gamma \sum_{s_{t+1}} P_\pi(s_{t+1} \mid s_t = s) V^\pi(s_{t+1}) \end{aligned}

第二行的展开依据是离散条件期望的定义。对于任意离散随机变量 XX 和条件 YY

E[XY]=xxP(xY)\mathbb{E}[X \mid Y] = \sum_{x} x \cdot P(x \mid Y)

即:把所有可能的结果 xx,乘以在条件 YY 下它发生的概率,再加起来。现在 XX 就是 Vπ(st+1)V^\pi(s_{t+1}),条件 YY 就是 st=ss_t = sst+1s_{t+1} 是离散随机变量,代入定义:

Eπ[Vπ(st+1)st=s]=st+1Vπ(st+1)Pπ(st+1st=s)\mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t = s] = \sum_{s_{t+1}} V^\pi(s_{t+1}) \cdot P_\pi(s_{t+1} \mid s_t = s)

每一项的直觉:从当前状态 ss 出发,按照策略 π\pi 行动后,有 Pπ(st+1st=s)P_\pi(s_{t+1} \mid s_t = s) 的概率跳到下一状态 st+1s_{t+1},而 st+1s_{t+1} 的价值是 Vπ(st+1)V^\pi(s_{t+1})。把所有可能的下一状态的价值按概率加权,就是"下一步平均能值多少"。

这就是贝尔曼方程最核心的魅力:当前状态的价值,等于即时奖励加上下一个状态价值的期望。

矩阵形式

上面的贝尔曼方程只写了一个状态 ss 的价值。但环境里不止一个状态——CartPole 有无穷多个状态,即使是简单的网格世界也有几十个。每个状态都有一条自己的贝尔曼方程,而且它们互相耦合Vπ(s)V^\pi(s) 依赖 Vπ(st+1)V^\pi(s_{t+1}),而 Vπ(st+1)V^\pi(s_{t+1}) 的方程里又可能引用回 Vπ(s)V^\pi(s)。这意味着你不能单独解一个方程,必须把所有状态的方程联立起来一起解。

为了把方程写成矩阵,我们先固定一个策略 π\pi。固定策略后,动作选择的不确定性可以被合并进两个量:

rπ(s)=aπ(as)R(s,a)r_\pi(s)=\sum_a \pi(a\mid s)R(s,a)

Pπ(ss)=aπ(as)P(ss,a)P_\pi(s'\mid s)=\sum_a \pi(a\mid s)P(s'\mid s,a)

也就是说,PπP_\pi 不是原始环境里的 P(ss,a)P(s'\mid s,a),而是“先按策略选动作,再由环境转移”之后得到的状态到状态转移概率。

当状态数量有限(NN 个)时,这 NN 个联立方程可以写成矩阵形式:

(Vπ(s1)Vπ(s2)Vπ(sN))vπ=(rπ(s1)rπ(s2)rπ(sN))rπ+γ(Pπ(s1s1)Pπ(s2s1)Pπ(sNs1)Pπ(s1s2)Pπ(s2s2)Pπ(sNs2)Pπ(s1sN)Pπ(s2sN)Pπ(sNsN))Pπ(Vπ(s1)Vπ(s2)Vπ(sN))vπ\underbrace{ \begin{pmatrix} V^\pi(s_1) \\ V^\pi(s_2) \\ \vdots \\ V^\pi(s_N) \end{pmatrix} }_{\boldsymbol{v}_\pi} = \underbrace{ \begin{pmatrix} r_\pi(s_1) \\ r_\pi(s_2) \\ \vdots \\ r_\pi(s_N) \end{pmatrix} }_{\boldsymbol{r}_\pi} + \gamma \underbrace{ \begin{pmatrix} P_\pi(s_1 \mid s_1) & P_\pi(s_2 \mid s_1) & \dots & P_\pi(s_N \mid s_1) \\ P_\pi(s_1 \mid s_2) & P_\pi(s_2 \mid s_2) & \dots & P_\pi(s_N \mid s_2) \\ \vdots & \vdots & \ddots & \vdots \\ P_\pi(s_1 \mid s_N) & P_\pi(s_2 \mid s_N) & \dots & P_\pi(s_N \mid s_N) \end{pmatrix} }_{\boldsymbol{P}_\pi} \underbrace{ \begin{pmatrix} V^\pi(s_1) \\ V^\pi(s_2) \\ \vdots \\ V^\pi(s_N) \end{pmatrix} }_{\boldsymbol{v}_\pi}

在这里:

  • vπ\boldsymbol{v}_\pi 是一个 N×1N \times 1 的列向量,装满了固定策略 π\pi 下所有状态的价值。
  • rπ\boldsymbol{r}_\pi 是一个 N×1N \times 1 的列向量,代表固定策略 π\pi 后每个状态对应的期望即时奖励。
  • Pπ\boldsymbol{P}_\pi 是一个 N×NN \times N 的策略诱导状态转移矩阵,描述了从任意状态出发、按策略行动后跳到另一个状态的概率。

如果你熟悉线性代数,就能立刻看出,这个庞大的方程组其实可以被极致压缩成一行简洁的表达式:

vπ=rπ+γPπvπ\boldsymbol{v}_\pi = \boldsymbol{r}_\pi + \gamma \boldsymbol{P}_\pi \boldsymbol{v}_\pi

为什么左右两边都是 vπ\boldsymbol{v}_\pi,却还能表示“下一状态”的价值?

这里最容易困惑的一点是:前面的单状态公式里,左边看的是当前状态,右边看的是下一状态:

Vπ(s)=rπ(s)+γsPπ(ss)Vπ(s)V^\pi(s) = r_\pi(s) + \gamma\sum_{s'}P_\pi(s'\mid s)V^\pi(s')

左边是 Vπ(s)V^\pi(s),右边却有 Vπ(s)V^\pi(s')。为什么写成矩阵后,左右两边看起来都变成了同一个 vπ\boldsymbol{v}_\pi

关键在于:矩阵形式不是只写一个状态,而是把所有状态的方程同时写出来。为了看清楚,我们把当前状态固定成 sis_i。单状态公式就变成:

Vπ(si)=rπ(si)+γjPπ(sjsi)Vπ(sj)V^\pi(s_i) = r_\pi(s_i) + \gamma\sum_j P_\pi(s_j\mid s_i)V^\pi(s_j)

这里的对应关系是:

单状态公式里的符号在矩阵里对应什么
当前状态 $s$ii 行,也就是当前正在算 sis_i 的价值
下一状态 $s'$jj 列,也就是可能跳到的 $s_j$
$P_\pi(s'\mid s)$矩阵元素 $P_\pi(s_j\mid s_i)$
$V^\pi(s')$价值向量里的第 jj 个分量 $V^\pi(s_j)$

所以,右边不是单独的 vπ\boldsymbol{v}_\pi,而是:

Pπvπ\boldsymbol{P}_\pi\boldsymbol{v}_\pi

vπ\boldsymbol{v}_\pi 这列向量只是把所有可能的“下一状态价值”都装起来:

vπ=(Vπ(s1)Vπ(s2)Vπ(sN))\boldsymbol{v}_\pi= \begin{pmatrix} V^\pi(s_1)\\ V^\pi(s_2)\\ \vdots\\ V^\pi(s_N) \end{pmatrix}

真正决定“当前状态是谁、下一状态按什么概率出现”的,是前面的 Pπ\boldsymbol{P}_\pi。矩阵乘法的第 ii 行展开后是:

(Pπvπ)i=jPπ(sjsi)Vπ(sj)(\boldsymbol{P}_\pi\boldsymbol{v}_\pi)_i = \sum_j P_\pi(s_j\mid s_i)V^\pi(s_j)

这和单状态公式右边的下一状态期望完全一样:

sPπ(ssi)Vπ(s)\sum_{s'}P_\pi(s'\mid s_i)V^\pi(s')

例如第一行对应从 s1s_1 出发:

(Pπvπ)1=Pπ(s1s1)Vπ(s1)+Pπ(s2s1)Vπ(s2)++Pπ(sNs1)Vπ(sN)(\boldsymbol{P}_\pi\boldsymbol{v}_\pi)_1 = P_\pi(s_1\mid s_1)V^\pi(s_1) + P_\pi(s_2\mid s_1)V^\pi(s_2) + \cdots + P_\pi(s_N\mid s_1)V^\pi(s_N)

也就是“从 s1s_1 出发,下一状态价值的概率加权平均”。如果下一步可能到 s2s_2,就会取 Vπ(s2)V^\pi(s_2);如果可能留在 s1s_1,也会取 Vπ(s1)V^\pi(s_1)。所有可能下一状态的价值都在同一列 vπ\boldsymbol{v}_\pi 里,所以右边仍然要用这同一列向量。

换句话说:

  • 左边的 vπ\boldsymbol{v}_\pi:每个当前状态自己的价值。
  • 右边的 vπ\boldsymbol{v}_\pi:提供所有可能下一状态的价值表。
  • 前面的 Pπ\boldsymbol{P}_\pi:按“从当前状态会跳到哪里”的概率,把这张价值表加权平均。
  • 合起来的 Pπvπ\boldsymbol{P}_\pi\boldsymbol{v}_\pi:从每个当前状态出发,下一状态价值的期望。

贝尔曼方程不是说“当前价值等于自己本身”,而是说:

当前价值=即时奖励+γ×下一状态价值的期望\text{当前价值}=\text{即时奖励}+\gamma\times\text{下一状态价值的期望}

既然这是一个关于 vπ\boldsymbol{v}_\pi 的一元一次线性方程,我们完全可以通过移项和提取公因式来直接解出 vπ\boldsymbol{v}_\pi

vπγPπvπ=rπ(IγPπ)vπ=rπvπ=(IγPπ)1rπ\begin{aligned} \boldsymbol{v}_\pi - \gamma \boldsymbol{P}_\pi \boldsymbol{v}_\pi &= \boldsymbol{r}_\pi \\ (\boldsymbol{I} - \gamma \boldsymbol{P}_\pi) \boldsymbol{v}_\pi &= \boldsymbol{r}_\pi \\ \boldsymbol{v}_\pi &= (\boldsymbol{I} - \gamma \boldsymbol{P}_\pi)^{-1} \boldsymbol{r}_\pi \end{aligned}

(注:这里的 I\boldsymbol{I} 是单位矩阵。)

至此,我们得到了固定策略 π\pi 下贝尔曼方程的解析解(Analytic Solution)。这意味着,只要环境的规则(奖励和转移概率)以及策略 π\pi 是公开透明的,我们理论上就能直接算出这个策略下所有状态的准确价值。

既然有公式,为什么还要学其他算法?

因为现实很残酷。计算解析解需要对矩阵 (IγPπ)(\boldsymbol{I} - \gamma \boldsymbol{P}_\pi) 求逆,而矩阵求逆的计算复杂度高达 O(N3)O(N^3)。如果状态空间稍微大一点(比如围棋的 1017010^{170} 种局面),这辈子都算不完。所以,这种“上帝视角”的直接求解法通常只存在于理论和极简单的玩具环境中。面对复杂问题,我们必须转向动态规划(DP)、蒙特卡洛(MC)或时序差分(TD)等通过不断迭代来逼近真实价值的算法。

动作价值函数 Q(s,a)

前面我们一直在问:“站在这个状态,按策略 π\pi 继续走,平均能拿多少分?” 这个答案就是 Vπ(s)V^\pi(s)。它很有用,但它还不够用来做选择。原因在于:Vπ(s)V^\pi(s) 只给状态打分,它没有单独回答“某一个动作本身好不好”。

换个更日常的说法:你站在一个路口,Vπ(s)V^\pi(s) 像是在说“这个路口整体还不错”。可是你真正要决定的是:往左走,还是往右走? 只知道“这个路口不错”还不够,你还想知道“先往左走大概能拿多少分,先往右走大概能拿多少分”。CartPole 里也是一样:杆子右倾时,状态价值只告诉你这个局面在当前策略下平均怎么样,却不直接告诉你现在推左好,还是推右好。

所以,我们把问题问得更细一点:在状态 ss 下,如果我先做动作 aa,接下来再按照策略 π\pi 继续行动,未来平均能拿多少分? 这个分数就是 Q 函数(Q-function),也叫动作价值函数

Vπ(s)V^\pi(s) 相比,Qπ(s,a)Q^\pi(s,a) 多看了一个东西:动作 aa。可以把二者的区别记成:

V 和 Q 的区别

对比点$V^\pi(s)$$Q^\pi(s,a)$
问的问题站在状态 ss,按策略 π\pi 走,平均怎么样?站在状态 ss先做动作 aa,再按策略 π\pi 走,平均怎么样?
动作怎么处理不单独指定动作,动作由策略 π\pi 来选先把动作 aa 指定出来
动作的影响混在策略 π\pi 的平均结果里被单独拿出来打分
适合回答这个局面整体好不好?这个局面下哪个动作更好?

所以,VV 更适合评价“局面整体好不好”,QQ 更适合比较“这个局面下哪个动作更好”。策略改进需要的是后者。

Q 函数的定义是:

Qπ(st,at)=Eπ[Gtst,at]Q^\pi(s_t, a_t) = \mathbb{E}_\pi[G_t \mid s_t, a_t]

这行公式直接定义了 Qπ(st,at)Q^\pi(s_t,a_t):当前在状态 sts_t,先指定动作 ata_t,之后继续按策略 π\pi 行动,未来回报 GtG_t 的期望是多少。

V 和 Q 的关系可以先用一句话理解:VV 是“还没决定动作时,这个状态平均值多少”;QQ 是“已经指定某个动作后,这个选择值多少”。

看一个具体状态 sts_t。假设这里只能选两个动作:向右或向左。当前策略 π\pi 不是固定选一个动作,而是有时向右、有时向左:

动作 $a_t$策略选择概率 $\pi(a_t\mid s_t)$动作价值 $Q^\pi(s_t,a_t)$Vπ(st)V^\pi(s_t) 的贡献
向右$0.7$$10$$0.7\times 10=7$
向左$0.3$$4$$0.3\times 4=1.2$

这里的 Qπ(st,向右)=10Q^\pi(s_t,\text{向右})=10,意思是:如果先向右走,之后继续按策略 π\pi 行动,平均能拿 10 分Qπ(st,向左)=4Q^\pi(s_t,\text{向左})=4,意思是先向左走后平均只能拿 4 分。

Vπ(st)V^\pi(s_t) 问的不是“指定某个动作后值多少”,而是“在策略 π\pi 自己选择动作时,这个状态平均值多少”。所以要把两种动作按策略概率加起来:

0.7×10+0.3×4=8.20.7 \times 10 + 0.3 \times 4 = 8.2

因此,这个例子里:

Vπ(st)=8.2V^\pi(s_t)=8.2

也就是说,Vπ(st)V^\pi(s_t) 不是重新定义出来的另一个东西,而是把同一个状态下所有可能动作的 Qπ(st,at)Q^\pi(s_t,a_t) 按策略概率平均起来:

Vπ(st)=atAπ(atst)Qπ(st,at)V^\pi(s_t) = \sum_{a_t \in \mathcal{A}} \pi(a_t \mid s_t) Q^\pi(s_t, a_t)

同样,Qπ(s,a)Q^\pi(s,a) 也有自己的一步递推关系:先看动作 aa 带来的即时奖励,再看动作之后到达的下一状态价值。

Qπ(st,at)=Eπ[Gtst,at]=Eπ[rt+γGt+1st,at]=R(st,at)+γEπ[Gt+1st,at]=R(st,at)+γEπ[Vπ(st+1)st,at]=R(st,at)+γst+1SP(st+1st,at)Vπ(st+1)\begin{aligned} Q^\pi(s_t, a_t) &= \mathbb{E}_\pi[G_t \mid s_t, a_t] \\ &= \mathbb{E}_\pi[r_t + \gamma G_{t+1} \mid s_t, a_t] \\ &= R(s_t, a_t) + \gamma \mathbb{E}_\pi[G_{t+1} \mid s_t, a_t] \\ &= R(s_t, a_t) + \gamma \mathbb{E}_\pi[V^\pi(s_{t+1}) \mid s_t, a_t] \\ &= R(s_t, a_t) + \gamma \sum_{s_{t+1} \in \mathcal{S}} P(s_{t+1} \mid s_t, a_t) V^\pi(s_{t+1}) \end{aligned}

这说明:采取动作 ata_t 的价值 = 动作 ata_t 带来的即时奖励 + 动作 ata_t 导致的下一状态的平均价值。

贝尔曼期望方程

有了 VVQQ 的转换关系,我们可以沿着等号继续推下去,写出完整的贝尔曼期望方程

也就是先写出 VVQQ 的关系,再把 Qπ(st,at)Q^\pi(s_t, a_t) 的贝尔曼展开式代进去:

Vπ(st)=atAπ(atst)Qπ(st,at)=atAπ(atst)[R(st,at)+γst+1SP(st+1st,at)Vπ(st+1)]\begin{aligned} V^\pi(s_t) &= \sum_{a_t \in \mathcal{A}} \pi(a_t \mid s_t) Q^\pi(s_t,a_t) \\ &= \sum_{a_t \in \mathcal{A}} \pi(a_t \mid s_t) \left[ R(s_t, a_t) + \gamma \sum_{s_{t+1} \in \mathcal{S}} P(s_{t+1} \mid s_t, a_t) V^\pi(s_{t+1}) \right] \end{aligned}

这个公式的逻辑非常清晰,分两层展开:

层级在平均什么对应公式
动作层策略可能选择不同动作$\sum_{a_t} \pi(a_t \mid s_t)$
状态层同一个动作可能到达不同下一状态$\sum_{s_{t+1}} P(s_{t+1} \mid s_t, a_t)$

直观例子:宝藏走廊

想象一条 5 格走廊,宝藏在最右边。你只能一直向右走。每走一步要花 1 点体力,所以每一步奖励是 1-1;到达宝藏后游戏结束,终点价值记为 00

先不要急着看整条路。我们从最容易的位置开始:第 5 格是宝藏,已经结束了,所以它的价值是 0。

位置为什么这样算价值
第5格已经到宝藏,不用再走$0$
第4格走一步到第5格:$-1 + 0$$-1$
第3格走一步到第4格:$-1 + (-1)$$-2$
第2格走一步到第3格:$-1 + (-2)$$-3$
第1格走一步到第2格:$-1 + (-3)$$-4$

所以这条走廊的价值表是:

[4,3,2,1,0][-4,\,-3,\,-2,\,-1,\,0]

这个例子只想说明一件事:当前位置的价值,可以用“走一步的奖励 + 下一格的价值”算出来。 这就是贝尔曼方程最直观的样子。

贝尔曼最优方程

贝尔曼期望方程回答的是:“如果我按照策略 π\pi 行动,状态 sts_t 值多少分?” 但 RL 的终极目标是寻找最好的策略。我们想知道:“如果我每一步都做最优选择,状态 sts_t 最多值多少分?”

这就引出了最优价值函数 V(st)V^*(s_t) 和最优动作价值函数 Q(st,at)Q^*(s_t, a_t)。 在一个状态下,最优的选择就是挑出那个让 Q(st,at)Q^*(s_t, a_t) 最大的动作:

V(st)=maxatAQ(st,at)V^*(s_t) = \max_{a_t \in \mathcal{A}} Q^*(s_t, a_t)

同样,最优的 Q(st,at)Q^*(s_t, a_t) 依然遵循贝尔曼递推关系(只是未来的状态也被认为会按照最优策略行动):

Q(st,at)=R(st,at)+γst+1SP(st+1st,at)V(st+1)Q^*(s_t, a_t) = R(s_t, a_t) + \gamma \sum_{s_{t+1} \in \mathcal{S}} P(s_{t+1} \mid s_t, a_t) V^*(s_{t+1})

Q(st,at)Q^*(s_t, a_t) 代入 V(st)V^*(s_t) 中,我们就得到了贝尔曼最优方程

V(st)=maxatA[R(st,at)+γst+1SP(st+1st,at)V(st+1)]V^*(s_t) = \max_{a_t \in \mathcal{A}} \left[ R(s_t, a_t) + \gamma \sum_{s_{t+1} \in \mathcal{S}} P(s_{t+1} \mid s_t, a_t) V^*(s_{t+1}) \right]

对比期望方程和最优方程,唯一的区别在于:求和(平均)变成了求最大值(max\max

  • 期望方程 atπ(atst)\sum_{a_t} \pi(a_t \mid s_t):按照策略的概率加权平均。
  • 最优方程 maxat\max_{a_t}:抛弃概率,直接挑选价值最大的那个动作。只要解出了最优方程,最优策略也就自然产生了(每次选 argmaxatQ(st,at)\arg\max_{a_t} Q^*(s_t,a_t) 即可)。

看一个两步小例子。现在站在状态 ss,你有两个动作:向右或向左。先把路径写清楚:

当前动作眼前奖励到达哪里
向右$+1$$s_R$
向左$+0$$s_L$

真正容易混淆的是“到达下一状态以后,后面怎么走”。普通策略和最优策略在这里不一样:

到达的状态后面继续按普通策略 π\pi后面每一步都按最优方式走
$s_R$平均还能拿 $5$最多还能拿 $7$
$s_L$平均还能拿 $2$最多还能拿 $4$

这张表的意思是:如果第一步向右到了 sRs_R,普通策略 π\pi 后面可能还会探索、可能不会每次都选最好动作,所以它平均还能拿 55;但如果从 sRs_R 开始每一步都选最好的动作,最多还能拿 77。如果第一步向左到了 sLs_L,普通策略后面平均还能拿 22;但如果后面也每一步都选最优动作,最多能拿 44

现在再算 QQ 就清楚了。先看普通策略 π\piQπ(s,a)Q^\pi(s,a) 的意思是:先做动作 aa,之后继续按策略 π\pi

动作奖励下一状态后续按 π\pi 走的价值$Q^\pi$
向右$+1$$s_R$$5$$Q^\pi(s,\text{右})=1+5=6$
向左$+0$$s_L$$2$$Q^\pi(s,\text{左})=0+2=2$

如果当前策略 π\pi 在状态 ss 仍然随机探索,比如 40%40\% 选向右、60%60\% 选向左,那么它的状态价值就是把这两个 QπQ^\pi 按概率平均:

Vπ(s)=0.4×Qπ(s,)+0.6×Qπ(s,)=0.4×6+0.6×2=3.6V^\pi(s)=0.4\times Q^\pi(s,\text{右})+0.6\times Q^\pi(s,\text{左}) =0.4\times 6+0.6\times 2=3.6

再看最优情况。Q(s,a)Q^*(s,a) 的意思是:先做动作 aa,之后每一步都按最优方式走。所以向右之后用的是 sRs_R 的最优后续价值 77,不是普通策略下的 55

动作奖励下一状态后续按最优走的价值$Q^*$
向右$+1$$s_R$$7$$Q^*(s,\text{右})=1+7=8$
向左$+0$$s_L$$4$$Q^*(s,\text{左})=0+4=4$

在当前状态,向右的最优动作价值是 8,向左是 4,所以最优价值直接取最大值:

V(s)=maxaQ(s,a)=max(8,4)=8V^*(s)=\max_a Q^*(s,a)=\max(8,4)=8

所以两种计算的区别是:

情况用的是哪个 Q当前动作怎么处理算出来的 V
普通策略 $V^\pi$$Q^\pi$按策略概率平均:0.40.4 右、0.60.6$3.6$
最优价值 $V^*$$Q^*$直接选最大:$\max_a Q^*(s,a)$$8$

期望方程是在评价“当前策略平均怎么样”,所以用 QπQ^\pi 并按策略概率平均;最优方程是在寻找“从现在到未来都做最佳选择,最多能有多好”,所以用 QQ^* 并取最大值。

价值表:从价值方程到可更新的表格

到这里,我们已经知道 Vπ(s)V^\pi(s) 的定义,也推导出了贝尔曼方程。它告诉我们:如果策略 π\pi 固定,真正的价值函数必须满足“眼前奖励 + 下一状态价值”的递推关系。

不过,贝尔曼方程只给出了一条约束,并没有直接给出答案——它说的是“真正的 VV 必须让当前状态和下一状态的价值互相对得上”。这就像写出一组线性方程,还不等于解出了每个未知数;知道价值之间应该怎样递推,也不等于已经知道每个 V(s)V(s) 的具体数值。

要把方程变成算法,我们需要给每个状态分配一个存储位置,初始随便填个数,然后让程序反复修改它、逼近真实值——这就是价值表

如果状态空间很小,最朴素的做法就是为每个状态保存一个数字,不需要先上神经网络。比如三格走廊里有三个状态 S,M,GS,M,G,我们就准备三行:

状态 $s$当前估计 $V(s)$含义
$S$$0$SS 出发的长期回报估计
$M$$0$MM 出发的长期回报估计
$G$$0$从终点出发,通常没有后续回报

这张“状态 \rightarrow 价值估计”的清单,就是本书说的价值表。它不是新的数学对象,而是 VV 的一种表示方式。数学上,它可以看成前面矩阵形式里的价值向量 v\boldsymbol{v};程序里,它可以是 NumPy 数组、Python 字典、哈希表,或者数据库表中的一列。

更一般地说,这属于表格方法(tabular methods)。在强化学习文献中,表格方法指的是:状态和动作数量足够小,可以为每个状态或每个状态-动作对保存一个独立条目,并直接更新这些条目[1]。所以“表”不一定真的画成电子表格;重点是每个状态都有一个单独的存储位置。

这里先把两个容易混淆的东西分开:

  • 环境规则表:描述任务本身,记录“从哪里、做什么、到哪里、拿到多少奖励”。在这种小型离散问题里,它就是环境模型的一种表格表示;如果环境有随机性,表里还要写出到不同下一状态的概率。
  • 价值表:描述算法当前的判断,记录“从这个状态出发,长期来看大概值多少”。

教材里经常把价值表直接画在状态空间上。下面这张图来自 Sutton 和 Barto 的小型 Gridworld 策略评估例子。这里的 GridWorld 是一个网格环境:格子表示状态,移动方向表示动作,格子里的数字表示当前对 Vk(s)V_k(s) 的估计。

左列展示同一个随机策略经过 k=0,1,2,3,10,k=0,1,2,3,10,\infty 轮策略评估后的价值表;右列展示如果拿这些价值表去做贪心选择,会得到怎样的策略。

Sutton 和 Barto 教材中小型 Gridworld 的迭代策略评估示意:左列是不同迭代轮次下的状态价值表,右列是对应贪心策略。

图源:Sutton and Barto, Reinforcement Learning: An Introduction, 2nd ed., Figure 4.1。原书采用 CC BY-NC-ND 2.0 许可。

先只看左列就够了。k=0k=0 时,除了终点,许多格子的价值估计都从 0 开始;迭代几轮以后,靠近终点的位置先发生变化,更远的位置再慢慢被带动。这里的数字不是“走进这一格立刻得到的奖励”,而是“从这一格出发,之后按当前策略走,预期总共会得到多少回报”。

换个最小例子看,考虑一个三格走廊:

环境规则表:记录一步会发生什么

当前状态动作下一状态奖励
$S$右走$M$$-1$
$M$右走$G$$-1$
$G$结束$0$

价值表:记录从这里出发以后大概值多少

状态 $s$当前估计 $V(s)$含义
$S$$-2$SS 出发预计还要走两步
$M$$-1$MM 出发预计还要走一步
$G$$0$已经到终点,没有后续奖励

第一张表来自环境,告诉我们“走一步会发生什么”;在这个走廊例子里转移是确定的,所以每一行只写一个下一状态。如果同一个动作可能通向多个下一状态,环境规则表就要写成带概率的形式,也就是 P(ss,a)P(s'\mid s,a)。第二张表来自算法,保存当前对长期回报的估计。奖励是一步的,价值是长期的;奖励由环境给出,价值需要算法估计。

注意,第二张表里的 2,1,0-2,-1,0 是已经算对之后的结果。算法一开始通常不知道这些答案,它可能先把整张表初始化为 0:

状态 $s$当前估计 $V(s)$
$S$$0$
$M$$0$
$G$$0$

这里的 0 不是说这些状态真的只值 0 分,而是说“现在还不知道,先用 0 作为初始猜测”。后面的 DP、MC、TD 要做的,就是不断修改右边这一列,让它逐渐接近真实的 VπV^\pi

总结一下:价值表解决的是一个很具体的问题——给抽象的价值函数一个可以反复更新的载体。当状态数量有限且能枚举时,价值表就是最直接的表示;当状态空间巨大或连续时,这张表装不下,后面才需要用函数近似和神经网络来代替。

同一个思想也会自然扩展到动作价值。状态价值表只给每个状态存一个数;动作价值表则给每个“状态-动作对”存一个数,也就是 Q(s,a)Q(s,a)。第 3.5 节看到的 Q 表,本质上就是把这里的价值表从“每个状态一格”扩展成“每个状态下每个动作一格”。经典 TD 学习可以看成用经验修正状态预测值[2];Q-learning 则是在有限状态、有限动作并反复采样的表格设定下更新动作价值[3]

从方程到更新规则

上一小节已经说明了价值表的作用:每个状态都在表里有一个位置,但里面的数字一开始只是临时估计。接下来真正要解决的是:这些数字应该怎样一步步变成更接近真实价值的估计?

先把贝尔曼方程换个角度看。前面写它时,它像一个“正确答案必须满足的等式”:

Vπ(s)=aπ(as)[R(s,a)+γsP(ss,a)Vπ(s)].V^\pi(s)= \sum_a\pi(a\mid s) \left[ R(s,a)+\gamma\sum_{s'}P(s'\mid s,a)V^\pi(s') \right].

这里左右两边都是真正的 VπV^\pi,所以它是在描述最终答案的关系。但算法一开始没有真正的 VπV^\pi,只有一张临时价值表 VkV_k。于是自然的做法是:把方程右边当成一个新的目标值,用它来改写旧表

回答怎么改写之前,先区分两种情况:

  • 环境模型已知:这里的“环境模型”,指的是环境规则的数学版本:在状态 ss 做动作 aa 后,会以什么概率到达各个下一状态 ss',以及平均会拿到多少奖励。也就是我们清楚转移概率 P(ss,a)P(s'\mid s,a) 和奖励 R(s,a)R(s,a),可以直接用贝尔曼方程构造更新规则。
  • 环境是黑盒:我们不知道这些信息,只能实际走一步,观察到一个奖励和一个下一状态。

先看第一种情况。

对固定策略 π\pi,把旧表记作 VkV_k。现在我们不再假装已经知道真实的 VπV^\pi,而是拿旧表里的 Vk(s)V_k(s') 去估计下一状态的价值:

BellmanTargetk(s)=aπ(as)[R(s,a)+γsP(ss,a)Vk(s)].\text{BellmanTarget}_k(s)= \sum_a\pi(a\mid s) \left[ R(s,a)+\gamma\sum_{s'}P(s'\mid s,a)V_k(s') \right].

这一步的含义是:

  • 内层的 sP(ss,a)Vk(s)\sum_{s'}P(s'\mid s,a)V_k(s'),是在算“做动作 aa 后,下一状态价值的期望”。
  • 外层的 aπ(as)\sum_a\pi(a\mid s),是在按当前策略 π\pi 对动作再取平均。
  • 加上 R(s,a)R(s,a) 和折扣因子 γ\gamma 后,得到的是“旧表认为状态 ss 现在应该值多少”。

于是更新规则就很直接:

Vk+1(s)BellmanTargetk(s).V_{k+1}(s)\leftarrow \text{BellmanTarget}_k(s).

对所有状态都做一次这样的计算,就得到新一轮价值表 Vk+1V_{k+1}。这一步常被称为一次 Bellman backup(贝尔曼备份):用下一状态的旧估计,反过来更新当前状态。

有时我们也不直接替换,而是只往目标值移动一小步:

V(s)V(s)+α[BellmanTargetk(s)V(s)].V(s)\leftarrow V(s)+\alpha\left[\text{BellmanTarget}_k(s)-V(s)\right].

这里 α\alpha 是学习率。α=1\alpha=1 表示完全采用新目标;α=0.1\alpha=0.1 表示只把旧值往目标方向挪 10%。不管是直接替换,还是小步移动,核心思想都一样:贝尔曼方程右边给出目标,价值表负责保存当前估计

用一个最小的例子来验证这件事。为了不被多个状态分散注意力,先把价值表缩到最小:整张表只有一行,唯一的状态是 ss

状态 $s$当前估计 $V(s)$
$s$$0$

想象你面前只有一台老虎机 A,每一轮按下按钮得到一次奖励,然后又回到同一个状态 ss。策略固定:永远选择 A。现在只问一个问题:

从这个状态开始,一直玩下去,折扣后的平均总回报是多少?

设定如下:

  • 只有一个状态,玩完一轮还是回到同一个状态。
  • 永远选择 A 机器。
  • A 机器 60% 概率奖励 +1+1,40% 概率奖励 1-1
  • 折扣因子 γ=0.9\gamma=0.9

单步期望奖励是:

R=0.6×(+1)+0.4×(1)=0.2R=0.6\times(+1)+0.4\times(-1)=0.2

因为每一轮之后还是同一个状态,所以下一状态价值仍然要查价值表里的同一格,也就是 V(s)V(s)。根据贝尔曼期望方程,有:

V(s)=0.2+0.9V(s)V(s)=0.2+0.9V(s)

解析解:直接解方程,V(s)0.9V(s)=0.2V(s)-0.9V(s)=0.2,得到 V(s)=2.0V(s)=2.0。这个 2.02.0 不是单步奖励,而是价值表里状态 ss 这一格最终应该接近的数字,表示“从现在开始一直玩下去,折扣后的平均总回报”。

迭代法:如果我们不想(或者不能)直接解方程,也可以从初始价值表 V0(s)=0V_0(s)=0 开始,每轮执行一次贝尔曼更新,把状态 ss 这一格改成新的估计:

Vk+1(s)R+γVk(s)V_{k+1}(s)\leftarrow R+\gamma V_k(s)

先手算前几轮:

轮次更新公式表中 V(s)V(s) 的新值
初始-$0$
第 1 轮$0.2+0.9\times0$$0.2$
第 2 轮$0.2+0.9\times0.2$$0.38$
第 3 轮$0.2+0.9\times0.38$$0.542$
第 4 轮$0.2+0.9\times0.542$$0.6878$
第 5 轮$0.2+0.9\times0.6878$$0.81902$

每一轮都用“即时期望奖励 0.20.2 + 折扣后的旧价值估计”来得到新的估计。因为这里只有一个状态,所以看起来只是在更新一个数;换成多个状态时,同样的操作就是逐格更新整张价值表。刚开始离 2.02.0 很远,但会一点点靠近。

python
R = 0.2
gamma = 0.9
V = 0.0

for i in range(50):
    V = R + gamma * V

print(round(V, 6))

运行结果

1.998698

这就是贝尔曼迭代的基本形状:不是一次把答案算出来,而是反复应用贝尔曼关系,让估计值逐步接近真实价值。在固定策略 π\pi 下,它对应的是迭代策略评估;如果以后把“按策略平均”换成“对动作取最大值”,就会走向最优控制里的价值迭代。

当环境是黑盒:TD 误差

先回到刚才的老虎机例子。那里我们能写出 V(s)=0.2+0.9V(s)V(s)=0.2+0.9V(s),是因为两件事都已经知道:平均每次奖励是 0.20.2,按完按钮以后一定回到同一个状态。换句话说,我们知道环境规则,所以可以直接算“平均来说下一步会怎样”。

真实任务通常没有这么方便。智能体不知道每个动作之后会去哪里,也不知道各种结果各有多大概率。它只能真的走一步,看到一个奖励,再看到自己落在哪个状态。TD 误差就是在这种情况下用的:先把它理解成一个对账工具,比较“这一步实际经历给出的目标”和“价值表里原来的估计”差了多少。

如果第一次读到这里还没有完全理解,没有关系。下一节会把 DP、MC、TD 放在一起对比,后面讲具体算法时也会反复回到这个概念。现在先抓住一个区别:模型已知时,我们算的是平均情况;TD 看到的是刚刚发生的这一种情况

先看模型已知的写法。假设我们知道完整环境规则,就可以写出精确的 Bellman target:

aπ(as)[R(s,a)+γsP(ss,a)V(s)].\sum_a\pi(a\mid s) \left[ R(s,a)+\gamma\sum_{s'}P(s'\mid s,a)V(s') \right].

这里的 R(s,a)R(s,a) 不是某一次奖励,而是平均奖励;P(ss,a)P(s'\mid s,a) 也不是某一次下一状态,而是到每个下一状态的概率。这个式子的意思是:把所有可能动作、所有可能下一状态都算进去,再按概率平均。

TD 做不到这一点。它没有那张概率表,只知道刚才这一步真实发生了什么:这次拿到的奖励是 rr,这次到达的下一状态是 ss'。于是它先用这一条经验拼出一个临时目标:

Target=r+γV(s)\text{Target} = r + \gamma V(s')

这里用小写的 rrss',就是在提醒我们:它们不是环境的平均规律,而是刚刚看到的一次结果。这个 target 可能偏高,也可能偏低;但样本多了以后,这些高高低低会逐渐互相抵消。

对比起来就是:

方法用到的奖励用到的下一状态target 的性质
精确 Bellman 更新期望奖励 $R(s,a)$所有可能的 ss',按 P(ss,a)P(s'\mid s,a) 加权平均精确期望
TD 更新这一次实际奖励 $r$这一次实际到达的 $s'$带噪声的一次样本估计

用一组数值看会更清楚。假设在状态 ss 按当前策略行动后,环境有两种可能:

下一状态概率这一步奖励当前价值估计
$s_1$70%$+1$$V(s_1)=5$
$s_2$30%$-1$$V(s_2)=0$

γ=0.9\gamma=0.9。如果模型已知,我们会把两种可能都算进去:

BellmanTarget=0.7×(1+0.9×5)+0.3×(1+0.9×0)=3.55.\text{BellmanTarget} =0.7\times(1+0.9\times5)+0.3\times(-1+0.9\times0) =3.55.

这就是精确 Bellman 更新:它像是手里有一张环境说明书,知道从 ss 出发可能发生哪些结果,也知道每种结果的概率,所以可以一次算出平均目标 3.553.55

TD 的处境不一样。它没有这张说明书,也不是自己主动按 70% 和 30% 去抽结果。所谓“采样”,只是说:智能体真实走了一步,环境给了它一个结果。如果这个环境本来就有“多数时候到 s1s_1、少数时候到 s2s_2”的规律,那么反复从 ss 出发时,智能体自然会更常看到 s1s_1,偶尔看到 s2s_2。但在每一次更新时,TD 只使用眼前这一条经历。

假设现在价值表里 V(s)=3V(s)=3,学习率 α=0.1\alpha=0.1

如果这一次真的到了 s1s_1,拿到奖励 r=1r=1,TD 会算:

TD Target=1+0.9×5=5.5,\text{TD Target}=1+0.9\times5=5.5,

δ=5.53=2.5,\delta=5.5-3=2.5,

于是把 V(s)V(s) 往上调一点:

V(s)3+0.1×2.5=3.25.V(s)\leftarrow 3+0.1\times2.5=3.25.

如果另一次真的到了 s2s_2,拿到奖励 r=1r=-1,TD 会算:

TD Target=1+0.9×0=1,\text{TD Target}=-1+0.9\times0=-1,

δ=13=4,\delta=-1-3=-4,

于是把 V(s)V(s) 往下调一点:

V(s)3+0.1×(4)=2.6.V(s)\leftarrow 3+0.1\times(-4)=2.6.

把两种情况放在一起看:

这一次真实发生的事TD TargetTD 误差 $\delta$更新后 $V(s)$
到了 s1s_1,奖励 $+1$$5.5$$2.5$$3.25$
到了 s2s_2,奖励 $-1$$-1$$-4$$2.6$

这里有一个很重要的细节:TD 不保证每一次更新都更接近平均目标

在这个例子里,精确 Bellman target 是 3.553.55,而当前 V(s)=3V(s)=3,两者差 0.550.55。如果这一次到了 s1s_1,更新后变成 3.253.25,确实更接近 3.553.55;但如果这一次到了 s2s_2,更新后变成 2.62.6,反而离 3.553.55 更远了。

这不是矛盾,而是 TD 的正常现象。TD 每次只根据眼前这一条经历修正价值表,所以一次“坏结果”会把估计往下拉,一次“好结果”会把估计往上推。单次更新可能走偏,关键看很多次之后的平均方向。

把两种更新按环境本来的概率合在一起看:

0.7×3.25+0.3×2.6=3.055.0.7\times3.25+0.3\times2.6=3.055.

也就是说,如果从 V(s)=3V(s)=3 开始,下一次 TD 更新后的“平均位置”是 3.0553.055。它仍然没有直接跳到 3.553.55,但已经比 33 更靠近 3.553.55 了。

同样地,也可以从 TD 误差看:

0.7×2.5+0.3×(4)=0.55.0.7\times2.5+0.3\times(-4)=0.55.

平均 TD 误差是正的,说明从长期看,当前的 V(s)=3V(s)=3 偏低,应该往上调。只是每一次真实经历不一定都朝这个方向走。

这张表要表达的不是“智能体要按 70% 和 30% 去抽样”,而是:TD 每次只看真实发生的一条经历。常发生的结果会更频繁地参与更新,少发生的结果会更少参与更新。很多次更新累积起来,平均方向才会逐渐接近前面那个按概率加权的 Bellman 目标。

这里的 δ\delta 就是时序差分误差(Temporal Difference Error,简称 TD Error)。它衡量的是“一步目标”和“当前估计”之间差了多少:

δ=r+γV(s)Bellman targetV(s)当前估计\delta = \underbrace{r + \gamma V(s')}_{\text{Bellman target}} - \underbrace{V(s)}_{\text{当前估计}}

为什么叫“时序差分”?因为它比较的是时间序列上相邻两个状态之间的预测差异:站在 ss 时有一个旧预测,走到 ss' 后又用 r+γV(s)r+\gamma V(s') 给出一个新目标。

它的含义非常直接:

TD Error说明应该怎么调
$\delta>0$target 比当前估计高,说明低估了上调 $V(s)$
$\delta<0$target 比当前估计低,说明高估了下调 $V(s)$
$\delta=0$这次样本下 target 和估计一致基本不用调

最简单的更新公式就是:

V(s)V(s)+αδ.V(s)\leftarrow V(s)+\alpha\delta.

上面两个分支里的 3.253.252.62.6,就是用这个公式在 α=0.1\alpha=0.1 时算出来的结果。

这就是 TD 学习的基本动作:每走一步,就用“现实走出来的一步 + 下一状态估计”修正当前状态估计。多次采样之后,单次样本的噪声会被平均掉,价值表就会逐步靠近真正的 VπV^\pi

DP、MC、TD 三种方法分别处理不同的环境条件和信息假设,下一节 经典方法速览:DP、MC 与 TD 会专门对比。

本节总结

这一页公式很多,但主线只有一条:

  1. Vπ(s)V^\pi(s) 是从状态 ss 出发,按策略 π\pi 行动的平均长期回报。
  2. 回报可以递推:Gt=rt+γGt+1G_t=r_t+\gamma G_{t+1}
  3. 所以价值也可以递推:当前价值等于眼前奖励加下一状态价值。
  4. 如果策略固定,就得到贝尔曼期望方程。
  5. 如果每步都选最好的动作,就得到贝尔曼最优方程。
  6. 在有限状态问题里,可以把 V(s)V(s) 存成价值表,让每个状态都有一个可更新的数字。
  7. 如果我们只有采样数据,就用 Bellman target 和 TD Error 来一点点修正价值表中的 V(s)V(s)

V(s)V(s) 已经能告诉你“这个局面好不好”,但到这里还有两个缺口。

第一个缺口是:如果不知道环境模型,怎么估计 VV 贝尔曼期望方程里有 P(ss,a)P(s'\mid s,a)R(s,a)R(s,a),但真实任务里我们往往只拿得到一条条采样轨迹。下一节会讲 DP、MC、TD,它们就是三种从模型或数据中估计价值的方法。

第二个缺口是:VV 不直接告诉你该选哪个动作。 如果 V(s)=80V(s)=80,你只知道当前局面不错,却不知道该向左、向右,还是保持不动。更直接的办法是给每个动作也打分:

Q(s,a)Q(s,a)

先不用急着展开 QQ。这里只要记住两张表的分工:价值表 V(s)V(s) 给状态打分,动作价值表 Q(s,a)Q(s,a) 给“在状态 ss 下先做动作 aa”打分。若环境模型已知,也就是知道每个动作会怎样影响下一状态和奖励,我们可以用 VV 表做一步前瞻来比较动作;若环境模型未知,直接学习 QQ 表通常更方便,因为它把每个动作的长期后果直接存了下来。

所以接下来的顺序是:先看 DP、MC 与 TD,解决“怎么估计 VV”;再进入动作价值函数,解决“怎么用价值选动作”。

参考文献


  1. Sutton, R. S., & Barto, A. G. (2018). Reinforcement Learning: An Introduction (2nd ed.). MIT Press. 该书 Part I 题为 “Tabular Solution Methods”,第 4 章 Figure 4.1 展示了把状态价值直接写在 Gridworld 格子中的策略评估过程。MIT Press Open Access 页面:https://mitpress.mit.edu/9780262039246/reinforcement-learning/;作者官网 PDF:http://incompleteideas.net/book/RLbook2020.pdf↩︎

  2. Sutton, R. S. (1988). Learning to predict by the methods of temporal differences. Machine Learning, 3(1), 9-44. DOI: https://doi.org/10.1007/BF00115009. ↩︎

  3. Watkins, C. J. C. H., & Dayan, P. (1992). Q-learning. Machine Learning, 8, 279-292. DOI: https://doi.org/10.1007/BF00992698;作者页面:https://www.gatsby.ucl.ac.uk/~dayan/papers/wd92.html. ↩︎

现代强化学习实战课程