尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
从LQR到深度强化学习:CS285最优控制与策略梯度进阶指南
1. 从LQR到深度强化学习一条被低估的进阶路线很多人学强化学习一上来就扎进策略梯度、PPO、SAC这些热门算法里跑几个MuJoCo环境看到reward曲线往上走就觉得自己入门了。但真到了要自己设计控制器、调参调到怀疑人生的时候才发现底层那套最优控制的理论框架根本没搭起来。CS285的lec10到lec12这三讲恰好卡在一个非常关键的位置——它把经典最优控制里的LQR线性二次调节器和深度强化学习里的策略优化串了起来。如果你跳过LQR直接看后面的actor-critic很多推导你会觉得“凭空冒出来”但补上LQR这块基石之后整个逻辑链条会顺畅得多。这篇文章面向的是已经学过一点强化学习基础比如知道MDP、值函数、策略梯度大概怎么回事但在最优控制和深度RL结合处卡壳的人。我会把lec10到lec12的核心内容拆开重点讲清楚LQR为什么重要、它和RL的桥梁在哪里、以及实操中怎么把这些理论落地成能跑的代码。文章里涉及的公式推导我会尽量用直觉解释参数选择会给具体计算过程踩过的坑也会如实说。你不需要有控制理论背景但需要愿意动手推一推公式、跑一跑实验。先说结论LQR不是“过时的经典控制”它是理解现代深度RL中策略优化、值函数近似、甚至模型预测控制的一把钥匙。lec10讲LQR和轨迹优化lec11讲从最优控制到RL的过渡lec12讲策略梯度和actor-critic。这三讲连起来看你会发现很多深度RL里的设计选择其实在LQR框架下早有答案。2. LQR基础为什么它值得你花时间啃2.1 LQR到底在解决什么问题LQR要解决的问题非常具体你有一个线性系统状态转移是 ( x_{t1} A x_t B u_t )你想找一个控制序列 ( u_0, u_1, \dots, u_{T-1} )让整个轨迹上的累积代价最小。代价函数是二次型的[ J \sum_{t0}^{T-1} (x_t^T Q x_t u_t^T R u_t) x_T^T Q_f x_T ]这里 ( Q ) 和 ( Q_f ) 是半正定矩阵惩罚状态偏离原点( R ) 是正定矩阵惩罚控制量的大小。这个设定看起来简单但它有两个极其重要的性质第一最优控制律是状态的线性函数 ( u_t K_t x_t k_t )第二这个问题有解析解可以通过动态规划反向递推求出 ( K_t ) 和 ( k_t )。我刚开始学的时候觉得这太理想化了——真实系统哪有线性的但后来才明白LQR的价值不在于直接控制真实系统而在于它提供了一个可解析分析的最优控制基准。深度RL里的很多算法本质上是在用神经网络去逼近LQR给出的那个最优策略只不过系统是非线性的、代价函数是任意的。2.2 反向递推LQR的求解过程拆解LQR的求解用的是动态规划的思想从终点往回推。定义值函数 ( V_t(x) ) 为从时刻 ( t ) 的状态 ( x ) 出发到终点为止的最小代价。由于代价是二次型、系统是线性的可以假设 ( V_t(x) x^T P_t x 2 p_t^T x c_t )。这个假设不是拍脑袋而是因为二次型在线性变换下保持二次型所以值函数的形式可以预先确定。反向递推的步骤是这样的初始化 ( P_T Q_f )( p_T 0 )( c_T 0 )。对于 ( t T-1 ) 到 ( 0 )计算 [ K_t (R B^T P_{t1} B)^{-1} B^T P_{t1} A ] [ k_t (R B^T P_{t1} B)^{-1} B^T p_{t1} ] [ P_t Q A^T P_{t1} A - A^T P_{t1} B (R B^T P_{t1} B)^{-1} B^T P_{t1} A ] [ p_t A^T p_{t1} - A^T P_{t1} B (R B^T P_{t1} B)^{-1} B^T p_{t1} ]得到最优控制 ( u_t -K_t x_t - k_t )。这个递推过程在代码里就是一个for循环但有几个细节容易出错。第一矩阵求逆那一步( R B^T P_{t1} B ) 必须是对称正定的否则求逆会出问题。实际实现时可以用Cholesky分解或者直接调numpy的linalg.solve不要显式求逆。第二如果 ( Q ) 和 ( R ) 的量级差太多数值稳定性会变差建议先做归一化。第三当 ( T ) 很大时( P_t ) 会收敛到一个稳态值 ( P_\infty )这时候可以用稳态LQR不用每一步都递推。注意LQR的反向递推要求系统是可镇定的stabilizable也就是说所有不稳定的模态都能被控制输入影响。如果这个条件不满足递推出来的 ( P_t ) 可能发散。2.3 有限时域与无限时域LQR的区别lec10里花了很大篇幅讲有限时域LQR也就是 ( T ) 是固定的。这种情况下 ( K_t ) 是时变的越靠近终点控制增益越大因为你要在有限步内把状态拉回原点。无限时域LQR则是 ( T \to \infty )这时候 ( K_t ) 收敛到常数矩阵 ( K_\infty )可以用代数Riccati方程直接求解。实际做RL实验时大部分环境是无限时域的或者episode长度不固定所以稳态LQR更常用。但有限时域LQR的推导是理解动态规划的基础不能跳过。我建议你先手推一遍有限时域的递推再用scipy或者自己写代码验证最后看无限时域怎么从有限时域取极限得到。2.4 LQR与轨迹优化的关系LQR本质上是一个轨迹优化问题只不过它有解析解。更一般的轨迹优化问题非线性系统、非二次代价没有解析解需要用数值方法比如打靶法shooting method或者配点法collocation。lec10里提到的iLQRiterative LQR就是把非线性系统在 nominal trajectory 附近线性化然后用LQR求解再更新轨迹反复迭代。iLQR的每一步是这样的在当前轨迹 ( \bar{x}_t, \bar{u}_t ) 处线性化动力学( A_t \frac{\partial f}{\partial x} )( B_t \frac{\partial f}{\partial u} )。在轨迹处二次化代价函数得到 ( Q_t, R_t, Q_f )。用LQR反向递推求出最优控制增量 ( \delta u_t )。前向传播更新轨迹加入线搜索保证代价下降。重复直到收敛。这个流程和深度RL里的策略迭代非常像——都是在当前策略下评估然后改进策略。区别在于iLQR用的是局部线性二次近似而深度RL用的是神经网络全局近似。理解了iLQR你再看TRPO、PPO里的信赖域和线搜索会觉得似曾相识。3. 从最优控制到强化学习lec11的桥梁作用3.1 为什么需要从最优控制过渡到RLLQR和iLQR都假设你知道系统动力学 ( f(x, u) )。但现实中很多场景下你根本不知道动力学方程只能通过和环境交互采样来学习。这就是RL要解决的问题。lec11的核心就是讲清楚当你不知道动力学时怎么把最优控制的思想转化成RL算法。这里有一个关键的概念转换在最优控制里你优化的是控制序列 ( u_{0:T-1} )在RL里你优化的是策略 ( \pi_\theta(u|x) )。策略是一个从状态到动作分布的映射它可以是随机的也可以是确定的。这个转换看起来简单但它带来了两个新问题第一策略的参数量可能很大比如神经网络怎么高效优化第二采样是有噪声的怎么保证估计的梯度方向是对的3.2 值函数、Q函数与优势函数lec11里重新定义了值函数和Q函数但这次是在RL的语境下。值函数 ( V^\pi(x) ) 是从状态 ( x ) 出发按照策略 ( \pi ) 采样得到的期望累积回报。Q函数 ( Q^\pi(x, u) ) 是在状态 ( x ) 执行动作 ( u )然后按照 ( \pi ) 继续的期望累积回报。优势函数 ( A^\pi(x, u) Q^\pi(x, u) - V^\pi(x) ) 衡量的是动作 ( u ) 相对于平均水平的优劣。这三个函数的关系是RL算法的核心。策略梯度的公式可以写成[ \nabla_\theta J(\theta) \mathbb{E}{x \sim \rho^\pi, u \sim \pi\theta} [\nabla_\theta \log \pi_\theta(u|x) A^\pi(x, u)] ]这个公式的直觉是增加高优势动作的概率降低低优势动作的概率。但这里有一个坑——优势函数的估计是有偏的如果估计不准策略梯度就会把策略带偏。所以后面才有GAE广义优势估计这种技巧来平衡偏差和方差。3.3 策略迭代与值迭代的RL版本在最优控制里策略迭代是给定策略计算值函数然后基于值函数改进策略。在RL里这个流程变成了用当前策略 ( \pi_\theta ) 采样一批轨迹。用这些轨迹估计优势函数 ( \hat{A}^\pi(x, u) )。用策略梯度更新 ( \theta )。重复。这个流程和iLQR的迭代非常像但有一个本质区别iLQR每次迭代都重新线性化而RL的策略更新是在参数空间里走一小步。这个“一小步”的大小就是学习率它决定了算法的稳定性和收敛速度。学习率太大策略会崩太小收敛太慢。lec11里提到的信赖域方法比如TRPO就是用来控制这个步长的。3.4 模型学习从数据中估计动力学如果你既想用最优控制的思路又不知道动力学一个自然的想法是先从数据里学一个动力学模型 ( \hat{f}(x, u) )然后用iLQR或者MPC去控制。这就是基于模型的RLmodel-based RL。lec11里讨论了模型学习的几种方式一种是直接回归 ( x_{t1} - x_t ) 作为目标另一种是预测状态分布。直接回归的损失函数是均方误差但要注意模型误差会在多步预测中累积所以训练时最好用多步预测的损失。模型学习的一个常见坑是神经网络模型在训练数据分布内很准但一旦策略跑到分布外模型预测就会错得离谱。这时候用模型规划出来的控制量可能完全不可行。解决办法是加入不确定性估计比如用ensemble或者贝叶斯神经网络当模型不确定时降低对模型的信任。4. 策略梯度与Actor-Criticlec12的核心内容4.1 策略梯度的推导与直觉lec12从策略梯度开始讲。策略梯度的推导有两种方式一种是似然比方法REINFORCE另一种是路径导数方法。似然比方法不要求动力学可微适用性更广但方差大路径导数方法要求动力学可微方差小但有偏。CS285主要讲似然比方法因为它在深度RL里更常用。似然比方法的核心公式是[ \nabla_\theta J(\theta) \mathbb{E}{\tau \sim \pi\theta} [\sum_{t0}^{T-1} \nabla_\theta \log \pi_\theta(u_t|x_t) \hat{A}_t] ]其中 ( \hat{A}t ) 是优势函数的估计。这个公式的推导用到了log-derivative trick( \nabla\theta \pi_\theta \pi_\theta \nabla_\theta \log \pi_\theta )。这个技巧把对概率的梯度转化成了对log概率的梯度使得我们可以用采样来估计梯度。实操中( \hat{A}t ) 的估计方式决定了算法的性能。最简单的估计是 ( \hat{A}t \sum{tt}^{T-1} r{t} - b )其中 ( b ) 是基线。基线的作用是降低方差不影响期望。更好的估计是GAE[ \hat{A}t^{GAE} \sum{l0}^{T-t-1} (\gamma \lambda)^l \delta_{tl} ]其中 ( \delta_t r_t \gamma V(x_{t1}) - V(x_t) ) 是TD误差。( \lambda ) 控制偏差和方差的权衡( \lambda0 ) 时就是TD误差方差小但偏差大( \lambda1 ) 时就是蒙特卡洛回报无偏但方差大。实际中 ( \lambda ) 取0.95到0.99之间比较常见。4.2 Actor-Critic架构的设计选择Actor-Critic就是把策略actor和值函数critic分开表示actor负责选动作critic负责评估动作的好坏。lec12里讨论了几个设计选择第一actor和critic是否共享网络参数。共享参数可以减少参数量、加速训练但可能导致两个任务互相干扰。实际中如果状态空间是图像通常共享卷积层如果是低维状态通常分开。第二critic是学 ( V(x) ) 还是 ( Q(x, u) )。学 ( V(x) ) 的话优势函数需要 ( Q(x, u) - V(x) )而 ( Q(x, u) ) 可以用 ( r \gamma V(x) ) 来估计。学 ( Q(x, u) ) 的话优势函数直接是 ( Q(x, u) - V(x) )但 ( V(x) ) 需要额外估计。两种方式各有优劣实际中A2C、PPO通常学 ( V(x) )而DDPG、SAC通常学 ( Q(x, u) )。第三策略是随机还是确定。随机策略比如高斯策略天然有探索能力但方差大确定策略比如DDPG需要额外加噪声来探索但样本效率高。lec12主要讲随机策略因为它的策略梯度推导更直接。4.3 方差缩减技巧实操策略梯度的方差是最大的敌人。除了GAE还有几个常用的方差缩减技巧基线baseline用 ( V(x) ) 作为基线优势函数变成 ( Q(x, u) - V(x) )。基线不改变期望但能显著降低方差。奖励归一化把奖励减去滑动平均、除以滑动标准差。这个技巧在连续控制任务里几乎是标配。优势归一化在一个batch内把优势函数归一化到零均值、单位方差。这个技巧在PPO里很常用。并行采样用多个环境并行采样然后拼成一个batch。这样batch内的样本更独立梯度估计更稳。我实测下来奖励归一化和优势归一化对训练稳定性的提升最明显。特别是奖励归一化如果不做不同任务的奖励量级差很多学习率根本没法统一设。4.4 从策略梯度到PPO信赖域的实际实现lec12最后提到了信赖域方法也就是TRPO和PPO。TRPO的约束是KL散度小于某个阈值保证策略更新不会太大。PPO把约束软化成了惩罚项或者clip实现更简单。PPO的clip目标函数是[ L^{CLIP}(\theta) \mathbb{E}_t [\min(r_t(\theta) \hat{A}_t, \text{clip}(r_t(\theta), 1-\epsilon, 1\epsilon) \hat{A}_t)] ]其中 ( r_t(\theta) \frac{\pi_\theta(u_t|x_t)}{\pi_{\theta_{old}}(u_t|x_t)} ) 是概率比。clip的作用是当概率比超出 ( [1-\epsilon, 1\epsilon] ) 时梯度不再推动策略往那个方向走。这个设计比TRPO简单得多但效果差不多。实操中PPO有几个关键参数clip范围 ( \epsilon ) 通常取0.1到0.2GAE的 ( \lambda ) 取0.95每个batch更新多少次n_epochs通常取3到10学习率用3e-4到1e-3。这些参数不是随便设的背后都有偏差-方差权衡的考量。5. 实操复现从LQR到PPO的完整流程5.1 环境搭建与依赖选择要复现lec10到lec12的内容你需要一个能跑LQR和深度RL的环境。我建议用Python依赖如下pip install numpy scipy matplotlib gymnasium torchgymnasium是OpenAI Gym的维护版本接口更稳定。torch用来实现神经网络。如果你不想装gymnasium也可以自己写一个简单的线性系统环境LQR部分不需要gym。对于LQR实验我建议先从一个简单的双积分器开始[ A \begin{bmatrix} 1 \Delta t \ 0 1 \end{bmatrix}, \quad B \begin{bmatrix} 0 \ \Delta t \end{bmatrix} ]状态是位置和速度控制是加速度。( Q \text{diag}(1, 0.1) )( R 0.01 )。这个系统足够简单但能展示LQR的所有关键特性。5.2 LQR反向递推的代码实现下面是一个有限时域LQR的实现import numpy as np def lqr_finite(A, B, Q, R, Qf, T): n A.shape[0] m B.shape[1] P [None] * (T 1) K [None] * T P[T] Qf for t in range(T - 1, -1, -1): S R B.T P[t1] B K[t] np.linalg.solve(S, B.T P[t1] A) P[t] Q A.T P[t1] A - A.T P[t1] B K[t] return K, P这个实现里我用np.linalg.solve而不是显式求逆数值上更稳定。K[t]是时刻 ( t ) 的最优控制增益控制律是 ( u_t -K[t] x_t )。验证的时候你可以跑一个闭环仿真看状态是否收敛到零。如果发散检查 ( Q ) 和 ( R ) 是否正定以及系统是否可镇定。5.3 从LQR到iLQR的扩展iLQR的实现要复杂一些因为需要线性化和二次化。下面是一个简化版的iLQR核心循环def ilqr(f, cost, x0, U, T, n_iter50): U U.copy() for it in range(n_iter): # 前向传播 X [x0] for t in range(T): X.append(f(X[t], U[t])) # 反向递推 K, k backward_pass(f, cost, X, U) # 前向更新 X_new, U_new forward_pass(f, X, U, K, k) # 线搜索 U line_search(f, cost, X, U, X_new, U_new) return U这个框架和深度RL的策略迭代非常像前向传播对应采样反向递推对应策略评估前向更新对应策略改进。区别在于iLQR用的是解析梯度而深度RL用的是随机梯度。5.4 PPO在连续控制任务上的实现要点PPO的实现有几个关键模块第一网络结构。actor输出高斯分布的均值和标准差critic输出状态值。均值用tanh激活限制在动作范围内标准差用softplus保证正数。第二采样和更新。每个iteration采样一批轨迹计算GAE然后对actor和critic分别做梯度更新。critic的损失是值函数的均方误差actor的损失是PPO的clip目标。第三超参数。我常用的配置是learning_rate3e-4gamma0.99lambda0.95clip_epsilon0.2n_epochs10batch_size64。这些参数在MuJoCo任务上表现稳定。一个常见的坑是如果奖励没有归一化critic的损失会很大梯度会爆炸。解决办法是在环境wrapper里做奖励归一化用滑动平均和滑动标准差。5.5 实验结果对比与分析我跑了一个简单的对比实验在双积分器系统上分别用LQR、iLQR和PPO控制。LQR直接给出解析最优解累积代价最低iLQR迭代几次后接近LQRPPO需要更多样本但最终也能达到接近LQR的性能。这个对比说明了一个重要观点当系统是线性的、代价是二次的LQR是最优的深度RL没有必要。深度RL的价值在于处理非线性系统和非二次代价。但理解LQR能帮你判断深度RL算法的性能上限——如果PPO在双积分器上都跑不过LQR那说明实现有问题。6. 常见问题与排查技巧实录6.1 LQR递推发散的排查思路LQR反向递推发散通常有三个原因第一系统不可镇定也就是存在不稳定模态不受控制输入影响。检查方法计算PBH矩阵 ( [\lambda I - A, B] ) 的秩对所有不稳定特征值 ( \lambda ) 都要满秩。第二( R ) 不是正定的导致 ( R B^T P B ) 不可逆。检查 ( R ) 的特征值是否都大于零。第三数值误差累积特别是 ( T ) 很大时。解决办法是用稳态LQR或者用平方根滤波。6.2 策略梯度方差过大的处理策略梯度方差过大表现为训练曲线剧烈震荡不同随机种子结果差异巨大。处理方法第一加基线用 ( V(x) ) 作为基线。第二用GAE( \lambda ) 取0.95左右。第三奖励归一化。第四增大batch size。第五用并行环境采样。我通常同时用前四个效果就很明显了。6.3 PPO训练不收敛的常见原因PPO不收敛的原因很多我列一个速查表现象可能原因解决办法策略熵迅速降到零熵正则系数太小增大entropy_coef到0.01值函数损失震荡学习率太大降低critic学习率奖励不上升优势估计有偏检查GAE的lambda和gamma动作饱和动作范围没限制用tanh压缩均值训练后期崩溃clip范围太大减小clip_epsilon到0.16.4 模型学习中的分布偏移问题基于模型的RL最大的坑是分布偏移模型在训练数据上很准但策略跑到新区域后模型预测完全错误。解决办法第一用ensemble估计不确定性当不确定性高时降低模型的使用权重。第二用短rollout不要用模型预测太长的轨迹。第三定期用真实环境数据重新训练模型。第四用保守的模型预测比如对预测的状态加惩罚。6.5 从仿真到实物的迁移注意事项如果你想把LQR或RL算法用到真实系统上有几个注意事项第一仿真里的动力学和真实系统有差距LQR的增益需要重新调。第二真实系统有延迟和噪声需要在代价函数里加惩罚项。第三安全约束很重要LQR可以加约束变成约束LQRRL可以用安全层过滤动作。第四先从简单的PD控制开始逐步过渡到LQR和RL。我个人在实际操作中的体会是LQR那套东西看起来数学味很重但真正写代码实现一遍之后你会发现它比深度RL简单得多而且能给你很多直觉。比如为什么PPO要clip、为什么GAE要用lambda、为什么值函数要归一化这些问题在LQR框架下都有对应的解释。lec10到lec12这三讲值得反复看几遍每遍都会有新的收获。
RELATED

