强化学习系统性学习笔记(一):从理论基础到策略优化

强化学习系统性学习笔记(一):从理论基础到策略优化

一、强化学习的起源与核心问题

1.1 理论溯源:从生物学习到数学框架

强化学习的思想源头可以追溯到生物行为心理学中的"试错学习"原理。在自然界中,生物个体通过反复尝试不同行为并观察环境反馈,逐步学会选择能够带来更好结果的行动策略。这一朴素而普适的学习模式,为人工智能领域提供了重要启发。

在将这一思想转化为可计算框架的过程中,20世纪中叶至后期的多个数学分支做出了关键贡献。控制论研究了系统的反馈与调节机制,最优控制理论探讨了如何在动态系统中寻找最优决策序列,而Bellman方程和动态规划则为顺序决策问题提供了解析求解的数学工具。这些理论的共同特点是假设环境模型已知,即系统的状态转移规律和奖励函数都是确定的。

强化学习在此基础上迈出了更具挑战性的一步。当环境模型未知或难以精确建模时,智能体必须仅通过与环境的实际交互来学习最优策略。这种"边交互边学习"的范式,使得强化学习既继承了经典控制理论的数学严谨性,又具备了应对复杂未知环境的实用价值。在形式化表述中,我们通常采用马尔可夫决策过程作为数学抽象,将学习问题定义为:智能体在一系列状态中选择动作,观察环境反馈的奖励和新状态,目标是找到能够最大化长期累积奖励的策略。

1.2 核心目标的三个维度

理解强化学习要解决的核心问题,需要从以下三个相互关联的维度展开分析。

  • 首先是期望回报最大化 这一根本目标。我们用参数化策略\(\pi_\theta\)来描述智能体的决策规则,该策略在环境中产生轨迹\(\tau = (s_0, a_0, s_1, a_1, \dots)\),每条轨迹对应累积奖励\(R(\tau)\)。强化学习的数学目标可以明确表述为最大化期望回报\(J(\pi) = \mathbb{E}_{\tau \sim \pi}[R(\tau)]\)。这一目标函数看似简洁,但其优化过程充满挑战,因为期望值涉及所有可能轨迹的概率加权,而轨迹空间往往是高维甚至无限的。

  • 其次是在未知环境中的探索与利用权衡。与监督学习根本不同的是,强化学习没有"正确答案"的标注数据。智能体必须主动尝试各种动作,通过观察结果来判断动作的优劣。这带来了一个深刻的两难困境:过度探索会浪费时间在次优动作上,损失当前回报;而过早固定在某个看似不错的策略上,又可能错过更优的选择。如何在探索新可能性和利用已知信息之间取得动态平衡,是强化学习算法设计的核心考量之一。

  • 第三个维度关注样本效率与训练稳定性。在许多实际应用场景中,与环境交互的成本是昂贵的。无论是机器人的物理试错、游戏中的计算模拟,还是推荐系统的在线实验,每一次交互都意味着时间、计算或用户体验的代价。因此,算法必须能够在有限的交互次数内学到有效策略。与此同时,策略更新过程还必须保持稳定性,避免因参数更新过大或方差过高而导致性能剧烈波动甚至崩溃。这要求算法设计在收敛速度和稳定性之间找到精妙的平衡点。

1.3 发展脉络的四个阶段

为了系统理解强化学习的技术演进,我们可以沿着"基础理论→深度值函数→策略优化→大模型应用"这条逻辑主线,将其发展历程划分为四个关键阶段。

基础理论阶段奠定了强化学习的数学根基。早期研究主要针对状态空间较小的离散问题,采用表格方法存储和更新价值函数。经典算法如Q-learning、SARSA和蒙特卡洛方法在这一时期成熟,它们的收敛性分析为后续发展提供了理论保障。时序差分学习的提出更是将蒙特卡洛采样与动态规划的优点结合起来,成为现代强化学习的核心技术之一。这些方法的共同局限在于无法处理大规模或连续的状态空间。

2013年DeepMind提出的DQN标志着深度强化学习时代的到来。通过引入深度神经网络来近似动作价值函数,DQN首次使强化学习能够直接从高维感知输入中学习策略。经验回放机制和目标网络的使用,有效缓解了函数近似带来的训练不稳定问题。此后研究者们在DQN基础上持续改进,相继提出了Double DQN解决过估计问题、Dueling DQN分离状态价值与动作优势、优先经验回放提升样本效率,以及集大成的Rainbow算法。然而,基于价值函数的方法在处理连续动作空间和保证训练稳定性方面仍面临固有挑战,特别是函数近似、自举更新和非平稳数据分布这"致命三要素"的组合容易导致学习发散。

