ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

BP神经网络自整定PID控制仿真:从原理到Simulink实现与调参

BP神经网络自整定PID控制仿真:从原理到Simulink实现与调参 简介基于BP神经网络的自整定PID控制仿真实验文档面向控制工程、自动化及人工智能方向的学习者与研究者。文档完整阐述了BP神经网络的结构特征、学习算法以及神经网络自整定PID控制器的工作原理通过引入神经网络在线学习能力实时调整Kp、Ki、Kd三个PID参数有效克服传统PID控制器难以适应被控对象参数时变的局限性。资源为1个doc格式文件压缩包大小291KB适合在Matlab环境下对照仿真程序逐步实践帮助读者掌握4-5-3型BP网络的结构设计、学习速率与惯性系数的选取、梯度下降修正权系数的实现细节并理解网络结构变化对控制效果的具体影响。文档内容涵盖实验目的、原理分析、详细步骤、完整代码及结果讨论结构完整可直接参考使用。已有1207人学习浏览适合正在学习智能控制、神经网络应用或开展相关课程设计的高年级本科生及研究生使用。1. 基于BP神经网络的自整定PID控制仿真这个方向到底在解决什么问题把基于BP神经网络的自整定PID控制仿真拆开看这是一套典型的智能控制入门方案外层是经典PID闭环内层是一个BP神经网络每一拍根据误差在线调整kp、ki、kd三个参数。很多做电机调速、温度控制、过程控制的工程师会遇到这个场景——对象参数一变化固定PID就压不住超调或者响应变慢而BP自整定的卖点就是参数跟着工况走。这篇文章从原理、Simulink搭建、可复制的m函数代码到调参顺序和踩坑记录全部摊开适合马上要做仿真验证、课程设计或准备把这套算法搬上实物的从业者。不需要多深的神经网络基础会写m函数、会摆Simulink模块就能照做。2. 整定原理BP网络如何一点一点把PID参数推到位要复现这套仿真先把两个核心概念焊死增量式PID和BP网络的在线权值更新。外层是PID控制回路内层是BP网络在每一拍给出一组新的kp、ki、kd。这里有个容易误解的地方——网络并不是去拟合一张最优PID参数表而是通过梯度信息沿着让误差平方变小的方向实时调整输出。整个更新过程不依赖人工规则所以它属于自整定而不是传统的试凑法或齐格勒-尼科尔斯整定。2.1 网络的三个输入节点如何映射出kp、ki、kd先写增量式PID的控制律u(k) u(k-1) kp·x1 ki·x2 kd·x3其中x1、x2、x3不是随意取的它们和PID三项一一对应输入节点表达式PID语义x1e(k) - e(k-1)比例项驱动源反映当前变化x2e(k)积分项驱动源消除稳态偏差x3e(k) - 2e(k-1) e(k-2)微分项驱动源体现变化趋势这三个变量直接作为BP网络的输入层节点。如果你用bp神经网络结构图这个关键词去搜看到的绝大多数是输入层-隐含层-输出层的标准三层结构映射到这个方案里输入层就是x1、x2、x3再加一个常数偏置输出层就是kp、ki、kd三路。网络中间层的激活函数一般用tansig输出层用sigmoid。sigmoid把输出压到(0,1)区间为了保证三个PID参数始终为正再乘一组放大系数kp kp0 · o1ki ki0 · o2kd kd0 · o3这里的kp0、ki0、kd0就是PID的基准初值网络只负责在基准附近微调而不是从零开始无中生有生成参数。这个设计几乎是决定仿真能不能跑稳的第一个关键点如果让网络输出直接当PID参数初始权值稍微不合适前三拍就会把控制量打飞。权值更新沿用的是BP最经典的梯度下降思想。性能指标取E(k) 0.5·e(k)²网络输出经过映射进入Δu所以Δu对输出层每个节点输入的偏导可以写成∂Δu/∂net1 kp0 · o1·(1-o1) · x1∂Δu/∂net2 ki0 · o2·(1-o2) · x2∂Δu/∂net3 kd0 · o3·(1-o3) · x3再通过链式法则反向传播到隐含层。唯一的问题是∂y/∂u未知工程上的常规做法是先用符号函数sign(∂y/∂u)代替只保证更新方向正确幅度误差靠学习率来消化。这就是为什么后面代码里会留一个obj_sign参数。2.2 增量式PID与在线梯度更新为什么这套结构稳定位置式PID的积分项是全部历史误差的累加如果BP参数在某一拍突然跳一下累加结果会出现一个持续的偏置要花很长时间才能慢慢消掉。增量式只有当前拍的增量参数抖动带来的影响是局部的下一拍参数恢复正常后输出也就跟着恢复正常。BP在线训练过程中权值天然会小幅度抖动所以工程上几乎都用增量式。这也是你搜索pid算法、pid调速这类词时绝大多数BP自整定资料都拿增量式开刀的原因。对比一下另一个常见方案模糊PID模糊PID靠预置规则表规则覆盖不到的工况输出质量没有保证。BP-PID不需要规则表代价是网络结构、学习率都需要人为设定训练过程在别人眼里像黑匣子。不过在仿真阶段BP的上手成本其实更低——改网络结构只是一个数字而重新设计模糊规则表的工作量明显更大。这套方案还有一个容易忽略的细节它是完全在线训练。BP网络在控制过程中每一拍都做一次前向计算和一次反向更新不是先离线训练好再放上去跑。在线训练的好处是对象参数漂移后网络能自己追回来坏处是收敛稳定性更依赖学习率和初值。后面第5章要讲的很多翻车现场根源都在这里。3. 把仿真搭起来Simulink模型与可复制的整定函数原理讲清楚之后动手搭模型。这里给一个最小可跑的Simulink闭环模块少到你能在一小时之内从零搭完。被控对象先用线性二阶系统顶住G(s) 1/(s² 2s 1)这是最经典的验证床阻尼临界、无纯延迟网络学习压力小。如果连这个对象都整定不漂亮先别急着上高阶或非最小相位系统。3.1 最小Simulink模型六个模块搭一个闭环先看模块清单模块作用关键参数Step参考输入Step time 0Final value 1Sum误差计算符号设置为 -Transfer Fcn被控对象Numerator [1]Denominator [1 2 1]Zero-Order Hold离散-连续接口Sample time 1e-3MATLAB FunctionBP自整定PID控制器输入e输出uSample time 1e-3Scope观察y和u负载端口即可信号连接顺序是Step出来接Sum的正端被控对象输出y接Sum的负端Sum的输出就是误差e。e进MATLAB Function函数输出u经过Zero-Order Hold后进Transfer FcnTransfer Fcn的输出再分两路一路回Sum一路进Scope。注意MATLAB Function必须要设置采样时间不要让它继承。因为函数内部有persistent状态变量是按拍更新的如果被当成连续模块处理Simulink会报采样时间冲突或者干脆在仿真中产生代数环。设置成1e-3后控制律每1毫秒更新一次被控对象在Simulink里仍然按连续方式求解。3.2 可直接复制的BP-PID控制器代码把下面这段代码完整复制到MATLAB Function模块里输入名是e输出名是u函数名保持bppid_controllerfunction u bppid_controller(e) % BP神经网络自整定PID控制器增量式 % 固定网络结构输入43个误差特征1偏置隐含层5输出层3 persistent e1 e2 u_prev W1 W2 dW1 dW2 if isempty(e1) e1 0; e2 0; u_prev 0; % 权值初始化为(-0.1, 0.1)的小随机数 W1 (rand(5, 4) - 0.5) * 0.2; W2 (rand(3, 5) - 0.5) * 0.2; dW1 zeros(size(W1)); dW2 zeros(size(W2)); end % 三个误差特征与增量式PID三项一一对应 x [e - e1; e; e - 2*e1 e2; 1]; % 最后一位1是偏置输入 xn x ./ (1 abs(x)); % 工程归一化防止误差量纲差异过大 % 隐含层tansig激活函数 h_in W1 * xn; h 2 ./ (1 exp(-2 * h_in)) - 1; % 输出层sigmoid激活函数把输出压到(0,1) o_in W2 * h; o 1 ./ (1 exp(-o_in)); % 基准PID初值网络只在初值附近微调 kp0 1.0; ki0 0.5; kd0 0.1; kp kp0 * o(1); ki ki0 * o(2); kd kd0 * o(3); % 增量式PID控制量 du kp * (e - e1) ki * e kd * (e - 2*e1 e2); u u_prev du; % ---- 权值在线更新近似梯度 ---- obj_sign 1; % 对象Jacobian符号增益为正填1为负填-1 % 输出层每个节点对控制量的近似贡献 g1 kp0 * o(1) * (1 - o(1)) * (e - e1); g2 ki0 * o(2) * (1 - o(2)) * e; g3 kd0 * o(3) * (1 - o(3)) * (e - 2*e1 e2); delta_out obj_sign * e * [g1; g2; g3]; lr 0.05; % 学习率整定不稳定就往0.01以下调 alpha 0.03; % 动量因子 % 输出层权值更新 dW2 lr * delta_out * h alpha * dW2; W2 W2 dW2; % 隐含层反向误差tansig导数为1-h^2 delta_h (W2 * delta_out) .* (1 - h.^2); dW1 lr * delta_h * xn alpha * dW1; W1 W1 dW1; % 保存上一拍状态 e2 e1; e1 e; u_prev u;逻辑上有两个点需要说明。第一控制量u在权值更新之前就算完了保证本拍输出不受本拍权值更新的影响否则会出现参数边算边用的耦合抖动。第二xn的归一化是x除以1|x|这是工程上非常实用的处理。误差在过渡过程初期可能很大不归一化的话梯度会被误差的绝对值放大权值一步跳出去就收不回来了。代码里kp0、ki0、kd0、lr、alpha、obj_sign这六个量是主要可调参数。obj_sign需要根据被控对象的增益极性设置如果u增大导致y增大填1如果对象是反向特性比如某些加热器用占空比控制却接了制冷负载填-1。仿真阶段遇到的大部分参数越调越乱都和这些量的初始搭配有关。3.3 先固定PID验证再开BP推荐的第一步跑通顺序不要第一次就把BP代码塞进去直接仿真。我一般按三步走第一步把MATLAB Function里的内容临时替换成固定增量式PID比如kp1.0、ki0.5、kd0.1确认Simulink模型本身没搭错阶跃响应能稳定第二步把固定PID换回上面的BP代码保持kp0、ki0、kd0和刚才的固定值一致跑一次阶跃仿真看Scope里的y曲线和固定PID差多少第三步把学习率先调到0.01跑一遍再逐步往上加。为什么这样走因为BP-PID的初始权值是随机的网络在最初的几拍里很可能输出一个和kp0差距较大的参数。如果模型连固定PID都不稳你根本分辨不清是模型问题还是BP更新问题。固定PID相当于给整个链路设置了一个基线后面BP有没有改善、改善多少一眼就能从超调量和调节时间上看出来。4. 五个必调参数网络结构、学习率与初值映射的取舍仿真能跑起来之后接下来就是调参。这个方案的调参自由度比普通PID多一层因为除了PID本身的特性还多了网络结构和学习率。如果不理清楚哪些参数先动、哪些参数后动很容易陷入越调越乱的循环。下面按优先级从高到低讲。4.1 网络结构选择4-5-3是怎么定下来的代码里的网络结构是输入4、隐含层5、输出3。输入4的含义是三个误差特征加一个常数偏置。为什么输入不直接用3个节点因为偏置能够给隐含层提供一个可调节的阈值少了它网络在误差全为零时输出仍然可能不对称稳态阶段容易出现参数漂移。偏置在代码里由x的最后一维1实现权值W1里对应列就学习到了偏置量。隐含层5个节点是经验值。节点少了网络拟合能力不足碰上非线性稍强的对象误差降不下去节点多了比如到15到20权值数量大幅增加在线训练时容易过拟合而且参数抖动明显。对于大多数二阶、三阶线性对象4到8个隐含层节点足够。如果后续对象是非线性的可以加到8但学习率通常要同步调低。输出层3个节点对应kp、ki、kd激活函数用sigmoid是为了保证参数非负。还有一种方案是输出层用线性激活函数让网络可以输出负参数但初值设置非常难而且PID参数出现负值后系统可能瞬间发散不推荐在仿真入门阶段使用。4.2 五个必调参数的取值范围与影响这里给一张实用参数表数值范围来自我跑过的二阶对象和常见电机对象的经验参数建议范围常见取值影响隐含层节点数4 ~ 85太少欠拟合太多参数抖动学习率lr0.005 ~ 0.20.05过大震荡过小收敛慢动量因子alpha0 ~ 0.10.03平滑权值轨迹太大容易过冲采样周期Ts对象最快时间常数的1/10 ~ 1/201e-3过大导致控制质量下降PID基准初值kp0/ki0/kd0按对象试凑1.0/0.5/0.1决定网络工作点最重要采样周期这一项容易被忽略。上面的代码里Ts1e-3是因为对象G(s)1/(s²2s1)的自然频率约为1 rad/s时间常数在秒级1ms采样已经足够密。如果你把对象换成电机电流环时间常数是毫秒级Ts就要降到0.01ms量级否则离散化带来的滞后会让BP网络完全学不到正确的梯度方向。PID基准初值是这里最值得花时间的参数。我的习惯是先用固定PID把kp0、ki0、kd0调到阶跃响应基本能看的程度——超调不超过30%、稳态无静差然后再开BP。基准初值直接决定了网络输出的工作点比如kp01那么网络输出o1在0.5附近时实际kp约为0.5网络只是在0到1之间微调。如果你把kp0给成10一开始网络输出0.5都可能让系统发散。4.3 调试顺序先动学习率再动初值最后动结构参数一多最容易犯的错误是同时改好几个变量最后出了问题根本定位不到原因。我现在遵循的调试顺序是先动学习率再动PID基准初值最后才动网络结构。具体来说第一次跑BP如果响应曲线剧烈震荡优先把lr从0.05降到0.01甚至0.005震荡基本都会缓解。如果降了学习率之后还是震荡再检查kp0、ki0、kd0是否过大把kp0减半试试。只有当这两种手段都调完、响应仍然不满意时才考虑把隐含层节点从5改到8或者调整归一化方式。网络结构和激活函数属于低频变量不应该作为日常调参手段否则你永远分不清问题是出在算法还是出在结构。注意bp神经网络自整定PID并不是一次仿真就能收敛到理想值。在线训练的性质决定了参数会一直小幅波动只要波动幅度不引起输出明显抖动就是正常现象。5. 仿真调试避坑参数乱跳、震荡与跑不通的常见原因这一章全是实操中常见的翻车现场。每条按现象、原因、解决的顺序写方便你遇到问题时直接对照排查。5.1 收敛与震荡类问题现象1Scope里PID参数曲线像锯齿控制量u大幅摆动甚至比固定PID还差。原因学习率过大或者误差特征没有归一化。过渡过程初期误差很大梯度乘以误差后一步就会把权值推到一个极端位置导致下一拍参数剧烈跳变。解决把lr从0.05下调到0.01同时在代码中确保xn的归一化保留。也可以给kp、ki、kd输出加限幅比如限制在基准值的正负50%以内这一招在实物调试时几乎是必备的仿真阶段能少很多噪音。现象2稳态误差一直存在e已经很小了但三个PID参数还在缓慢漂移。原因输出层sigmoid接近饱和。当网络输出o接近0或接近1时sigmoid导数o(1-o)几乎为零权值更新基本停滞而此时的PID参数可能被卡在基准值乘以接近1的区间内。解决检查kp0、ki0、kd0的取值是否让网络输出长期工作在饱和区。如果kp0偏大网络输出0.2时实际kp就已经很大后续想通过减小o来降低kp却发现梯度几乎为零。把kp0调小让网络输出更多停留在0.3到0.7之间的活跃区间。现象3同一个网络结构每次跑的结果差异很大换一组随机初始权值就翻车。原因BP在线训练本质上是局部搜索初始权值落在哪个位置决定了最后爬到哪个局部极小点。解决把W1、W2的初始化范围从(-0.1, 0.1)缩小到(-0.05, 0.05)同时提高动量因子到0.05左右。如果项目条件允许先离线预训练一组权值作为在线初值这是第6章要展开的两段式训练思路。5.2 Simulink工程类问题与参数迁移问题现象4MATLAB Function报代数环错误或者仿真速度慢到无法忍受。原因最常见的是MATLAB Function没有设置采样时间被Simulink当成连续模块处理还有一种情况是反馈路径上存在瞬时依赖导致求解器反复迭代。解决先在MATLAB Function参数里把Sample time固定为1e-3若仍然报警在y反馈到Sum的路径上加一个Unit Delay让反馈值比控制量晚一拍进入误差计算代数环就断了。注意加了Unit Delay后闭环会多出一拍延迟kp0、ki0、kd0可能需要稍微调大。现象5换一个被控对象后同样的参数完全跑飞。原因采样周期和PID基准初值都是跟着对象走的。比如把二阶对象换成带延迟的温度对象时温度回路时间常数大、延迟明显Ts1e-3会让积分项几乎不起作用而微分项会对噪声特别敏感这就是常说的温度PID波动温差大。解决先估算对象的最快时间常数把Ts调整到它的1/10到1/20之间。然后重新试凑kp0、ki0、kd0不要沿用上一个对象的数值。对温度这类大惯性对象kd0通常要取得很小甚至可以先置零。注意仿真里BP参数不收敛不一定都是BP的锅。先看被控对象本身是否在这个采样周期下可控再看固定PID能不能稳定。很多BP不收敛到最后发现是对象离散化错了。6. 从仿真到可信结果两段式训练与三个验证指标仿真跑通只是第一步真正的价值在于结果可信、可复现、能迁移。这一章给两个实战技巧和一个验证套路都是我反复用过的方案。6.1 两段式训练离线给初值在线微调最稳妥的做法是先离线后在线。离线阶段固定一组典型输入信号比如阶跃叠加正弦关闭权值更新让网络只做前向计算把误差积累到足够大后再用批量数据训练出一组W1、W2作为在线仿真的初始权值。在线阶段把学习率降到0.01让网络在好的初值附近微调。这一步能避开大量随机初始化翻车。如果把这套算法搬上实物我强烈建议把BP整定放到慢回路。控制周期内保持kp、ki、kd不变每隔几十拍才让BP网络更新一次参数底层仍然用增量式PID跑快回路。这样网络计算耗时再长也不影响控制频率整定过程也更平稳。6.2 三个验证指标ITAE、超调量、调节时间不要只盯着Scope曲线看个大概。把误差和仿真时间保存到工作区用三个指标判断好坏function [ITAE, overshoot, settling_time] eval_response(t, y, r_final) dt t(2) - t(1); e r_final - y; ITAE sum(abs(e) .* t) * dt; overshoot max(0, (max(y) - r_final) / r_final * 100); idx find(abs(e) 0.02 * r_final, 1, first); settling_time t(idx); endITAE对长时间的小误差敏感适合判断稳态精度超调量看动态品质调节时间看收敛速度。三个指标一起看才能说明BP自整定比固定PID好在哪里。比如调节时间从3秒降到1.5秒超调从25%降到8%这就是能写进报告里的硬结论。我现在每次搭这种BP-PID仿真第一件事仍然是先固定PID把对象跑顺再开BP。这个顺序帮我省掉了不知道多少次参数越调越乱的血泪时间。先建立基线再谈智能算法的增量价值这个习惯到现在还在用。希望帮到你。本文还有配套的精品资源点击获取
返回列表