RL 学习笔记 #3 值迭代和策略迭代
本文最后更新于:2024年12月5日 下午
在上一节中,我们介绍了贝尔曼最优公式,这里将介绍求解 BOE 的首个 model-based 的算法:值迭代(Value Iteration)和策略迭代(Policy Iteration)。此外,我们还将讨论它们的变种之一:截断策略迭代(Truncated Policy Iteration)。
值迭代 | Value Iteration
上一节中,我们将贝尔曼最优公式整理为递归形式: \[ v_*(s) = \max_a \left[ \sum_r p(r \mid s, a) r + \gamma \sum_{s'} p(s' \mid s, a) v_*(s') \right] \] 值迭代(Value Iteration)直接利用递归性,通过不断迭代逼近最优状态值函数 \(v_*(s)\)。整个算法可以概括为: \[ v^{(k+1)}=f\left(v^{(k)}\right)=\max _\pi\left(r_\pi+\gamma P_\pi v^{(k)}\right), \quad k=1,2,3 \ldots \] 因此这个算法理论上需要包含两个主要步骤:
- 策略更新(PU):\(\pi^{(k+1)} = \arg\max _\pi\left(r_\pi+\gamma P_\pi v^{(k)}\right)\)
- 状态更新(VU):\(v^{(k+1)}=r_{\pi^{(k+1)}}+\gamma P_{\pi^{(k+1)}} v^{(k)}\)
而策略 \(\pi\) 更新的时候由于使用了贪心选择,这两个步骤可以合并简化,直接使用最优的动作价值去更新状态价值: \[ v^{(k+1)}(s) = \max_a q^{(k+1)}(s,a) \]
值得一提的是,贪心更新策略 \(\pi\) 也带来了一个有趣的现象:越靠近目标区域的状态越先变好。直观上就是因为 \(\pi\) 依赖于其他状态,而当其他状态都不好的时候无从更新,只有接近目标区域的状态有明确的优化方向。
具体步骤
初始化值函数:设定初始值 \(v^{(0)}(s)\),通常初始化为全零或任意常数。
迭代更新值函数: 对于每个状态 \(s\),根据贝尔曼最优公式更新 \(v(s)\): \[ v^{(k+1)}(s) = \max_a \left[ \sum_r p(r \mid s, a) r + \gamma \sum_{s'} p(s' \mid s, a) v^{(k)}(s') \right] \]
判断收敛: 检查值函数更新是否足够小(例如 \(\lVert v^{(k+1)} - v^{(k)} \rVert_\infty < \epsilon\)),若收敛则停止迭代并输出 \(v^{(k+1)}\)。
推导策略: 一旦得到收敛的值函数 \(v_*(s)\),通过以下方式获得对应的最优策略 \(\pi^*\): \[ \pi^*(s) = \arg\max_a \left[ \sum_r p(r \mid s, a) r + \gamma \sum_{s'} p(s' \mid s, a) v_*(s') \right] \]
伪代码实现
1 |
|
策略迭代 | Policy Iteration
策略迭代是另一种求解 BOE 的方法,核心思想是交替优化策略和状态值函数,直到收敛到最优策略 \(\pi^*\)。
与值迭代不同的是,策略迭代先初始化一个随机策略,再交替进行以下两个主要步骤:
- 策略评估(PE):\(v_{\pi^{(k)}}=r_{\pi^{(k)}}+\gamma P_{\pi^{(k)}} v_{\pi^{(k)}}\)
- 策略改进(PI):\(\pi^{(k+1)} = \arg\max _\pi\left(r_\pi+\gamma P_\pi v_{\pi^{(k)}}\right)\)
这里有四个问题需要回答:
- 在 PE 步骤如何求解状态值?
- 在上一节有介绍,已知策略时可以通过矩阵形式直接求解精确解,也可以利用 Bootstrap 迭代法。
- 注意:如果采用 Bootstrap 迭代法,实际上我们是在整个大的策略迭代中又嵌套了一个小的迭代!
- 在 PI 步骤如何确保新策略好于旧策略?
- 可以证明:对于任何 \(k\),有 \(v_{\pi^{(k+1)}} \ge v_{\pi^{(k)}}\)。证明过程略。
- 这个算法为什么能到达最优策略?
- 可以证明收敛性:\(\{v_{\pi^{(k)}}\}^{\infty}_k \to v^*\)。证明过程略。
- 策略迭代和值迭代有什么关系?
- 策略迭代的收敛性证明是基于值迭代的收敛性。
- 这两种算法是截断策略迭代(Truncated Policy Iteration)的两个极端表现。
具体步骤
初始化策略: 随机初始化一个初始策略 \(\pi^{(0)}\)。
策略评估: 在当前策略 \(\pi^{(k)}\) 下,通过求解以下线性方程组来获得状态值函数 \(v_{\pi^{(k)}}(s)\): \[ v_{\pi^{(k)}}(s) = \sum_a \pi^{(k)}(a \mid s) \left[ \sum_r p(r \mid s, a) r + \gamma \sum_{s'} p(s' \mid s, a) v_{\pi^{(k)}}(s') \right] \]
当状态空间较小时,可以直接解线性方程组;
对于较大的问题,可以使用 Bootstrap 迭代逼近的方法。
策略改进: 基于更新后的值函数 \(v_{\pi^{(k)}}\),贪心更新策略: \[ \pi^{(k+1)}(s) = \arg\max_a \left[ \sum_r p(r \mid s, a) r + \gamma \sum_{s'} p(s' \mid s, a) v_{\pi^{(k)}}(s') \right] \]
检查收敛: 如果策略不再变化,即 \(\pi^{(k+1)} = \pi^{(k)}\),则算法结束,\(\pi^{(k)}\) 即为最优策略;否则返回步骤 2。
伪代码实现
1 |
|
截断策略迭代 | Truncated Policy Iteration
截断策略迭代(Truncated Policy Iteration)是值迭代和策略迭代的一般化推广,旨在权衡收敛速度与计算效率。如果将两个算法对齐:
Steps | Policy Iteration | Value Iteration | Comments |
---|---|---|---|
(1) Policy | \(\pi^{(0)}\) | N/A | |
(2) Value | \(v_{\pi^{(0)}}=r_{\pi^{(0)}}+\gamma P_{\pi^{(0)}} v_{\pi^{(0)}}\) | \(\textcolor{red}{v^{(0)}:=v_{\pi^{(0)}}}\) | 人为赋予 VI 的相同初始值,便于比较 |
(3) Policy | \(\pi^{(1)} = \arg\max _\pi\left(r_\pi+\gamma P_\pi v_{\pi^{(0)}}\right)\) | \(\pi^{(1)} = \arg\max _\pi\left(r_\pi+\gamma P_\pi v^{(0)}\right)\) | 这一步的操作和结果一模一样 |
(4) Value | \(\textcolor{blue}{v_{\pi^{(1)}}=r_{\pi^{(1)}}+\gamma P_{\pi^{(1)}} v_{\pi^{(1)}}}\) | \(\textcolor{blue}{v^{(1)}=r_{\pi^{(1)}}+\gamma P_{\pi^{(1)}} v^{(0)}}\) | 由 \(v_{\pi^{(1)}}\ge v^{(0)}\) 得 \(v_{\pi^{(1)}}\ge v^{(1)}\) |
(5) Policy | \(\pi^{(2)} = \arg\max _\pi\left(r_\pi+\gamma P_\pi v_{\pi^{(1)}}\right)\) | \(\pi^{(2)} = \arg\max _\pi\left(r_\pi+\gamma P_\pi v^{(1)}\right)\) | 接下来差距越变越大 |
... | ... | ... | ... |
可以看到,关键的分歧在于 (4) Value 步骤时,策略迭代采用的是一个内嵌迭代去多次更新了状态值,而值迭代只采用一次更新得到了新状态值。
那么,在这二者之间,是否存在一个中间结果?截断策略迭代应运而生,其主要特点是对策略评估(PE)过程进行截断。减少了内嵌迭代的计算开销,相较于策略迭代更高效。
关于截断策略迭代的收敛性证明,直观上可以用 VI 和 PI 两条曲线的夹逼来解释。具体证明过程略去。
具体步骤
初始化策略: 随机初始化一个策略 \(\pi^{(0)}\)。
截断的策略评估: 在当前策略 \(\pi^{(k)}\) 下,迭代更新值函数 \(v^{(k)}(s)\),但仅进行有限次迭代(如 \(n\) 次),而非完全收敛。
策略改进: 基于截断后的值函数 \(v^{(k)}(s)\),更新策略: \[ \pi^{(k+1)}(s) = \arg\max_a \left[ \sum_r p(r \mid s, a) r + \gamma \sum_{s'} p(s' \mid s, a) v^{(k)}(s') \right] \]
判断收敛: 如果策略 \(\pi^{(k+1)} = \pi^{(k)}\),则停止;否则返回步骤 2。
伪代码实现
1 |
|
算法比较
算法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
值迭代 | 通过单个过程即可直接逼近最优值函数,简单、直接,适用于小规模问题 | 收敛速度较慢,尤其是当状态空间较大或 \(\gamma\) 接近 1 时,每次迭代的更新量可能变得很小 | 状态空间较小、对精度要求较高 |
策略迭代 | 收敛速度快,通常只需几轮策略更新即可收敛 | 每轮策略评估计算量大,尤其是在状态空间很大时,可能成为瓶颈 | 中小规模问题、对速度要求较高 |
截断策略迭代 | 权衡了值迭代和策略迭代的优缺点,减少了策略评估的计算开销,相较于策略迭代更高效 | 收敛速度可能略低于完整的策略迭代 | 大规模问题、需要减少计算开销 |
以上三种算法是强化学习中的经典方法,为后续的 Model-Free 算法奠定了重要的基础。