为克服值函数方法的局限,研究社区转向直接策略优化的路径。策略梯度方法通过参数化策略本身并对期望回报直接求导,天然适用于连续动作空间和随机策略。从最基础的REINFORCE算法开始,结合价值函数作为基线的Actor-Critic架构逐步成型。为解决策略梯度的高方差和训练不稳定问题,TRPO引入信赖域约束确保更新幅度可控,PPO则通过截断目标简化实现同时保持性能。在连续控制领域,DDPG、TD3和SAC等方法将策略优化与值函数估计深度结合,在样本效率和稳定性之间取得了更好的平衡。这些算法的共同特点是更加注重更新过程的稳定性控制和方差降低技术。

近年来,强化学习在大型语言模型对齐领域找到了新的应用方向,形成了以RLHF为代表的技术范式。在ChatGPT等模型的训练中,策略优化方法被用于根据人类偏好反馈微调模型行为,使其输出更符合人类价值观和使用期望。这一阶段面临的挑战包括超高维离散动作空间、长序列中的稀疏奖励、以及如何避免模型学会"欺骗"奖励模型等安全性问题。DPO等离线优化方法的提出,试图绕过显式奖励建模的复杂性,直接从偏好数据中学习策略,展现了策略优化理论在新场景下的适应性演化。

通过这样的阶段划分,我们不仅能够理清技术发展的时间线,更重要的是理解每个阶段如何针对前一阶段的核心问题提出解决方案,以及这些方案又引入了哪些新的挑战。这种演进逻辑为我们后续深入探讨策略梯度方法提供了必要的背景知识。

二、强化学习方法的分类体系

2.1 基于模型依赖性的根本划分

