
如果你对照着监督学习的直觉去调强化学习很容易经历这样的场景loss 不降反升reward 曲线像心电图温度系数调来调去也说不清到底在改什么。监督学习里有一个明确的损失函数梯度下降之后训练集损失会下降强化学习里目标函数是期望回报可你很少能打印出一个稳定下降的“Reinforcement Loss”。这个落差本质上不是代码问题而是视角问题。MaxRL这个提法想做的事是把强化学习从“通过试错最大化回报”重新表述成“通过数据拟合最大化似然”。它不是某一个具体的算法而是一套看待强化学习的框架。一旦你接受这套框架策略梯度、行为克隆、离线强化学习、模型预测控制甚至 Agentic RL 里的语言 Agent 训练都可以用同一套语言讲清楚奖励是权重策略是条件分布训练过程是带权重的最大似然估计。这篇文章我会用三个视角展开。第一个视角讲为什么奖励可以看成轨迹的对数似然第二个视角讲策略更新为什么可以写成带权最大似然第三个视角讲强化学习的整体训练流程为什么和 EM 算法非常像。最后我会给一个可以用 20 行 Python 跑通的极简示例并列出实际工程中容易踩的坑。1. 这篇文章真正要解决的问题很多人在刚开始学强化学习时会觉得算法特别碎策略梯度一套说法Q-learning 一套说法Actor-Critic 又有一套说法最后还要面对行为克隆、离线强化学习、最大熵强化学习这些看起来互不相干的子领域。这些算法当然各有各的推导但如果你只记住公式不建立统一视角遇到一个新问题就不知道选哪种框架去思考。另一个更实际的问题是调参。强化学习里最常见的“奖励缩放”“温度系数”“熵系数”本质上都在做同一件事控制“似然权重”的形状。你用最大似然的角度看就能理解为什么 reward scaling 和 temperature 会在很多算法里反复出现为什么 loss 不降不代表不学习。这篇文章真正想解决的是认知成本问题。读完你应该能做到三件事能用自己的话解释“强化学习为什么可以被理解为最大似然估计”能把策略梯度、行为克隆、离线加权回归放在同一张表里比较能在做 Agentic RL 或深度强化学习项目时用“带权最大似然”来设计训练目标而不是被公式牵着走。MaxRL 的核心判断是强化学习的本质困难不在于“梯度怎么算”而在于“哪些样本值得被模仿”。最大似然正好给了我们一个组织样本权重的自然语言。2. 基础概念与核心原理先明确几个基本概念后面所有内容都建立在它们之上。2.1 最大似然估计是什么最大似然估计是参数估计里最经典的方法。假设我们有一组观测数据 (x_1, x_2, \dots, x_n)它们服从某个带参数 (\theta) 的分布 (p_\theta(x))。最大似然估计就是找一组参数 (\theta)让这些数据出现的概率乘积最大[ \hat{\theta}{\mathrm{MLE}} \arg\max\theta \prod_{i1}^n p_\theta(x_i) ]取对数之后乘积变成求和[ \hat{\theta}{\mathrm{MLE}} \arg\max\theta \sum_{i1}^n \log p_\theta(x_i) ]所以最大似然的本质是选一组参数使得已经发生的事尽可能像是会发生的。在监督学习里数据就是带标签的样本模型就是条件分布 (p_\theta(y|x))训练就是在做最大似然。2.2 强化学习中的策略是什么强化学习中的策略 (\pi_\theta(a|s)) 也是一个条件分布给定状态 (s)模型输出动作 (a) 的概率。这里“动作”可以是离散动作、连续动作向量也可以是 Agent 生成的 token 或工具调用序列。如果只看这个结构策略网络和分类网络没有本质区别。它们都是输入状态或上下文输出动作分布。差别在于监督学习的标签来自人工标注或专家数据强化学习的“标签”并不直接给出而是要通过奖励信号来判断哪些动作“值得被当作标签”。这个差别正好是 Reinforce、PPO 等算法里 log-prob 乘上优势项的原因。2.3 轨迹的似然怎么写一条轨迹 (\tau) 是由状态、动作互相交替组成的序列[ \tau (s_1, a_1, s_2, a_2, \dots, s_T, a_T) ]在策略 (\pi_\theta) 控制下整条轨迹的分布可以写成[ p_\theta(\tau) p(s_1) \prod_{t1}^T p(s_{t1}|s_t, a_t) \pi_\theta(a_t|s_t) ]其中 (p(s_{t1}|s_t, a_t)) 是环境动态也就是状态转移概率。环境动态不归策略控制所以如果我们只想优化策略部分只需要关注[ \log \pi_\theta(\tau) \sum_{t1}^T \log \pi_\theta(a_t|s_t) ]这就是为什么几乎所有策略优化算法最终都会出现在某个时刻求log_prob(action)的代码。所谓“最大化轨迹似然”在策略层面就是让高回报轨迹上的动作概率尽量大。2.4 MaxRL 与传统最大似然的关键差异对比项监督式最大似然强化学习式最大似然数据来源固定数据集策略与环境交互采样标签含义人工标注的目标值高回报轨迹中的动作样本权重通常均匀由奖励或优势决定更新方式最小化负对数似然最小化带权负对数似然训练目标拟合全部数据拟合“在高奖励条件下出现的轨迹”这个表格是 MaxRL 的核心强化学习本质上不是不做最大似然而是做一种被奖励过滤过的最大似然。3. 视角一把奖励看成轨迹的对数似然第一个视角解决“奖励和目标函数的关系”这个问题。3.1 引入“最优性”变量控制作为概率推断Control as Inference里有一个经典做法定义一个二值变量 (O1) 表示“这条轨迹是好的”。奖励越大这条轨迹越有可能是好的。我们可以写成[ p(O1|\tau) \propto \exp\left(\frac{r(\tau)}{\alpha}\right) ]这里 (r(\tau)) 是整条轨迹的累计回报(\alpha) 是温度系数。它不是随便拍的而是让奖励可以当作“对数似然贡献”来用。如果进一步写出给定最优性条件下的轨迹后验分布[ p(\tau|O1) \frac{p(\tau) \exp(r(\tau)/\alpha)}{Z} ]取对数[ \log p(\tau|O1) \log p(\tau) \frac{r(\tau)}{\alpha} - \log Z ]你会在左边看到“最大似然”右边看到“最大回报”。也就是说当我们说“最大化回报”的时候其实是在最大化“这条轨迹事后被判定为最优”的对数似然。这个视角最大的价值在于强化学习不再被看成纯粹的数值优化问题而是被看成概率模型的推断问题。最优策略就是让“高质量轨迹”在模型下具有高密度的策略。3.2 为什么最大熵和探索不是额外技巧上面公式里的 (\log p(\tau)) 一项很重要。它代表策略先验或轨迹先验在控制问题里会自然带来熵增。这解释了为什么最大熵强化学习不是一个“为了探索而硬加的技巧”而是概率推断视角下自然会出现的行为温度 (\alpha) 高时(p(\tau)) 占主导策略倾向于保持随机更多探索温度 (\alpha) 低时奖励占主导策略倾向于选择高回报动作逐渐变成确定性策略。如果你遇到的最大熵强化学习比如 SAC你可以把它的目标函数理解为在最大化奖励似然的同时维持轨迹先验的熵。MaxRL 视角不会改变 SAC 的实现但会改变你对“熵系数为什么存在”的理解。3.3 与 Q-learning 的关系在最大熵框架下soft Q-learning 中的值函数和策略还有一个有趣的关系[ \pi(a|s) \propto \exp(Q(s,a) - V(s)) ]这实际上是一个能量模型形式的条件分布。(\log \pi(a|s)) 在这个表达里直接和 Q 值挂钩所以训练 Q 网络本质上是在估计这个能量模型的配分函数和能量函数。MaxRL 视角下的 Q-learning不再只是“查表式动态规划”而是“用最大似然去拟合一个基于能量的策略分布”。这个视角的好处是你可以从概率模型角度理解为什么 soft Q 需要温度、为什么要算 log-sum-exp也能解释为什么直接最大化 hard Q 会导致策略过早确定化。4. 视角二策略更新可以写成带权最大似然第二个视角解决“策略网络怎么更新”的问题。4.1 从行为克隆说起假设我们有一套专家轨迹数据集 (\mathcal{D} {(s_i, a_i)})里面每个动作都被认为是好的。那模仿学习的目标就是最大化这些动作的似然[ \theta^* \arg\max_\theta \sum_{(s,a)\in\mathcal{D}} \log \pi_\theta(a|s) ]这就是行为克隆。它本质上是一个纯最大似然问题和分类任务一模一样所以训练起来稳定、容易收敛。但行为克隆有一个致命问题它默认所有样本同等重要而强化学习中我们只有奖励哪些动作值得学需要自己去判断。4.2 把奖励变成样本权重我们可以给每个样本分配一个权重 (w_i)这个权重取决于奖励[ \theta^* \arg\max_\theta \sum_i w_i \log \pi_\theta(a_i|s_i) ]如果 (w_i 1)就是行为克隆如果 (w_i) 来自高回报轨迹的归一化奖励就是 Reweighted Behavior Cloning 或 Reward-Weighted Regression 的通用形式。用代码看加权重不过是在交叉熵损失上加一个系数# 文件路径maxrl_loss_demo.py import torch import torch.nn.functional as F # states: [batch, state_dim] # actions: [batch] 或 [batch, 1] # weights: [batch]由 reward/advantage 归一化得到 logits policy(states) nll F.cross_entropy(logits, actions, reductionnone) # 每个样本的负对数似然 loss (weights * nll).mean()这段代码几乎就是 MaxRL 视角里策略更新的最小形态先算每个动作的负对数似然然后用奖励相关权重做加权平均最后梯度下降。4.3 策略梯度就是带符号权重的最大似然真正完整的强化学习当然不能只用固定数据还要考虑数据来自旧策略的问题。但策略梯度的数学形式和上面的加权 NLL 非常接近[ \nabla_\theta J(\theta) \mathbb{E}{\tau \sim \pi\theta}\left[ \sum_t \nabla_\theta \log \pi_\theta(a_t|s_t) \cdot A_t \right] ]你可以把优势函数 (A_t) 理解成动作样本的权重。它可能是正数代表“这个动作比平均好”也可能是负数代表“这个动作比平均差”。负权重意味着我们要降低这个动作的似然。所以策略梯度不是“另一种强化学习”而是“最大似然估计的随机梯度版本只不过权重被优势函数代替”。这也是为什么 PPO、REINFORCE 等算法里核心操作都是log_prob乘advantage而不是直接乘reward。我强烈建议你在实现策略网络时不要只保留forward输出动作还应该单独提供log_prob方法。从 MaxRL 视角看log_prob才是策略网络的“主力输出”动作采样只是它的副产品。5. 视角三整个训练过程像 EM 算法第三个视角解决“数据从哪里来、模型怎么迭代”的问题。5.1 EM 算法的结构EMExpectation-Maximization算法用于带隐变量的最大似然估计分为两步E 步基于当前参数推断隐变量的分布计算每个样本的后验概率M 步用这些后验概率作为权重最大化完整数据的对数似然。比如高斯混合模型里的责任度 (r_{ik})就是“第 (i) 个样本属于第 (k) 个高斯分布”的后验概率。M 步用这些责任度重新估计均值和方差。5.2 强化学习和 EM 的对应关系强化学习里的“隐变量”可以理解为“哪些状态动作对被高回报负责”。我们确实不知道哪个动作真正导致最终成功只能通过整条轨迹的回报反推。这个反推过程就是 E 步。E 步采样轨迹计算每条轨迹或每个状态动作对的奖励、优势、权重。这一步回答“哪些经验值得学”。M 步在带权数据上更新策略最大化加权对数似然。这一步回答“策略应该往哪个方向调”。这个对应关系非常优雅算法家族E 步近似获得权重M 步近似更新策略策略梯度 / PPO用当前策略采样计算优势优势加权 (\log \pi) 的梯度上升奖励加权回归对 rewards 做 softmax / 温度缩放最小化带权负对数似然行为克隆不需要专家数据权重均匀普通最大似然离线强化学习从固定数据集估计 Q 或权重带权最大似然或约束策略更新基于模型的强化学习采样并预测未来同时拟合动态模型的最大似然看到这张对应表你会发现很多深度强化学习算法之间的差异主要落在“E 步怎么估计权重”上而不是“M 步怎么更新”上。5.3 为什么不是严格 EM严格来说强化学习不是精确的 EM因为策略在 M 步之后会变化下一次 E 步的数据分布也随之变化。EM 在固定模型下保证对数似然单调递增强化学习却没有这种保证这也是训练曲线震荡的根本原因。但用 EM 作为心智模型仍然非常有用。它能解释为什么“不断重复旧数据”会出问题如果你用旧策略采样的数据去拟合新策略相当于拿错误分布的权重做最大似然没有重要性修正训练就会漂移。从 MaxRL 视角看强化学习可以被理解为“在迭代中反复估计哪些轨迹属于高回报区域然后做带权最大似然”。这个表述比“试错搜索最优策略”更接近现代 RLHF 和 Agentic RL 的真实做法。6. 极简代码示例用带权最大似然更新策略为了让你直观感受 MaxRL这里给一个 20 行左右的教学示例。它不使用真正的环境而是模拟几个状态动作样本用奖励权重做带权最大似然更新。这个例子不是完整的强化学习算法只演示核心的数学机制。6.1 完整代码# 文件路径maxrl_demo.py # 依赖numpy无需额外深度学习框架 import numpy as np def sigmoid(z): return 1.0 / (1.0 np.exp(-z)) class BernoulliPolicy: 二元动作的简单逻辑回归策略输出 P(a1|s) def __init__(self, dim2, lr0.2): self.w np.zeros(dim) self.lr lr def p(self, s): return sigmoid(np.dot(self.w, s)) def log_prob(self, s, a): p np.clip(self.p(s), 1e-12, 1.0 - 1e-12) return a * np.log(p) (1.0 - a) * np.log(1.0 - p) def make_demo_data(): # 状态第二维越高动作 1 的奖励越高 states np.array([ [1.0, 0.1], [1.0, 0.8], [1.0, 0.5], [1.0, 0.9], ]) actions np.array([0, 1, 1, 1]) rewards np.array([0.1, 1.0, 0.6, 0.9]) return states, actions, rewards def reward_to_weight(rewards, temp0.5): 把奖励转换成归一化权重防止 exp 数值爆炸 shifted (rewards - rewards.max()) / temp exp_w np.exp(shifted) return exp_w / exp_w.sum() def train(): states, actions, rewards make_demo_data() weights reward_to_weight(rewards) policy BernoulliPolicy(lr0.2) n len(states) for step in range(51): grads np.zeros_like(policy.w) for s, a, w in zip(states, actions, weights): p policy.p(s) # d log pi(a|s) / d w (a - p) * s grads w * (a - p) * s policy.w policy.lr * grads / n if step % 10 0: weighted_nll -sum( w * policy.log_prob(s, a) for s, a, w in zip(states, actions, weights) ) / n print(fstep{step:3d} weighted_nll{weighted_nll:.4f} w{policy.w}) print(最终权重:, policy.w) if __name__ __main__: train()6.2 运行命令python maxrl_demo.py如果当前环境没有 numpy先安装pip install numpy6.3 预期结果与验证方式这段代码不连环境、不采样轨迹只是一个最小可运行示例。运行后你应该看到weighted_nll整体呈下降趋势权重向“让高奖励样本概率更高”的方向移动由于状态第二维与高奖励相关最终 (w[1]) 会变成正值。具体的数值会受随机初始化和步长影响不用刻意复现某个数字。重点是理解三件事奖励被转成了权重负对数似然被加权参数更新方向等于带权梯度。6.4 为什么不叫完整强化学习因为完整强化学习至少要解决两个问题数据需要由当前策略不断采样产生而不是固定数据集奖励权重的估计需要考虑长期回报和方差控制不能只看单步奖励。MaxRL 视角可以解释策略更新这一步但它不替代探索、状态表示、收益估计这些工程模块。这也是“用最大似然重新理解强化学习”和“用最大似然替代强化学习”之间的区别。7. 用 MaxRL 视角重新选择算法当你看过一个新算法时建议先用下面几个问题归类它的训练数据是固定的还是在线采样的它给样本的权重是奖励、优势、动作概率还是全部相等它是否显式建模了动态或者最优性变量它的目标函数是否可以写成“带权对数似然”这些问题构成一个实用决策表场景推荐思路权重来源只有专家数据无奖励行为克隆 / 监督微调均匀权重有静态数据集和奖励离线 RL / 奖励加权回归reward / Q 值可以与环境在线交互策略梯度 / PPO / SACadvantage / soft reward需要高样本效率基于模型的 RL动态模型似然 策略似然训练语言 Agent 执行多步任务Agentic RL 偏好优化成功轨迹 / 偏好排序这个表不是绝对的但它能帮你快速去掉那些“看起来很像但前置条件完全不同”的干扰项。MaxRL 不负责告诉你哪个算法最强大它负责告诉你可以从哪个角度看算法之间的差异。8. 常见问题与排查方法问题现象可能原因排查方式解决方案加权负对数似然下降但最终回报不涨权重计算错误高奖励样本权重没被正确归一化打印 weights 分布检查 reward scale使用 softmax 温度归一化并加 baseline策略很快变成确定性策略温度太低奖励权重差距过大查看动作分布熵提高温度或对权重做平滑reward 取 exp 时出现 NaN奖励值跨度过大检查 reward min/max先减最大值再做 exp必要时先做 reward scaling旧数据上 loss 很低新环境表现很差分布偏移数据来自旧策略比较旧策略和新策略动作分布做重要性采样或重新采集数据模型输出概率恒为 0/1log 计算报错没有数值保护检查 logits 和 clip在 log_prob 中 clip 概率到极小值策略梯度训练震荡严重优势估计方差大打印 advantage 分布和方差使用 GAE、baseline 或 advantage normalization这里面最容易被忽视的是第一行加权 NLL 下降并不等于回报上升。因为权重本身会随着策略和环境的变化而改变。MaxRL 视角能帮你解释 loss 的含义但最终评价指标仍然应当是期望回报、任务成功率或安全约束满足率。9. 最佳实践与工程建议如果你真的想在项目里用 MaxRL 视角指导工程实现下面几点值得长期坚持。9.1 永远在 log 空间计算概率多个动作概率相乘很容易下溢。轨迹的似然要写成对数求和策略网络的输出也应该优先使用log_softmax、log_prob这类 API。不要在代码里出现“先算概率密度再手动相乘”的路径。9.2 奖励权重先归一化再进损失把奖励直接乘到负对数似然上通常会导致两个问题数值不稳定和训练尺度不一致。推荐做法是先将奖励做 shift 和温度缩放再转成权重或者使用优势归一化。温度系数的初始值可以从 (0.1 \sim 1.0) 范围开始试但不要把它当成必须固定不变的常数。9.3 跟踪策略熵从最大似然视角看策略分布本身就是模型。低熵不总是坏事但熵骤降通常意味着“模型过早确信”。建议在每个训练阶段记录策略熵加权 NLL未加权 NLL期望回报或任务成功率优势 / 权重的均值与方差。这几项指标合在一起才是一份完整的训练监控面板。9.4 对 Agentic RL把成功轨迹当作似然数据现在的 Agentic RL 场景里策略生成的是一个很长的文本动作序列包括思考、调用工具、读取结果等。环境状态变成了上下文奖励来自于任务成功与否。用 MaxRL 视角看成功和失败的轨迹都应该被组织成带权样本成功的轨迹权重更高失败的轨迹权重低甚至为负。这也解释了为什么很多 LLM Agent 训练会先用监督微调采集成功轨迹再用偏好优化或策略梯度做加权修正。前者是“纯最大似然”后者是“奖励加权的最大似然”。两者不是彼此替代而是同一个概率模型下的不同训练阶段。9.5 回滚与实验管理因为强化学习训练不稳定任何改动都应该能回滚。建议在代码里把 reward scaling、temperature、advantage 计算方式做成可配置项# 文件路径config.py rl_config { temperature: 0.5, reward_scale: 1.0, use_advantage_normalization: True, policy_lr: 3e-4, entropy_coef: 0.01, }训练时把这个配置存成 json每次实验都记录一组。出现异常结果时先对比配置差异再去看指标曲线。这比在代码里临时改数字要可靠得多。10. 总结与后续学习方向MaxRL 的核心并不复杂用一个带权最大似然公式把奖励、策略和训练流程统一起来。第一个视角让奖励变成轨迹的对数似然贡献第二个视角让策略更新变成带权负对数似然最小化第三个视角让整个训练循环对标 EM 算法。你可以继续用这套框架去读 SAC、PPO、离线强化学习以及 Agentic RL 的论文大概率会发现很多算法里的“巧思”其实是在回答同一个问题E 步怎么估计权重M 步怎么防止过度拟合。建议下一步做两件事。第一把本文的maxrl_demo.py改成真正连环境的 on-policy 版本每轮用当前策略采样计算优势再更新策略。第二把一个现成的监督微调脚本改成带权最大似然版本用合成奖励数据跑一次直观感受权重大小如何改变策略分布。最后提醒一句最大似然是理解强化学习的强大透镜但它不是魔法。探索、值函数估计、信用分配这些工程问题仍然存在。带着 MaxRL 视角去读代码和论文比单纯记住几个损失函数要有用得多。