尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

强化学习与控制论:从Bellman方程到值迭代的工程落地

强化学习与控制论:从Bellman方程到值迭代的工程落地 「强化学习与控制论」这个标题近年来频繁出现在机器人控制、自动驾驶决策、工业过程优化和各类学术综述里。对传统控制工程师来说强化学习像是一套用数据训练出来的黑盒对机器学习开发者来说控制理论又像是一堆需要重新补课的微分方程、稳定性和实时性约束。实际上两者共享同一个数学底座动态规划与最优性原理。这篇内容会从概念映射、Bellman 方程与最优控制的关系、模型已知与模型未知的分野展开再用一个只用 numpy 实现的离散值迭代案例把强化学习思路真正落到一个控制问题上最后讨论实机部署时的工程检查点与排查链路。适合正在做机器人控制、自动驾驶决策或者想从纯算法走向真实系统的开发者阅读。1. 强化学习与控制论为什么值得放在同一套知识体系里看1.1 两个领域都在解决同一个问题序列决策先看一个最简单的场景有一个系统它在每个时刻处于某个状态x决策者可以施加一个输入u系统按照动力学方程转移到下一个状态。决策者的目标是在一段时间内让某个累计指标最优。控制理论把它叫做“状态反馈控制”强化学习把它叫做“策略优化”。说法不同但是结构完全一致控制理论关心给定模型如何设计控制律使得闭环系统稳定、快速、鲁棒。强化学习关心没有完整模型时如何通过与环境交互收集数据学到一个策略使得累计奖励最大。传统控制擅长“已知模型下的强保证”强化学习擅长“复杂环境下的自适应”。过去几十年两者各自发展但底层的最优性原理是相通的。不理解这层联系控制工程师会误以为强化学习只是调超参机器学习工程师也会误以为控制理论只是调 PID。1.2 适合哪些读者需要哪些前置知识这篇文章的内容跨度比较大适合三类读者有控制理论背景想理解强化学习算法为什么有效的工程师。有机器学习背景想进入机器人、自动驾驶等控制场景的开发者。正在做课程设计或论文需要把动态规划、LQR、强化学习串起来的学生。前置知识不需要太多但建议先掌握三点基础线性代数矩阵运算、向量范数能看懂状态空间表达式。一门编程语言的基础文章中的示例使用 Python依赖只有 numpy。对“系统状态随时间演化”的基本直觉不需要严格证明能力。如果完全没接触过控制理论也不影响阅读前几章只需要把“状态”理解为“系统当前情况的数值描述”把“控制输入”理解为“你对该系统施加的动作”。1.3 这篇文章的技术主线这条主线是一个最小控制问题一阶离散时间系统状态是标量控制输入是标量目标是让状态尽快回到零附近同时控制量不要过大。为了说清楚问题会先用经典的最优控制方法 LQR 解一遍然后用强化学习中常用的值迭代再解一遍。你会发现两者的结果在数值上非常接近而且它们收敛到的是同一个不动点方程。接下来再把问题延伸到工程实际模型未知怎么办、实机部署要补哪些能力、控制周期抖动怎么排查。读完这篇文章你能得到一张可复用的概念映射表、一份可运行的 numpy 代码、一份实机部署前的检查清单以及一套从现象倒推原因的控制闭环排查顺序。2. 先统一语言状态、动作、策略与控制律的对应关系2.1 强化学习视角MDP 五元组强化学习的标准建模框架是马尔可夫决策过程通常写成五元组S状态集合系统中的所有可能状态。A动作集合决策者可以在每个状态执行的动作。P状态转移概率描述执行动作后系统转移到下一个状态的概率分布。R奖励函数表示在某个状态执行某个动作后获得的即时奖励。gamma折扣因子0 到 1 之间的数用来权衡未来奖励的重要性。智能体的目标是找到一个策略pi(a|s)使得累计折扣奖励的期望最大化G_t r_t gamma * r_{t1} gamma^2 * r_{t2} ...这里的核心假设是马尔可夫性下一时刻的状态只依赖当前状态和当前动作不依赖更早的历史。这个假设和控制理论中的“状态足以描述系统未来演化”是同一个意思。2.2 控制视角状态方程与代价函数控制理论的建模语言通常是确定性或带噪声的状态方程x_{t1} f(x_t, u_t)其中x_t是 t 时刻的系统状态u_t是 t 时刻的控制输入。设计目标是通过选择控制律u pi(x)来最小化累计代价J sum_{t0}^{∞} c(x_t, u_t)在状态空间模型中如果系统是线性的方程就写成x_{t1} A x_t B u_t代价函数最常见的形式是二次型c(x, u) x^T Q x u^T R u其中Q是状态权重矩阵R是控制权重矩阵。一个直觉理解是Q越大系统越急于把状态压回零R越大系统越不愿意用大控制量。2.3 一条完整的概念映射表把两套术语放在同一张表里后面阅读代码和文献时会轻松很多强化学习术语控制理论术语说明状态s状态x都表示系统当前情况的完整描述动作a控制输入u都是决策者施加给系统的量策略 pi(as)控制律u pi(x)奖励r(s,a)负的代价-c(x,u)一个最大化一个最小化折扣因子gamma折扣代价/终端权重权衡当前与未来的重要性状态转移 p(ss,a)动力学f(x,u)价值函数V(s)代价函数J(x)都是从当前状态出发的累计指标Q 函数Q(s,a)代价对输入的依赖评估“状态-输入”组合的长期效果这张表最重要的信息是策略和控制律是同一个对象价值函数和代价函数是同一个对象。后面所有数学推导其实都是围绕这些概念展开的。2.4 奖励与代价符号不同本质相同很多人第一次接触两个领域时会被“最大化奖励”和“最小化代价”弄混。最简单的方法是记住把奖励取负号就变成了代价。一个强化学习问题总可以改写成等价的控制问题只要把奖励函数变成负的代价函数。但有一点要注意奖励函数的设计会直接影响最优策略。如果只是给奖励乘以一个正的常数最优策略不变但如果把折扣因子、奖励塑形项改掉最优策略可能完全不同。实际项目中奖励函数写不好后面所有训练都是在错误的优化目标上打转。3. 动态规划是两个领域共同的数学底座3.1 Bellman 最优方程强化学习的核心方程是 Bellman 最优方程。它描述的是一个状态的最优价值等于“当前最优动作带来的即时奖励加上未来状态的最优价值的折扣期望”。V*(s) max_a [ r(s, a) gamma * sum_{s} p(s|s,a) * V*(s) ]这个方程之所以重要是因为它把一个无限时域问题拆成了“当前一步 剩余问题”的递归结构。只要方程成立就可以通过迭代求解这就是值迭代的思想。Q 函数是另一种等价写法它直接评估“在状态 s 先执行动作 a之后按最优策略行动”的价值Q*(s, a) r(s, a) gamma * sum_{s} p(s|s,a) * max_{a} Q*(s, a)强化学习算法中常见的 DQN、SARSA、Q-learning本质上都是在逼近这个 Q 函数。3.2 最优控制中的 HJB 与 Riccati 方程控制理论中的最优控制同样建立在这个递归思想上。连续时间版本是 Hamilton-Jacobi-Bellman 方程离散时间版本则可以写成 Bellman 方程的形式。对一个离散时间线性系统x_{t1} A x_t B u_t代价函数取二次型时最优价值函数是二次型V(x) x^T P x把V(x)代入 Bellman 方程经过推导就得到离散代数 Riccati 方程P Q A^T P A - A^T P B (R B^T P B)^{-1} B^T P A解出P之后最优控制律是线性状态反馈u -K x K (R B^T P B)^{-1} B^T P A这就是 LQR 的全部内容。关键点在于Riccati 方程只是 Bellman 方程在线性二次型这个特殊场景下的解析解。理解了这层关系就明白为什么很多强化学习论文喜欢拿 LQR 作为标准测试问题因为它有闭式解可以验证算法是否收敛到了正确结果。3.3 最小可运行案例一阶离散系统下面用一个最简单的系统把上面的联系跑通。考虑一阶离散系统x_{t1} x_t dt * (alpha * x_t u_t)其中alpha 0.5表示这个系统本身是轻微不稳定的dt 0.1是采样周期。目标是让状态尽快回到零同时控制尽量小代价函数取c(x, u) x^2 0.1 * u^2运行环境只需要 Python 和 numpypython -m venv .venv source .venv/bin/activate pip install numpy这段代码不依赖 gymnasium 等强化学习库目的是让你看清动态规划和最优控制共享的计算过程。3.4 用值迭代求解控制问题把状态空间离散成网格把控制输入离散成有限集合然后用值迭代求最优策略import numpy as np dt 0.1 alpha 0.5 def f(x, u): # 离散时间状态方程 return x dt * (alpha * x u) def cost(x, u): # 每步代价状态惩罚加控制惩罚 return x * x 0.1 * u * u # 状态网格从 -3 到 3共 121 个点 states np.linspace(-3.0, 3.0, 121) # 动作网格从 -2 到 2共 21 个点 actions np.linspace(-2.0, 2.0, 21) gamma 0.95 max_iter 5000 tol 1e-6 V np.zeros(len(states)) policy np.zeros(len(states)) def index_of(x): # 把连续状态映射到最近的网格下标 return int(np.clip(np.searchsorted(states, x), 0, len(states) - 1)) for it in range(max_iter): V_new np.zeros_like(V) policy_new np.zeros_like(policy) delta 0.0 for i, x in enumerate(states): best_val np.inf best_u actions[0] for u in actions: xn f(x, u) j index_of(xn) val cost(x, u) gamma * V[j] if val best_val: best_val val best_u u V_new[i] best_val policy_new[i] best_u delta max(delta, abs(best_val - V[i])) V, policy V_new, policy_new if delta tol: print(fvalue iteration converged at iteration {it 1}) break这段代码的逻辑很直白对每个网格状态遍历所有候选动作。用状态方程预测下一个状态。用“即时代价 折扣后的未来价值”评估这个动作。选择评估值最小的动作作为该状态的最优动作。重复直到价值函数稳定。运行后会看到类似输出value iteration converged at iteration 562收敛后用策略做一次状态轨迹仿真def rollout(x0, steps40): x x0 traj [] for _ in range(steps): i index_of(x) u policy[i] traj.append((x, u)) x f(x, u) return traj traj rollout(1.5) for k, (x, u) in enumerate(traj[:6]): print(fstep {k}: x{x:.3f}, u{u:.3f})预期输出类似step 0: x1.500, u-1.400 step 1: x1.365, u-1.200 step 2: x1.235, u-1.200 step 3: x1.114, u-1.000 step 4: x1.001, u-0.800 step 5: x0.891, u-0.800可以看到状态逐步回零控制量也逐步减小。这就是一个最简单的“强化学习思路解决控制问题”的完整闭环定义状态与动作、定义代价、用经验迭代逼近最优价值、用价值函数生成策略、在环境中滚动验证。3.5 值迭代结果与 LQR 增益的对比现在用 LQR 解同一个问题。系统的离散状态空间参数为A 1 alpha * dt 1.05 B dt 0.1 Q 1 R 0.1用 Riccati 迭代求解A np.array([[1.0 alpha * dt]]) B np.array([[dt]]) Q np.array([[1.0]]) R np.array([[0.1]]) def solve_dare(A, B, Q, R, max_iter10000, tol1e-12): P Q.copy() K np.zeros((B.shape[1], A.shape[0])) for _ in range(max_iter): K np.linalg.solve(B.T P B R, B.T P A) P_new A.T P (A - B K) Q if np.max(np.abs(P_new - P)) tol: break P P_new return K, P K, P solve_dare(A, B, Q, R) print(LQR gain K:, K[0, 0])运行后得到LQR gain K: 3.535在值迭代中控制量是在离散动作网格上选择的。状态x 0.4附近LQR 给出的控制量约为-3.535 * 0.4 -1.414而值迭代动作网格中距离最近的是-1.4。两者几乎一致。需要说明一个细节值迭代使用了折扣因子gamma 0.95经典 LQR 通常写不带折扣的形式所以数值不会完全相等但策略趋势和数量级高度一致。这已经足够验证一个核心结论在线性二次型场景下强化学习算法通过数据迭代逼近的正是最优控制理论给出来的解析解。4. 模型已知与模型未知两种工作方式的本质分野4.1 有模型方法先建模再设计控制理论主流的做法是先建立系统模型再基于模型设计控制器。LQR、MPC、极点配置都属于这一类。它们的共同优势是样本效率极高因为优化过程直接利用了模型信息不需要大量在线试错。有模型方法的代价是模型必须足够准确。如果建模有偏差设计出来的控制器可能不稳定或者性能明显下降。实际工程中摩擦、间隙、负载变化、温度漂移都会造成模型失配所以控制工程师还要花大量精力做鲁棒性分析和参数辨识。4.2 无模型方法用数据逼近最优策略强化学习的主打场景恰恰是模型难以精确描述的任务。比如四足机器人在地形复杂的废墟中行走很难写出每一步的接触动力学再比如自动驾驶在城市路口决策也无法用一组微分方程描述所有参与者的行为。无模型方法通过与环境的大量交互直接用奖励信号反推策略。代价是数据需求非常大。一个简单的倒立摆任务DQN 通常需要几十万步交互才能稳定真实机器人一次走两步就摔倒收集训练数据的成本远高于仿真。因此无模型 RL 在真正的控制现场往往需要配合仿真环境、预训练和领域随机化使用。4.3 模型偏差、试错成本与稳定性保证两个领域还有一个关键差异稳定性和安全性保证。控制理论有 Lyapunov 方法、不变集、可达性分析等工具可以在设计阶段就证明闭环系统稳定或者给出状态不会越过安全边界的条件。强化学习默认没有这些保证策略是通过优化目标函数训练出来的训练数据覆盖不到的区域策略行为无法保证。这不是说强化学习不能用而是说直接把它当作黑盒部署到真实系统上风险很高。更务实的路线是用强化学习生成或优化策略再用控制理论的方法做约束、过滤和兜底。这也是后文“混合架构”的出发点。4.4 选型速查表维度有模型控制LQR/MPC无模型强化学习模型要求需要动力学模型不需要显式模型样本效率高直接利用模型低需要大量交互数据稳定性保证可通过理论分析获得默认没有需要额外措施对复杂非线性建模困难时受限有表达力能拟合复杂策略实时计算开销依靠在线优化代价随规模上升推理通常很快训练很慢适合场景模型清晰的工业控制、轨迹跟踪模型难写、任务复杂的决策场景主要风险模型失配导致性能下降数据覆盖不足导致分布外失效需要说明的是这两个阵营之间的边界正在被“基于模型的强化学习”和“学习型 MPC”逐渐模糊。真正做工程时不需要强迫自己站队而是根据任务特性选工具。5. 从仿真跑到实机控制RL 还缺哪些工程能力5.1 稳定性与安全约束控制理论给出的保障仿真环境里策略效果不好最多是重新训练实机上同样的失误可能撞坏设备或伤到人。所以在真实系统上部署强化学习策略之前至少要回答三个问题状态超出训练分布时策略会输出什么动作动作必须满足执行器限幅策略输出超限后怎么处理策略失效时有没有一个降级到安全控制器的机制常见做法是把安全逻辑放在策略外面形成一个独立的安全层。比如控制学里的“安全过滤器”通过在线优化找到“离策略输出最近但不违反安全约束”的控制量。这类方法保留了 RL 策略的表达能力同时把安全边界交给有理论保证的模块。5.2 采样效率与虚实差距真实机器人上跑策略一个 episode 只有几十秒失败一次就要人工复位数据采集成本极高。于是工程上几乎都会引入仿真训练再迁移到实机也就是 sim-to-real。迁移过程中的主要障碍是模拟器与真实物理之间的差距。常见的缓解手段包括领域随机化在仿真中随机化质量、摩擦、延迟等参数让策略见过更多情况。系统辨识先用真实数据校准仿真参数缩小 sim 与 real 的差距。在线微调实机部署后继续用少量安全交互更新策略。这些手段不是强化学习算法的内容但决定了一个策略能不能从仿真走到实机。很多团队算法调得没问题最后卡在 sim-to-real本质上是把工程问题误当成了算法问题。5.3 实时性与控制周期ROS 2 Control 场景控制系统的实时性要求和普通互联网服务完全不同。假设控制周期是 10 毫秒那么每个控制周期内必须依次完成读取传感器状态、运行策略推理、计算控制量、下发执行器整个链路不能超过 10 毫秒。如果策略是一个大型神经网络GPU 推理时间本身可能就超过周期预算再加上 Python 解释器、动态内存分配、日志打印带来的抖动很容易出现“控制循环错过期望频率”的问题。这类故障在 ROS 2 环境中尤为常见ROS 2 Control 的控制器管理器周期性调用 update()一旦 update() 内出现长时间阻塞控制周期就会漂移任务日志里会记录循环时间超标。排查这类问题时不要只盯着算法效果而要先确认控制循环是否真的按期望周期在跑。如果一个明明设计在 10 ms 周期内的控制器实际循环时间是 40 ms那么策略再优秀也会表现为系统发散。5.4 学习环境与生产环境对照表项目学习/仿真环境生产/实机环境数据来源模拟器可无限生成真实传感器成本高且有风险失败代价重置即可可能损坏设备或造成安全事故控制周期通常不严格仿真时间可调硬实时要求错过周期即异常模型准确性仿真模型已知真实系统存在模型失配安全冗余通常没有必须配备限幅、看门狗、降级控制器可观测性全状态可直接读取传感器噪声、缺失、标定误差复现性随机种子可控环境变化、硬件老化导致不可复现设计一个强化学习控制系统时建议一开始就把这张表的两列都写出来明确哪些假设只存在于仿真中哪些能力是实机必须补的。否则训练结果很好看部署时却处处踩空。6. 强化学习做控制时的四个典型坑6.1 奖励函数设计不当训不出来未必是算法问题奖励函数是强化学习的目标函数目标写错了后续所有工程努力都会被抵消。常见错误是奖励太稀疏。一个真实机器人如果只有“到达目标点给 1否则给 0”早期探索几乎得不到任何反馈训练会极其缓慢。直接加稠密奖励又容易引入误导性偏差比如“离目标越近奖励越高”在某些地形下会鼓励系统停在半路。推荐的做法是分成几步先用稠密、光滑的奖励快速训练出基本行为再逐步替换成稀疏但更接近真实任务的奖励最后一定要检查奖励曲线和策略行为是否匹配。如果奖励在涨但控制轨迹越来越离谱问题多半出在奖励定义本身。6.2 把策略当黑盒忽略物理边界有些团队把 RL 策略当作黑盒输入状态、输出动作不检查动作是否超出执行器范围也不检查状态是否处于训练分布内。这在仿真里问题不大因为环境会宽容处理非法值在实机上电机限幅、关节限位、最大加速度都是硬约束。策略输出 100 N 的力执行器只能给 10 N最后系统行为会完全偏离仿真预期。正确做法是在策略输出后加一层约束处理限幅、平滑、速率限制并且把这些约束同时放进训练环境里让策略在约束范围内学习。否则策略学到的行为依赖的是“未受限动作”的幻想世界。6.3 评估只看均值不看方差与尾部风险强化学习训练结果通常不是稳定的。同一组超参数不同随机种子训练出来的最终性能可能差异很大同一个策略在初始状态稍有扰动时轨迹也可能出现明显分叉。如果只看平均回报很容易错过高风险场景。比如一个自动驾驶策略平均成功率 98%但失败的 2% 全部集中在某类光线条件下这正是实机部署前最需要关注的部分。评估时建议至少记录三组数字多次种子的均值、标准差、最差分位数。同时把失败样本单独拉出来分析确认失败场景是否有共同模式。控制系统的验收标准通常不是平均性能而是最坏情况是否可接受。6.4 推理延迟挤压控制周期强化学习策略部署到实机后最常见的一类故障不是算法错了而是“算不过来”。神经网络推理速度不稳定GPU 推理在并发任务干扰下抖动CPU 推理在系统负载升高时变慢Python 层的内存管理也可能造成周期性卡顿。一旦推理时间超过控制周期控制循环就会错过期望频率系统表现为震荡或发散。解决思路分两层算法层压缩网络、模型量化、剪枝、用 TensorRT 或 ONNX Runtime 加速系统层把推理放到独立线程、设置周期任务优先级、增加看门狗并且在推理超时的情况下降级到备用安全控制器。6.5 四个坑的速查表坑典型现象根因检查方式处理建议奖励函数不当奖励上涨但行为异常优化目标偏离真实任务绘图查看状态轨迹与奖励分阶段设计奖励加入物理约束忽略物理边界实机表现与仿真差异大动作超限未处理记录策略原始输出和执行器实际输出训练环境与部署端都加限幅评估只看均值平均指标好但偶发失控分布外场景未覆盖按种子和初始状态分组统计记录最差分位数,单独分析失败样本推理延迟超周期控制循环错过期望频率推理耗时超过周期预算采集循环时间戳和推理耗时压缩模型,独立线程,加看门狗和降级策略7. 控制闭环出问题时按这条链路排查7.1 第一层输入输出链路是否正常控制闭环出问题先不要怀疑算法按从物理到算法的顺序检查。先用最小代价确认状态值是否合理、传感器是否有噪声或标定错误、执行器是否正常响应。具体做法是在系统上手动施加一个固定控制量观察状态变化是否符合预期。如果状态观测本身是错的再好的策略也没有意义。检查清单状态单位、方向、坐标系是否一致。状态是否经过滤波滤波延迟会不会过大。控制量下发到执行器之前是否经过了限幅或变换。手动开环测试给固定 u看 x 的变化是否符合物理直觉。7.2 第二层训练统计与奖励日志输入输出没问题再回头看训练环节。把训练时的奖励曲线、Q 值、策略动作分布和部署后的日志放在一起对比。如果部署后的动作分布和训练时差异很大通常是状态分布漂移即模型遇到了训练时没见过的状态。如果训练曲线本身震荡剧烈可能是学习率太大、奖励尺度不合适或者探索噪声过强。如果 Q 值异常大或异常小检查奖励是否归一化、网络结构是否匹配。这一步最忌讳直接改超参重新训练。先把问题定位到“训练
返回列表