理解强化学习算法的多样性,首先需要把握一条最基本的分类线索:算法是否依赖环境模型。这一区分不仅是理论分类的需要,更深刻反映了不同方法在样本效率与模型偏差之间的根本权衡。

  • 有模型强化学习 的核心思想是显式学习或利用环境的动态特性。具体而言,智能体试图建立状态转移函数\(P(s'|s,a)\)和奖励函数\(r(s,a)\)的近似模型,然后在这个内部模型中进行规划和模拟。这种方法的优势在于样本效率:一条真实环境轨迹可以在模型内部生成多条虚拟轨迹用于训练,显著减少了与真实环境的交互次数。此外,拥有模型使得智能体能够"提前思考",在实际执行前评估不同行动序列的潜在后果。

  • 无模型强化学习则采取完全不同的策略。它不尝试理解环境的内在机制,而是直接从交互经验中学习策略或价值函数。这种方法的主要优势在于实现的直接性和对复杂环境的鲁棒性。当环境动态极其复杂或高维时,准确建模可能比直接学习策略更加困难。无模型方法避免了模型偏差带来的风险,即使环境规律难以捕捉,只要有足够的交互数据,算法也能逐步改进策略。

两类方法的对比可以从多个维度展开。在样本效率方面,有模型方法通常占优,因为模型允许在虚拟环境中进行大量"免费"的模拟实验。但这一优势的前提是模型足够准确,否则模型偏差会在规划过程中被放大,导致策略在真实环境中表现不佳。在适用场景上,有模型方法更适合那些环境动态相对规则、可以被有效近似的任务,以及采样成本极高的场景;而无模型方法则在环境复杂多变、模型难以学习但可以频繁交互的情况下更具优势。在实现复杂度上,有模型方法需要同时维护模型学习、规划优化和策略执行多个模块,技术挑战更大;无模型方法的算法流程相对更为直接。

值得注意的是,这一分类并非绝对对立。近年来许多先进算法采取混合策略,例如用学习到的模型辅助无模型方法的训练,或者在无模型框架中引入局部模型进行短期规划,试图综合两类方法的优势。

2.2 有模型方法的原理与实践

深入理解有模型强化学习,需要把握其"模型学习---规划---执行---反馈"的完整闭环。

模型获取 阶段,根据环境信息的可得性有不同路径。在某些场景下,环境模型是已知或可以通过物理定律精确描述的,例如经典控制问题中的线性系统。此时可以直接应用动态规划、线性二次调节等方法求解最优策略。更常见的情况是环境模型未知,需要智能体从交互数据中学习。模型可以采用参数化神经网络、高斯过程、或者基于记忆的非参数方法。模型学习本身是一个监督学习问题:给定历史经验\(\{(s_t, a_t, s_{t+1}, r_t)\}\),训练模型预测下一状态和奖励。

规划与模拟是有模型方法的核心环节。拥有模型后,智能体可以在不与真实环境交互的情况下,通过前向模拟评估候选策略的表现。规划方法可以是基于搜索的树展开,如蒙特卡洛树搜索;也可以是基于优化的轨迹规划,如模型预测控制;或者是生成虚拟经验补充训练数据,如Dyna架构和MBPO算法。这些虚拟经验使得相同数量的真实交互能够产生更多的学习信号。

然而,模型方法面临的根本挑战在于模型偏差的积累。即使模型在单步预测上误差较小,在长期规划中误差会被逐步放大。策略可能过度拟合模型的虚假特性,在真实环境中表现糟糕。应对这一问题的策略包括:使用模型集成来量化不确定性并在规划时保守行动;限制模型的使用范围,只在短期规划或数据密集区域使用;定期用真实数据更新模型,及时修正偏差;或者将模型用于辅助无模型方法,而非完全依赖模型。

代表性算法如MuZero在棋类游戏中取得了突破,它学习隐状态表示而非完整的环境动态,并结合树搜索进行规划。MBPO通过在模型内部生成短期轨迹来增强无模型算法的数据效率,同时通过限制模拟长度来控制模型误差的影响。这些进展展示了有模型方法在特定领域的巨大潜力,同时也凸显了模型质量控制的重要性。

2.3 无模型方法的两条主线

无模型强化学习虽然不依赖环境模型,但内部仍有清晰的技术分支,主要体现为值函数方法策略优化方法两条并行发展的主线。

2.3.1 值函数方法

值函数方法的核心逻辑 是通过估计每个状态或状态-动作对的价值,间接获得策略。动作价值函数\(Q(s,a)\)告诉我们在状态\(s\)采取动作\(a\)后能够获得的期望回报。一旦获得准确的\(Q\)函数,策略可以简单地通过贪心选择来确定:\(\pi(s) = \arg\max_a Q(s,a)\)。值函数的学习通常基于Bellman方程,利用时序差分误差进行增量更新。

深度强化学习时代,DQN及其变体将值函数方法推向了新高度。DQN使用深度神经网络近似\(Q\)函数,使其能够处理高维状态输入如图像。经验回放打破了数据的时序相关性,目标网络的引入稳定了训练过程。后续改进如Double DQN缓解了价值高估问题,Dueling架构分离了状态价值与动作优势的学习,优先经验回放根据TD误差加权采样,Rainbow算法则集成了多种改进技术。

值函数方法的优势在于可以充分利用离线数据,对样本的复用效率高。但它也面临固有挑战:在函数近似条件下,值函数更新可能不稳定甚至发散;对于连续或高维动作空间,求解\(\arg\max\)操作本身就是一个困难的优化问题;此外,值函数方法通常学习确定性策略,在需要随机探索或随机最优策略的场景下不够灵活。

2.3.2 策略优化方法

策略优化方法采取了更直接的路径 ,即对策略本身进行参数化并直接优化期望回报。策略\(\pi_\theta(a|s)\)用神经网络表示,参数\(\theta\)通过梯度上升调整以最大化目标函数\(J(\pi_\theta)\)。这一方法天然适用于连续动作空间和随机策略,因为网络输出可以是动作分布的参数。

策略梯度方法的理论基础是策略梯度定理,它给出了期望回报对策略参数的梯度表达式。最基础的REINFORCE算法直接实现这一梯度,但存在高方差问题。为降低方差,研究者引入了价值函数作为基线,形成Actor-Critic架构:Actor网络代表策略,Critic网络估计价值函数用于评估Actor的表现并提供低方差的优势估计。

现代策略优化算法进一步强化了训练稳定性。TRPO通过信赖域约束确保策略更新不会过大,但实现复杂度高。PPO简化了这一思想,使用截断目标函数限制策略变化幅度,在保持性能的同时大幅简化了实现。对于连续控制任务,DDPG、TD3和SAC等方法将确定性或随机性策略与值函数深度结合,并通过各种技巧提升稳定性,如目标网络延迟更新、噪声注入和熵正则化等。

策略优化方法的优势在于更新过程相对稳定,能够自然处理连续和高维动作空间,且可以学习随机策略。挑战在于样本效率通常低于值方法,因为策略梯度需要on-policy或近on-policy的数据,难以充分利用历史经验。此外,梯度估计的方差仍然是影响收敛速度的关键因素。

在实践中,这两条主线并非完全独立。许多先进算法是混合架构,同时维护策略网络和值网络,试图综合两者优势。这种趋势反映了强化学习研究从追求单一最优方法转向针对具体问题灵活组合技术的务实态度。

2.4 技术图景的整体把握

至此,我们完成了对强化学习方法分类体系的系统梳理。从最顶层的有模型与无模型划分,到无模型内部的值函数与策略优化两条主线,这个分类框架让我们更清晰理解丰富算法生态。

理解这一体系的价值不仅在于知道算法的类别归属,更在于把握不同方法背后的设计哲学和适用场景。

  • 有模型方法追求样本效率,代价是模型偏差风险;
  • 无模型方法规避建模困难,但需要更多交互数据。
    • 值函数方法通过价值估计间接优化策略,适合离线学习;
    • 策略优化直接作用于决策函数,更加稳定灵活。

在接下来的部分,我们将聚焦于策略优化这一重要分支,深入探讨其理论基础、核心算法和实现细节。这一选择基于策略优化方法在现代深度强化学习特别是大模型对齐任务中的广泛应用和持续发展。从最基础的策略梯度定理出发,我们将系统推导REINFORCE算法,理解优势函数的引入动机,并最终掌握TRPO、PPO等先进算法的设计原理。

三、策略优化的理论基础与算法实现

3.1 从期望回报到可计算梯度的推导路径

3.1.1 目标:最大化期望回报

策略优化方法的数学起点是明确定义优化目标。对于参数化策略\(\pi_\theta(a|s)\),我们将其在环境中产生的轨迹记为\(\tau = (s_0, a_0, s_1, a_1, \dots, s_T, a_T)\),轨迹的累积回报为\(R(\tau) = \sum_{t=0}^T r(s_t, a_t, s_{t+1})\)。策略的性能由期望回报衡量:\(J(\pi_\theta) = \mathbb{E}{\tau \sim \pi\theta}[R(\tau)]\)。我们的目标是找到最优参数\(\theta^* = \arg\max_\theta J(\pi_\theta)\),而梯度上升提供了一条自然的优化路径:\(\theta \leftarrow \theta + \alpha \nabla_\theta J(\pi_\theta)\)。

然而,这个看似简洁的目标函数背后隐藏着深刻的计算挑战。期望\(J(\pi_\theta)\)涉及对所有可能轨迹的积分,而轨迹空间通常是高维甚至连续无限的。我们既无法枚举所有轨迹,也无法解析地计算这个期望值。因此,策略优化的理论核心任务是将\(\nabla_\theta J(\pi_\theta)\)转化为一个可以通过有限采样近似的表达式。

这一转化过程需要分两步完成。

  • 第一步是理论推导:我们需要找到梯度的解析形式,将其表达为某个期望的形式\(\nabla_\theta J(\pi_\theta) = \mathbb{E}{\tau \sim \pi\theta}[f(\tau, \theta)]\),其中\(f\)是可以从单条轨迹数据中计算的函数。这一步确保了梯度在数学上是可表达的。
  • 第二步是样本估计:在实际训练中,我们通过与环境交互收集有限条轨迹\(\{\tau_1, \dots, \tau_N\}\),然后用经验平均近似期望:\(\nabla_\theta J(\pi_\theta) \approx \frac{1}{N}\sum_{i=1}^N f(\tau_i, \theta)\)。只有完成这两步,我们才能将理论上的梯度转化为实践中可执行的参数更新。

3.1.2 对数导数技巧(log-derivative trick / score function)

推导的关键数学工具是对数导数技巧 ,也称为score function方法。对于任意依赖参数\(\theta\)的概率分布\(p_\theta(x)\),其导数可以写成:\(\nabla_\theta p_\theta(x) = p_\theta(x) \nabla_\theta \log p_\theta(x)\)。这一恒等式看似平凡,却是将梯度从概率本身转移到对数概率的桥梁。应用这一技巧到轨迹分布上,我们可以将对\(P(\tau|\theta)\)的导数转换为对\(\log P(\tau|\theta)\)的导数,后者的计算要简单得多。

具体而言,轨迹在策略下的概率可以分解为:\(P(\tau|\theta) = \rho_0(s_0) \prod_{t=0}^T P(s_{t+1}|s_t, a_t) \pi_\theta(a_t|s_t)\),其中\(\rho_0(s_0)\)是初始状态分布,\(P(s_{t+1}|s_t, a_t)\)是环境转移概率。

取对数后得到:\(\log P(\tau|\theta) = \log \rho_0(s_0) + \sum_{t=0}^T [\log P(s_{t+1}|s_t, a_t) + \log \pi_\theta(a_t|s_t)]\)。注意到这个表达式中,只有策略项\(\log \pi_\theta(a_t|s_t)\)依赖于参数\(\theta\),初始分布和环境转移都与\(\theta\)无关。

因此对\(\log P(\tau|\theta)\)求导时,那些与环境相关的项全部消失,只剩下:\(\nabla_\theta \log P(\tau|\theta) = \sum_{t=0}^T \nabla_\theta \log \pi_\theta(a_t|s_t)\)。

这一结果意义重大:梯度的计算完全不需要知道环境动态模型,只需要知道策略本身和轨迹数据。

将这一结果代入期望回报的梯度表达式,结合对数导数技巧,我们得到策略梯度定理的基础形式 :\(\nabla_\theta J(\pi_\theta) = \mathbb{E}{\tau \sim \pi\theta}\left[\sum_{t=0}^T \nabla_\theta \log \pi_\theta(a_t|s_t) \cdot R(\tau)\right]\)。

3.1.3 因果性改进

这个公式给出了第一版可用的策略梯度,但它存在一个直觉上的不合理之处:在时间步\(t\)的动作\(a_t\)与整条轨迹的总回报\(R(\tau)\)相乘,其中包括了\(t\)时刻之前获得的奖励。然而根据因果性原则,当前动作只能影响未来的结果,不应该对过去的奖励负责。这种不必要的关联会引入额外的方差。

为修正这一问题,我们引入reward-to-go 的概念。对于时间步\(t\),定义从该时刻起的累积回报\(G_t = \sum_{t'=t}^T r(s_{t'}, a_{t'}, s_{t'+1})\)。可以证明,将公式中的\(R(\tau)\)替换为\(G_t\)不改变梯度的期望值(因为被移除的项期望为零),但显著降低了梯度估计的方差。修正后的梯度公式变为:\(\nabla_\theta J(\pi_\theta) = \mathbb{E}{\tau \sim \pi\theta}\left[\sum_{t=0}^T \nabla_\theta \log \pi_\theta(a_t|s_t) \cdot G_t\right]\)。这个版本在理论和实践中都更为合理。

3.1.4 引入基线/优势函数(Baseline / Advantage)

进一步降低方差的方法是引入基线函数 。关键观察是:对于任何仅依赖状态\(s_t\)而不依赖动作\(a_t\)的函数\(b(s_t)\),都有\(\mathbb{E}{a_t \sim \pi}\left[\nabla\theta \log \pi_\theta(a_t|s_t) \cdot b(s_t)\right] = 0\)。这意味着我们可以从\(G_t\)中减去\(b(s_t)\)而不改变梯度的期望,从而得到:\(\nabla_\theta J(\pi_\theta) = \mathbb{E}{\tau \sim \pi\theta}\left[\sum_{t=0}^T \nabla_\theta \log \pi_\theta(a_t|s_t) \cdot (G_t - b(s_t))\right]\)。基线的引入纯粹是为了方差降低,它不改变梯度的期望方向,但能显著减小估计的随机波动。

最有效的基线选择是状态价值函数 \(V^\pi(s_t)\),它表示在状态\(s_t\)遵循策略\(\pi\)能获得的期望回报。当\(b(s_t) = V^\pi(s_t)\)时,乘子\(G_t - V^\pi(s_t)\)被称为优势函数 \(A^\pi(s_t, a_t)\),它度量了动作\(a_t\)相对于该状态下平均表现的优劣程度。优势函数的引入是策略梯度方法中最重要的技术之一,几乎所有现代算法都采用某种形式的优势估计。最终,我们得到策略梯度的标准形式:\(\nabla_\theta J(\pi_\theta) = \mathbb{E}{\tau \sim \pi\theta}\left[\sum_{t=0}^T \nabla_\theta \log \pi_\theta(a_t|s_t) \cdot A_t\right]\),其中\(A_t = G_t - V^\pi(s_t)\)。

至此,我们完成了从期望回报到可计算梯度的完整推导。这一推导链条不仅给出了算法的数学基础,更揭示了策略优化的核心思想:通过对数概率梯度捕捉参数对策略的影响,通过优势函数评估动作的好坏,两者结合产生指向性能提升的参数更新方向。

3.2 REINFORCE算法的实现与局限

基于前述推导,最直接的策略优化算法是REINFORCE,由Williams在1992年提出。它的算法流程体现了策略梯度理论的最简实现。

训练循环的每一轮迭代包含以下步骤:首先,使用当前策略\(\pi_\theta\)在环境中采样若干条完整轨迹。对于每条轨迹中的每个时间步,计算从该步开始的累积回报\(G_t\)。然后构造梯度估计:\(\hat{g} = \frac{1}{N}\sum_{i=1}^N \sum_{t=0}^{T_i} \nabla_\theta \log \pi_\theta(a_t^{(i)}|s_t^{(i)}) \cdot G_t^{(i)}\),其中\(N\)是轨迹数量。最后通过梯度上升更新参数:\(\theta \leftarrow \theta + \alpha \hat{g}\)。如果引入基线,则将\(G_t^{(i)}\)替换为\(G_t^{(i)} - b(s_t^{(i)})\)。

REINFORCE的优点在于推导严格、实现简单、理论上无偏。它不需要任何环境模型,只需要能够采样轨迹并计算对数概率梯度。对于简单任务,REINFORCE往往能够收敛到合理策略。然而,它也暴露了策略梯度方法的固有弱点:梯度估计的高方差。即使使用相同策略采样的不同轨迹,其回报可能差异巨大,导致梯度估计在不同batch之间剧烈波动。这种高方差直接影响学习效率:为了获得稳定的梯度信号,需要大量轨迹样本;而即便有足够样本,训练过程仍可能非常缓慢。

对于长时间跨度的任务,问题更加严重。累积回报\(G_t\)随着轨迹长度增加而方差膨胀,梯度估计的信噪比急剧下降。此外,REINFORCE是纯on-policy算法,每次参数更新后旧的轨迹数据就失效了,无法复用历史经验,导致样本效率低下。在高维或连续控制任务中,这些问题会使算法几乎无法收敛。

认识到这些局限性,研究者们发展出一系列改进技术,其中最重要的是引入价值网络形成Actor-Critic架构。

3.3 Actor-Critic架构的设计原理

Actor-Critic方法通过引入价值函数估计来解决REINFORCE的高方差问题,形成了现代策略优化算法的基础框架。

在这一架构中,系统维护两个独立的神经网络:Actor网络\(\pi_\theta(a|s)\)参数化策略,负责选择动作;Critic网络\(V_\phi(s)\)参数化状态价值函数,负责评估状态的好坏。两个网络的参数\(\theta\)和\(\phi\)独立训练,但在训练过程中相互协作。

Critic的训练目标是准确估计当前策略下的状态价值。给定一批经验数据,我们可以用实际观察到的累积回报\(G_t\)作为真实价值的样本,通过最小化均方误差来更新Critic:\(\mathcal{L}{\text{critic}}(\phi) = \mathbb{E}{s_t, G_t}\left[(V_\phi(s_t) - G_t)^2\right]\)。这是一个标准的监督学习问题:网络的输入是状态,目标是预测该状态的真实回报。

Actor的训练则利用Critic的价值估计来构造优势函数。对于状态\(s_t\)和动作\(a_t\),实际回报\(G_t\)与预测价值\(V_\phi(s_t)\)的差值\(A_t = G_t - V_\phi(s_t)\)就是优势的估计。这个优势告诉我们:相比该状态的平均表现,当前动作带来的回报是更好还是更差。Actor的目标函数构造为:\(\mathcal{L}{\text{actor}}(\theta) = -\mathbb{E}{\tau, t}\left[\log \pi_\theta(a_t|s_t) \cdot A_t\right]\)。注意这里的负号使得最小化这个loss等价于最大化期望回报。

在实际实现中,一个关键技术细节是在计算优势时需要将价值估计视为常数,即\(A_t = G_t - V_\phi(s_t).\text{detach}()\)。这个操作阻断了梯度从Actor回传到Critic的路径,确保两个网络的训练目标相对独立。如果不这样做,Actor的更新会干扰Critic的学习,因为优势的改变会同时来自策略本身的改进和价值估计的变化,造成训练不稳定。

通过这种分离,Critic专注于学习准确的价值预测,不受策略更新的直接影响;Actor则利用Critic提供的低方差优势信号调整策略,不需要关心价值估计的具体实现。这种职责分工使得两个网络可以以不同的学习率、不同的频率独立优化。

在实际训练时,通常会将两个loss合并为总loss:\(\mathcal{L} = \mathcal{L}{\text{actor}} + \beta \mathcal{L}{\text{critic}}\),其中\(\beta\)是平衡系数。一次反向传播可以同时更新两组参数。如果Actor和Critic共享部分网络层(如共享的特征提取器),合并loss还允许梯度在共享层叠加,实现更高效的特征学习。

Actor-Critic架构的核心价值在于将策略梯度的无偏性与价值函数的低方差估计结合起来。相比纯REINFORCE,它的梯度估计更稳定,收敛更快,样本效率更高。然而,它也引入了新的挑战:需要同时训练两个网络,增加了超参数调节的复杂度;如果Critic的估计不准确,会引入偏差影响策略学习;两个网络的训练速度如果不匹配,可能导致相互干扰。后续的算法改进很大程度上围绕着如何更好地平衡Actor和Critic的训练展开。

3.4 策略梯度中的loss函数本质辨析

对于初学者而言,Actor-Critic中的loss函数常常引起困惑:为什么我们定义的这个loss与监督学习中的loss看起来相似,却有着完全不同的含义?这一问题触及强化学习与监督学习的本质区别,值得深入剖析。

第一个关键差异在于数据分布的依赖性 。在监督学习中,训练样本来自固定的数据分布,与模型参数无关。无论模型如何更新,数据集保持不变。而在策略梯度中,轨迹数据由当前策略生成,策略参数\(\theta\)的改变会直接影响下一批数据的分布。当我们更新\(\theta\)后,之前采样的轨迹就不再能代表新策略的行为,其对应的loss值也失去了意义。这种"数据分布随参数移动"的特性是强化学习区别于监督学习的根本特征。

第二个差异体现在loss数值的解释性 上。在监督学习中,loss值直接度量模型的预测误差,其减小对应着泛化性能的提升。我们可以通过监控loss曲线来判断训练进展。但在策略梯度中,\(\mathcal{L}{\text{actor}} = -\log \pi\theta(a|s) \cdot A\)这个量本身并不衡量策略的好坏,它只是一个构造出来的"代理目标",用于产生正确方向的梯度。loss值的大小与真正关心的期望回报之间没有直接对应关系。我们可能看到loss在下降,但策略性能却在波动甚至下降。

第三个关键点是局部有效性与全局不一致性 。给定当前策略\(\pi_\theta\)和对应采样的轨迹,构造的loss函数的梯度方向确实指向期望回报的上升方向,这是策略梯度定理保证的。但这种保证只在无穷小的参数更新步长下成立。一旦我们进行有限步长的更新,策略发生实质性改变后,原先构造的loss就不再准确反映新策略的性能。这就是为什么策略优化需要小心控制更新幅度,因为过大的更新会使我们的优化目标失效。

这些差异在实践中产生重要影响。我们不能像监督学习那样无限制地最小化loss,因为那可能导致策略偏离采样数据分布太远,进入我们的优化目标不再有效的区域。我们也不能简单地用loss值的下降来判断训练是否成功,必须定期在环境中实际评估策略的回报。更重要的是,我们需要采用特殊的技术来确保更新的稳定性,如限制策略变化幅度、使用信赖域约束、或采用截断目标函数,这些正是TRPO和PPO等先进算法的核心创新。

理解策略梯度loss的这种"工具性"而非"目标性"特征,是掌握强化学习算法设计的关键一步。它解释了为什么策略优化比监督学习更加微妙和困难,也为后续理解更复杂算法的设计动机打下了基础。


至此,我们完成了对策略优化理论基础的系统阐述。从期望回报的定义出发,通过严格的数学推导得到了策略梯度公式,理解了REINFORCE算法的实现与局限,掌握了Actor-Critic架构的设计原理,并深入辨析了强化学习中loss函数的本质含义。后续我们将会继续学习更先进的策略优化算法如TRPO、PPO、DPO等。

3.5 REINFORCE算法代码实现

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import gymnasium as gym
from torch.distributions import Categorical
from collections import deque

# 1. 定义超参数
learning_rate = 0.001 # 适当降低学习率以增加稳定性
gamma = 0.99
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"using device:{device}")