相关推荐

美赛时间序列预测全攻略:从数据预处理到ARIMA与机器学习集成

美赛时间序列预测全攻略:从数据预处理到ARIMA与机器学习集成

美赛里凡是遇到“给一串历史数据,要你预测未来某段时间的值”这种题——气温、车流量、商品销量、发电量、汇率、感染者数量——基本都能归到时间序列回归预测这个大类。这个类型在历年美赛题目里出现频率非常高,而且不像微分方程模型那样依赖复杂的机理…

📅 2026/10/13 7:47:30
Android架构笔记:状态管理、依赖注入与模块化实战

Android架构笔记:状态管理、依赖注入与模块化实战

1. 为什么我把架构笔记写成这样如果你和我一样,经历过一段“能跑就行”的开发阶段,再回头看自己写过的Activity,多少都会冒冷汗。启动页跳转写满了碎逻辑,接口回调直接在页面里改UI,一个方法超过200行——不是不想改&a…

📅 2026/10/13 7:47:30
西门子S7-1200在锂电涂布机浆料输送系统的应用与调试

西门子S7-1200在锂电涂布机浆料输送系统的应用与调试

做锂电非标设备这些年,涂布机的浆料输送系统一直是我觉得入门西门子S7-1200最合适的“练兵场”。它不像机器人控制那样偏重运动学,也不像DCS那样强调大点数冗余,而是把模拟量处理、PID调节、变频通讯、触摸屏组态、安全回路这些PLC工程师日常…

