十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

单神经元自适应PID:Hedd学习规则与Simulink仿真实践

单神经元自适应PID:Hedd学习规则与Simulink仿真实践 简介单神经元自适应PID有监督Hedd仿真资料包面向自动控制、智能算法方向的研究者与工程师聚焦传统PID在非线性、时变系统下参数整定困难的问题利用单神经元网络实现增益在线自整定并通过有监督方式优化权重更新。压缩包内共6个文件包括2个Simulink模型slx、2个MATLAB脚本m以及2个Word文档docx分别对应连续系统与离散系统的仿真实现、核心算法代码和理论说明。整个资源仅35KB轻量易用目前已有268人学习下载。通过该资源可快速掌握单神经元自适应PID的建模思路、有监督学习机制及硬件在环仿真验证方法适合课程设计、毕业设计或控制算法入门参考。1. 单神经元自适应PID用一个神经元替掉三个回路做电机转速、加热炉温度或者压力调节的工程师大多经历过同一个坎PID参数在现场调得好好的工况一变超调就回来重新整定又得折腾半天。传统自适应控制理论漂亮可真落到项目里模型辨识还没做完交付周期已经撑不住了。单神经元自适应PID正好卡在这个缝里——它只有一个神经元三个权值对应PID的P、I、D三路增益靠有监督Hedd学习规则在线修正不依赖对象模型Simulink里搭一个仿真半小时内能跑通。下面把这个仿真拆开讲控制器结构怎么连、Hedd学习规则怎么写、参数怎么定、发散时先查哪里最后给一套可以反复用的验证脚本。2. 单神经元PID的结构设计与有监督Hedd学习规则2.1 神经元先替PID干一次加权求和传统PID的输出是一组固定系数的组合比例项压当前误差积分项消静差微分项预测误差趋势。单神经元PID做的事情在数学形式上几乎一样只是把三个固定增益换成了神经元的三个权值。输入 x1、x2、x3 分别接误差、误差积分、误差微分输出是三个输入对权值的加权和。权值在每拍闭环结束后更新一次等效的 Kp、Ki、Kd 随着工况在线变化这就是“自适应”三个字的来源。这个结构只有一个节点计算量小到可以在STM32这类单片机上实时跑裸机控制里加一个定时器中断就能执行。无人机串级PID中内环参数难以手工整定常见的做法也是把内环PID换成单神经元自适应PID外环仍然用普通PID让内环自己适应姿态变化。相比级联PID需要靠经验给内环定参数单神经元的优势是不需要被控对象模型只需要误差和输入输出信号天然适合模型不清楚、参数会漂移的现场回路。为什么不做多层神经网络多层网络需要训练数据或者观测器收敛时间不可控在实时控制回路里一个S函数延迟都可能引起振荡。单神经元本质上是把“神经网络控制”裁剪到只剩一个可学习节点保留了在线调整能力去掉了训练开销。这也是这类方案在工程仿真里反复被拿出来对比的原因。2.2 有监督Hedd规则误差拿来做监督信号Hedd学习规则可以理解为Hebb思想加监督信号Hebb学习强调“一起激活的连接要增强”而这里权值更新的依据不是单纯的相关性而是闭环误差 e(k)。误差小的时候权值基本不动误差大的时候权值朝使误差减小的方向修正。这样控制器会在运行中自动找回合适的增益组合。我使用如下形式的权值更新式wi(k1) wi(k) eta(i) * e(k) * du(k) * xi(k)其中 wi(k) 是第 i 路权值eta(i) 是对应学习率e(k) 是当前误差du(k) 是控制器输出增量xi(k) 是第 i 个输入。乘上 du(k) 的目的是把控制动作的方向也作为监督信号如果误差为正而控制器输出在减小说明这个方向的调整不利于消除误差权值就会被反向修正。有些实现把 du(k) 换成误差变化量 e(k)-e(k-1)两种写法在慢对象上收敛效果接近但带 du 的形式在对象存在纯滞后时更稳定因为控制增量的变化比误差变化更早反映执行机构的状态。学习率 eta 分三路设置而不是共用一个值。比例路学习率影响响应速度积分路学习率影响静差消除微分路学习率影响阻尼统一用一个值很容易出现“上升变快了但高频抖动也来了”的尴尬情况。这个细节在后面的参数表里展开。2.3 增量式输出与三路输入的定义单神经元PID输出采用增量式结构du K * sum(wi .* x); % 神经元输出增量 u u du; % 对控制量累加x 的三路输入定义为x1 e(k); % 比例项信息 x2 e(k) x2_prev; % 积分项累加 x3 (e(k) - e_prev) / Ts; % 微分项近似用增量式而不是位置式有一层实际考虑位置式输出直接给执行机构一旦积分项累积失控控制量会一次性跳变增量式每一拍只输出变化量即使丢掉一两拍执行机构也能维持上一拍的位置对带阀门的机构更友好。下面是这套控制器的主要参数清单后续仿真里的初值都从这张表出发。参数含义初值参考K神经元输出增益整体放大系数0.11.0eta(1)比例路学习率0.050.4eta(2)积分路学习率0.020.2eta(3)微分路学习率0.010.3wi三个权值初值0.1 左右Ts采样周期对象时间常数的 1/101/203. 用Simulink和m脚本搭一套可复现的有监督Hedd仿真3.1 Simulink各模块的连接与求解器设置常见做法是在Simulink里搭一个固定步长离散仿真模块连接顺序是Step信号源进入Sum块做误差计算误差三路分别接入MATLAB FunctionMATLAB Function输出控制增量du经过Unit Delay模块和一个Sum累加得到实际控制量u之后接Saturation限幅再传给被控对象模型对象输出反馈回Sum形成闭环另外分一路到Scope观察响应曲线。启动仿真第一件事不是改参数而是设置求解器。在Model Settings里把求解器类型从Variable-step改成Fixed-step求解器选discreteFixed-step size填0.01。如果不改变步长求解器会在一个控制周期内多次调用MATLAB Function权值在同一拍里被更新很多次等效学习率被放大几十倍结果就是仿真发散——这不是算法问题是求解器配置问题很多单神经元PID仿真“跑不起来”都是这个原因。MATLAB Function内部接口可以这样组织输入是误差及其积分微分输出是增量权值用persistent变量保持function du snpid_block(e, ei_sum, ed, p) % p.K 神经元增益p.eta(1:3) 三个学习率 persistent wi if isempty(wi) wi [0.1 0.1 0.1]; end x [e, ei_sum, ed]; du p.K * (wi * x); % 有监督Hedd权值更新 wi wi p.eta .* e .* du .* x; wi min(max(wi, -5), 5); % 限幅 end这里把权值限幅直接写进了函数避免在参数面板里额外接模块。du作为增量输出外部再用Unit Delay累加函数内部不保存上一拍的控制量逻辑更清晰也方便单独测试权值更新部分。3.2 不依赖Simulink的最小复现脚本如果身边只有MATLAB基础环境或者想先确认算法本身没问题我习惯先跑一个纯m脚本。被控对象选用三阶惯性环节频域特性更接近温度或压力对象也更容易暴露积分路参数过大的发散行为。%% 单神经元自适应PID有监督Hedd仿真独立脚本 clear; clc; Ts 0.01; T_end 10; N T_end / Ts 1; t (0:N-1) * Ts; r ones(1, N); r(1:100) 0; % 1s后给单位阶跃 % 被控对象离散化G(s) 1/(s1)^3 s tf(s); Gd c2d(1/(s1)^3, Ts, zoh); [num, den] tfdata(Gd, v); % 控制器参数初值 K 0.6; eta [0.30 0.15 0.10]; wi [0.1 0.1 0.1]; w_lo -5; w_hi 5; u_lo -1; u_hi 1; y zeros(1, N); u zeros(1, N); e zeros(1, N); ei_sum 0; e_prev 0; for k 1:N-1 e(k) r(k) - y(k); % 当前误差 ei_sum ei_sum e(k) * Ts; % 积分项累加 x [e(k), ei_sum, (e(k) - e_prev) / Ts];% 三路输入 du K * (wi * x); % 神经元增量输出 u(k1) u(k) du; u(k1) min(max(u(k1), u_lo), u_hi); % 控制量限幅 % 被控对象差分方程三阶zoh离散模型 if k 3 y(k1) -den(2)*y(k) - den(3)*y(k-1) - den(4)*y(k-2) ... num(2)*u(k) num(3)*u(k-1) num(4)*u(k-2); else y(k1) 0; % 前几拍没有历史数据 end % 有监督Hedd权值更新 for i 1:3 wi(i) wi(i) eta(i) * e(k) * du * x(i); wi(i) min(max(wi(i), w_lo), w_hi); end e_prev e(k); end figure; subplot(2,1,1); plot(t, r, --, t, y, -); ylabel(y); grid on; legend(指令,响应); xlim([0 T_end]); subplot(2,1,2); plot(t, u); ylabel(控制量 u); grid on; xlabel(t/s);代码里c2d用的zoh保持器这是执行机构通常的零阶保持特性比tustin变换更接近真实离散控制场景。差分方程中num和den是离散传递函数的分子分母系数长度为4对应三阶对象。控制器每拍执行顺序是先算误差再算三路输入然后计算增量并累加最后用误差、增量、输入三者一起更新权值。顺序不能乱如果先更新权值再用新权值计算du等效于把当前拍的误差重复利用了两次学习过程会明显变快但更容易振荡。3.3 Simulink侧常用的参数传递与监视方式复杂一点的仿真会把参数定义在模型工作区里MATLAB Function通过参数对象传入而不是把数值硬编码在函数内部。这样改一组参数不需要打开函数编辑器。监视权值变化时从函数单独输出wi数组接一个Demux和Scope就能看到三路权值如何自适应调整当对象特性变化时权值曲线会明显移动这是判断控制器“确实在学习”的最直观证据。4. 仿真发散与参数整定单神经元PID最容易踩的3个坑4.1 K过大的典型发散形式与Ziegler-Nichols思路的区别单神经元PID的K参数类似传统PID的总增益但它不是直接乘在误差上而是乘在神经元输出增量上所以K影响的是每拍控制量变化的步长。K设到2以上仿真往往表现为等幅振荡曲线像锯齿一样来回冲K小于0.05时输出缓慢逼近10秒仿真结束可能还没到目标值。传统Ziegler-Nichols方法要先加大比例增益找到临界振荡点再按经验公式回退单神经元PID不必走这套流程。K从0.1开始每轮仿真增加0.1看响应曲线的上升时间和是否出现初期的振铃现象一般三次就能定下来。K值依赖对象的时间常数温度对象时间常数几百秒K可以小到0.01电机转速这类快速对象K反而要给到0.5以上脚本里要注意对象的量纲。4.2 三路学习率的分工与经验范围学习率直接决定权值每拍变化的幅度。下面是不同对象的参数调整侧重点适合仿真初期对照使用。对象类型eta(1) 比例路eta(2) 积分路eta(3) 微分路主要风险温度/压力慢对象0.100.300.050.100.010.05积分率过大引发低频振荡电机转速中等对象0.200.400.080.150.050.10比例率过大会超调快速伺服/流量对象0.050.200.020.050.100.30微分率过大会放大噪声调试时先固定比例路观察阶跃响应有没有等幅振荡有振荡就降eta(1)响应慢就升K这个环节和普通PID整定手感一致。静差一直存在的场景优先加eta(2)而不是加积分输入项的限幅范围因为积分路学习率太小会让权值长时间停留在当前值附近等效的Ki根本跟不上对象漂移。微分路在仿真中几乎不会引起问题但中式慢对象里微分权值会异常增大因为微分输入项本身长期接近零误差的微小变化就会带来较大的相对波动这时需要给权值限幅收紧。4.3 “仿真发散”时先检查什么仿真发散的表现分三类对象输出直线冲顶不回头输出等幅振荡且幅度越来越大控制量长期贴在限幅上下沿。遇到这些情况按顺序排查先看Scope里u曲线是否在±1的限幅上来回顶再看三路权值是否被推到±5限幅墙上最后检查误差积分项是否已经累积到远超对象需要的量级。积分累积过大是很隐蔽的问题。限幅后误差一直存在权值按 e(k)dux 的规律持续更新积分路的权值会不断朝同一方向增长等效Ki越滚越大形成正反馈。一个实用的处理办法是在饱和期间停止或减半更新权值% 限幅饱和时降低权值更新强度防止积分权值跑偏 if u_lo u(k1) u(k1) u_hi wi wi eta .* e(k) .* du .* x; else wi wi 0.5 * eta .* e(k) .* du .* x; end注意这个判断用u(k1)也就是已经限幅后的值如果u已经贴边说明执行机构到顶继续让权值同向增长没有意义减半更新的同时等待误差反向即可。还有一类发散是从Simulink里把变步长求解器忘了改回来优先检查求解器设置再回到这节的参数问题。5. 从仿真到可用单神经元PID的验证脚本与小技巧5.1 用自动扫描脚本缩小K和eta的初步范围手动调参试几轮能稳住但说不好是不是局部最优。固定步长仿真跑一轮只要几十毫秒扫描整个参数空间也只需几分钟。把上一章的仿真主体封装成函数输入K和eta输出误差序列再用ITAE指标做排序最省事。function itae run_snpid_sim(K, eta, Ts) % 返回ITAE指标 % ... 主体代码与第3章循环一致 ... end best_itae inf; for K 0.1:0.1:1.0 for et1 0.1:0.1:0.5 for et2 0.05:0.05:0.25 itae run_snpid_sim(K, [et1, et2, 0.1], 0.01); if itae best_itae best_itae itae; best_K K; best_eta [et1, et2, 0.1]; end end end end fprintf(K%.2f eta[%.2f %.2f %.2f] ITAE%.4f\n, ... best_K, best_eta, best_itae);ITAE对误差持续时间的惩罚比ISE更重优先抑制长时间静差符合控制系统整定习惯。扫描得到的参数需要回到Simulink里带限幅验证一次脚本中如果没写限幅得到的参数在真实执行机构条件下不一定成立。5.2 检验自适应性直接改被控对象参数参数确定后把被控对象从1/(s1)^3改成1/(1.5s1)^3重新运行同一套仿真观察响应是否仍然收敛。权值曲线在这一步会重新分布说明控制器在根据误差调整参数。如果响应发散回到第4章的排查流程重点看学习率是否需要整体缩小。仿真发散在参数扫描阶段就能避免这里只是最后确认。5.3 一个容易被忽略的工程细节微分输入项在离散实现里除以Ts仿真步长固定时没问题但移植到单片机后定时器周期如果有抖动微分项会突然变大。常见做法是把输入定义成不除Ts的差分形式让采样周期在权值里被吸收再配合限幅处理。从仿真到实物的差距往往不在算法本体的收敛性而在这些定时、限幅、单位换算的细节上仿真通过只是第一步。本文还有配套的精品资源点击获取
返回列表