# 2. 定义actor-critic网络
# actor(策略网络):输入状态,输出动作的概率分布
# critic(价值网络):输入状态,输出该状态的价值估计(基线)

class ActorCritic(nn.Module):

    def __init__(self, state_dim, action_dim, hidden_dims=[128]):
        super().__init__()
        

        # 动态创建共享层
        layers = []
        # 输入层
        layers.append(nn.Linear(state_dim, hidden_dims[0]))
        layers.append(nn.ReLU())
        
        # 循环创建多个隐藏层
        for i in range(len(hidden_dims) - 1):
            layers.append(nn.Linear(hidden_dims[i], hidden_dims[i+1]))
            layers.append(nn.ReLU())
        
        # 使用 nn.Sequential 将所有层组合起来
        self.share_layer = nn.Sequential(*layers)
        
        # Actor和Critic的头部连接到最后一层隐藏层
        # 最后一层隐藏层的维度是 hidden_dims[-1]
        last_hidden_dim = hidden_dims[-1]
        self.actor_head = nn.Linear(last_hidden_dim, action_dim)
        self.critic_head = nn.Linear(last_hidden_dim, 1)
    
    def forward(self, state):
        share_features = self.share_layer(state)
        
        action_logits = self.actor_head(share_features)
        action_probs = F.softmax(action_logits, dim=-1)

        state_value = self.critic_head(share_features)

        # 返回动作的概率分布和状态价值
        return Categorical(action_probs), state_value