📅 2026/10/13 7:42:30
MORE NEWS

更多资讯

📰

NaughtyAttributes ShowAssetPreview 详解:在 Unity Inspector 中直接预览 Sprite 与 Prefab 资源

游戏开发开发工具 【免费下载链接】NaughtyAttributes Attribute Extensions for Unity 项目地址: https://gitcode.com/gh_mirrors/na/NaughtyAttributes 点击查看 免费下载 ShowAssetPreview 是 NaughtyAttributes 提供的一个 Drawer Attribute(抽屉属…

📰

Varlet Pagination 分页组件完全指南:两种模式、属性配置与源码原理剖析

UI组件前端 【免费下载链接】varlet A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop. 项目地址: https://gitcode.com/gh_mirrors/va/varlet 点击查看 免费下载 分页(Pagination)是处理大数据量…

📰

cortex 项目中的 go-openapi/swag jsonutils 模块:动态 JSON、有序键 JSONMapSlice 与可插拔序列化 Adapter 机制全解析

可观测性时序数据库后端指标监控 【免费下载链接】cortex A horizontally scalable, highly available, multi-tenant, long term Prometheus. 项目地址: https://gitcode.com/gh_mirrors/cortex6/cortex 点击查看 免费下载 jsonutils 是开源 Go 工具库 github.com…

📰

LunaTranslator 游戏实时翻译器使用指南:HOOK、OCR 与内嵌翻译

LunaTranslator 游戏实时翻译器使用指南:HOOK、OCR 与内嵌翻译 【免费下载链接】LunaTranslator 视觉小说翻译器 / Visual Novel Translator 项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator 日文视觉小说里大段假名读不懂,只能…

📰

从Blending到Bagging:集成学习如何用群体决策提升模型稳定性

翻到Week 7的笔记,这大概是整门《机器学习技法》公开课里最让人耳目一新的一章。前面六周我们一直在跟“单一模型”较劲:线性模型、支持向量机、核方法、决策树,每一个都研究得很深,但谁都避免不了一个尴尬——换个数据分布&#…

📰

AI日报自动化实战:多源采集与结构化输出

1. 一份AI日报的诞生逻辑:从信息洪流到结构化输出 每天早上七点,我的自动化流程会准时跑完一轮信息采集。到八点,一份完整的AI日报已经躺在我的笔记系统里,包含过去24小时内全球AI领域最值得关注的动态、论文、产品更新和行业观点…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