def train():
    env = gym.make("CartPole-v1")
    state_dim = env.observation_space.shape[0]
    action_dim = env.action_space.n
    
    # 使用列表来定义多个隐藏层
    hidden_dims = [256, 128] 
    
    model = ActorCritic(state_dim, action_dim, hidden_dims).to(device)
    optimizer = optim.AdamW(model.parameters(), lr = learning_rate)
    max_episodes = 150
    log_interval = 25

    # 用于记录最近的奖励值,以便更准确地评估模型性能
    recent_rewards = deque(maxlen=log_interval)

    for i_episode in range(1, max_episodes + 1):
        state, _ = env.reset()
        ep_reward = 0 

        # 用于存储当前回合的数据
        log_action_probs = []
        state_values = []
        rewards = []
        
        # 玩一回合游戏
        while True:
            state_tensor = torch.from_numpy(state).float().unsqueeze(0).to(device)
            dist, state_value = model(state_tensor)
            
            action = dist.sample()
            
            log_action_probs.append(dist.log_prob(action))
            state_values.append(state_value)

            state, reward, terminated, truncated, _ = env.step(action.item())
            done = terminated or truncated

            rewards.append(reward)
            ep_reward += reward

            if done:
                break
        

        rewards_to_go = []
        discounted_reward = 0
        # 从后往前计算每个时间步的折扣回报
        for r in reversed(rewards):
            discounted_reward = r + gamma * discounted_reward
            rewards_to_go.insert(0, discounted_reward)
            
        rewards_to_go = torch.tensor(rewards_to_go, dtype=torch.float32, device=device)
        
        # 整理数据格式
        log_action_probs = torch.cat(log_action_probs)
        state_values = torch.cat(state_values).squeeze()
        
        # 计算优势函数 A(s,a) = Q(s,a) - V(s)
        # 这里用 G_t (rewards_to_go) 作为 Q(s,a) 的估计
        advantages = rewards_to_go - state_values
        advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-8)

        # 计算 Actor 和 Critic 的损失
        # detach防止actor_loss.backward() 会把梯度通过 advantages 反向传播到 state_values,进而影响 value 网络(critic)的参数。
        """
        在策略梯度法中,我们定义的 loss 只是一个"产生正确梯度的数学工具",
        它的值本身没有任何意义,但通过它的梯度,我们可以用常规的反向传播机制更新策略参数。
        """
        actor_loss = -(log_action_probs * advantages.detach()).mean()
        critic_loss = F.mse_loss(state_values, rewards_to_go)
        
        loss = actor_loss + 0.5 * critic_loss # 加一个系数可以平衡两个损失

        # 更新网络参数
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        recent_rewards.append(ep_reward)

        if i_episode % log_interval == 0:
            avg_reward = sum(recent_rewards) / len(recent_rewards)
            print(f'Episode {i_episode}\tLast reward: {ep_reward:.2f}\tAverage reward over last {log_interval} episodes: {avg_reward:.2f}')
            print(f"  actor_loss:{actor_loss.item():.4f}, critic_loss:{critic_loss.item():.4f}, total_loss:{loss.item():.4f}")

    env.close()

if __name__ == "__main__":
    train()
相关推荐
、、、、南山小雨、、、、2 天前
Pytorch强化学习demo
pytorch·深度学习·机器学习·强化学习
段智华2 天前
“AI+“行动下的可控智能体:GPT-5 与 GPT-OSS 高性能推理 安全可控 产业落地 GPT-OSS 一可控AI目前全球唯一开源解决方案
强化学习·大模型微调
大千AI助手4 天前
MATH-500:大模型数学推理能力评估基准
人工智能·大模型·llm·强化学习·评估基准·数学推理能力·math500
帅帅爱数学7 天前
DeepMimic论文详细解析:基于示例引导的深度强化学习实现物理仿真角色技能
算法·强化学习
镰刀韭菜8 天前
【大语言模型】大模型后训练入门指南
人工智能·自然语言处理·大语言模型·强化学习·ppo·后训练·grpo
bylander9 天前
【论文阅读】A Survey of Reinforcement Learning for Large Reasoning Models
论文阅读·大模型·llm·强化学习
Phoenixtree_DongZhao10 天前
《Nature》封面:DeepSeek-R1通过强化学习激发大语言模型的推理能力
人工智能·强化学习·混合专家
九章云极AladdinEdu10 天前
集成学习智慧:为什么Bagging(随机森林)和Boosting(XGBoost)效果那么好?
人工智能·随机森林·机器学习·强化学习·集成学习·boosting·ai研究
zzzyzh22 天前
RL【8】:Value Function Approximation
强化学习