预习神经网络原理及应用
课程大作业所整理的笔记。
本文将介绍单神经元PID控制器原理、有监督Hebb学习规则、单神经元PID控制器的改进、Simlink仿真具体步骤、S-function的使用方法。依照上述原理与方法完成单神经元PID控制器的设计与仿真。
下一篇文章将介绍基于BP神经网络的PID控制器的设计与仿真。
绪论
神经网络
人工神经网络(Artificial Neural
Networks,ANN),简称神经网络,是指一类受生物学和神经科学启发得来的的数学模型。主要通过对人脑的神经元网络进行抽象,构建人工神经元,并按照一定拓扑结构来建立人工神经元之间的连接,来模拟生物的神经网络。
人工神经网络由许许多多信息处理单位(对应于人脑中的神经元)根据不同的相互作用强度(即连接权值)互连而成,其实质是对生物学上的人脑神经体系的一种近似与模拟,人工神经网络能够像人体神经系统一样对外界知识进行检索、处理与存储。
单神经元原理
单神经元,又被称作MP神经元,由心理学家McCulloch和数学家Pitts于1943年根据生物神经元的结构提出。
单神经元模型如上图所示,其中\(x_1,x_2,\cdots,x_n\)为接收到的信息,\(\omega_{i1},\omega_{i2},\cdots,\omega_{in}\)为连接的权值。将各个信息值按照权重相加并做一定处理,所得到的结果被称为“净输入”,其表达式为:
\(net_i=\sum\limits_{j = 1}^n
\omega_{ij}x_j-\theta_i\)
式中\(\theta_i\)为神经元\(i\)的阈值。
最终的输出值\(y_i\)与净输入\(net_i\)的关系式为:\(y_i=g(net_i)\),这里的\(g\)被称为激活函数。
单神经元PID控制器原理

单神经元PID控制框图如上图所示,图中\(r_{in}\)为系统输入值(设定值),\(y_{out}\)为系统实际输出值,输入转换模块将\(r_{in}\)与\(y_{out}\)变换为神经元的输入状态变量\(x_i(k)\),这三个状态变量与PID控制器的三个参数(\(K_p,K_i,K_d\))相关,PID控制器采用增量式算法,其中:
\(x_1(k)=e(k)\),对应PID控制的积分项,与误差量相等;
\(x_2(k)=\Delta
e(k)=e(k)-e(k-1)\),对应PID控制的比例项,反映误差变化的方向;
\(x_3(k)=\Delta^2
e(k)=e(k)-2e(k-1)+e(k-2)\),对应PID控制的微分项。
取\(\omega_i(k)\)为\(x_i(k)\)的神经元连接权值,取\(K\)为神经元的比例系数(要求\(K>0\)),则有:
\(u(k)=u(k-1)+K\sum\limits_{i = 1}^3
\omega_i(k)x_i(k)\)
\(\Delta
u(k)=K[\omega_1(k)e(k)+\omega_2(k)\Delta e(k)+\omega_3(k)\Delta^2
e(k)]\)
由此可知,\(K\)值越大,系统整体速度越快,但同时超调量也会增多,而且影响系统整体稳定性。
神经元通过有监督型Hebb学习,对神经元连接权值进行实时修正,以实现对PID控制器参数的自适应调整。
这里取教师信号(系统性能指标)\(z(k)=e(k)\),得到\(k\)时刻的连接权值为:
\(\omega_i(k)=\omega_i(k-1)+\eta
z(k)u(k)x_i(k)\)
式中\(\eta\)为学习速率,取大于零的较小值。
单神经元PID控制器改进
为解决当\(\eta\)的值较大时,单神经元PID的学习速度增大的同时可能造成的收敛速度降低问题,可以让输入状态变量的连接权值以不同学习速率分开调整。
这里对不同状态变量采用不同的连接权值学习速率\(\eta_P,\eta_I,\eta_D\),可以得到:
\(\omega_1(k)=\omega_1(k-1)+\eta_I
z(k)u(k-1)x_1(k)\)
\(\omega_2(k)=\omega_2(k-1)+\eta_P
z(k)u(k-1)x_2(k)\)
\(\omega_3(k)=\omega_3(k-1)+\eta_D
z(k)u(k-1)x_3(k)\)
\(u(k)=u(k-1)+K\sum\limits_{i=1}^3
\omega_i^{'}(k)x_i(k)\)
\(\omega_i^{'}(k)=\frac{\omega_i(k)}{\sum\limits_{j=1}^3
|\omega_j(k)|}\)(归一化处理)
而实际经验表明,PID参数不仅与\(e(k)\)有关,还与其变化值\(\Delta
e(k)\)有关,将后者也加入到连接权值调整公式中,可以得到:
\(\omega_1(k)=\omega_1(k-1)+\eta_I
z(k)u(k-1)[e(k)+\Delta e(k)]\)
\(\omega_2(k)=\omega_2(k-1)+\eta_P
z(k)u(k-1)[e(k)+\Delta e(k)]\)
\(\omega_3(k)=\omega_3(k-1)+\eta_D
z(k)u(k-1)[e(k)+\Delta e(k)]\)
单神经元PID控制器仿真分析
仿真模型搭建
使用Simulink构建一个简单的连续系统仿真模型,如下图所示:

仿真模型最中央的“exp_pidf”是一个S函数(S-function)模块,它是一个Matlab脚本文件,在仿真模型中实现单神经元PID的相关运算。
S函数模块左侧的Mux总线与该函数的五个输入值相连,它们分别是\(e(k),e(k-1),e(k-2),u(k-1),u(k)\)。
这里\(e(k)\)是误差变量,也是整个PID控制器的输入变量。在\(e(k)\)的基础上串联一个延时环节(Unit
Delay)就会得到\(e(k-1)\),他表示的是上一次的误差。同理串联两个延时环节得到\(e(k-2)\)。
\(u(k)\)是控制器输出量,同理可知串联一个延时环节得到的\(u(k-1)\)是上一次的输出量。
S函数模块右侧的Demux总线与该函数的四个输出值相连,它们是控制器输出值\(u(k)\)与PID的三个参数\(K_i,K_p,K_d\)。
这里\(u(k)\)是必须输出的值,而输出PID的三个参数值,是为了观察仿真运行过程中三个参数的变化情况。
S-function模块
S函数(S-function)是System-function系统函数的缩写,是指采用非图形化的方式(计算机语言)描述的一个功能块。首先要在Simulink中,找到S函数模块,打开库浏览器,找到Simulink->User-Defined Functions->S Function。

打开S函数模块,可以看到“模块参数”界面,有三个空。
第一个是S-Function名称,这个名称就是自己创建的matlab脚本的名称,脚本与仿真文件需要在同一文件夹内,点击“编辑”可以打开该脚本文件。
第二个是S-Function参数,它既不是输入参数也不是输出参数,而是外部参数,这些参数将被导入到脚本文件中参与计算。本次仿真外部参数为不同的连接权值学习速率\(\eta_P,\eta_I,\eta_D\)和神经元比例系数\(K\),填写为[ni;np;nd],K
。
最后一个是S-Function模块,在S-function是用C语言编写并用MEX工具编译的C-MEX文件时,需要填写该参数,这里不做修改。
右键S函数模块->封装->编辑封装,就能打开封装编辑器(Mask Editor)。

完成这一步后,再打开S函数模块,会直接弹出设置外部参数的对话框,更方便调整参数。

S-function编写
下面介绍S函数的编写原则,并基于此写出单神经元PID控制器的S函数。
1
function [sys,x0,str,ts,simStateCompliance] = exp_pidf(t,x,u,flag,deltak,K)
t是时间变量;
x是状态变量,对应前面的\(x_i(k)\)或\(\omega_i(k)\);
u是输入向量,对应仿真文件中S函数模块与左侧Mux总线相连的五个输入值\(e(k),e(k-1),e(k-2),u(k-1),u(k)\),它们在S函数程序中被表示为\(u(1),u(2),u(3),u(4),u(5)\);
flag是标志位,在仿真程序运行的不同阶段,会根据标志位运行不同的子函数。
deltak是外部参数,这里deltak=[ni;np;nd],表示控制器积分、比例、微分的学习速率,它是一个列向量。
K是外部参数,神经元比例系数。这里的外部参数与前面“模块参数”界面中设置的参数要一一对应。
sys是程序返回值,它不一定是控制器输出量,返回的值取决于flag值,也就是不同的子函数;
x0是状态变量初始值;
str默认为空,无需设置;
ts是采样时间,包含采样时间和偏移量;
simStateComplicance是附加变量;
1 | switch flag, |
接下来完成这个主函数,它是一个switch-case结构,选择不同的标志位以进入不同的子函数。
其中flag=0时进入初始化函数,flag=2时更新状态变量,flag=3时计算控制器输出值。
1 | function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes |
初始化函数如上所示,主要关注离散的状态变量数量(NumDiscStates)、输出量数量(NumOutputs)、输入量数量(NumInputs)。
状态变量初始值x0设成不为零的较小数,可以避免可能出现的程序报错。
1 | function sys=mdlUpdate(t,x,u,deltak) |
状态变量更新函数如上所示。
其中x为上一次状态变量,\(x=[\omega_1(k-1);\omega_2(k-1);\omega_3(k-1)]\)
sys为更新后状态变量,\(sys=[\omega_1(k);\omega_2(k);\omega_3(k)]\)
其对应的公式为:
\(\omega(k)=\omega(k-1)+\eta
z(k)u(k-1)[e(k)+\Delta e(k)]\)
1 | function sys=mdlOutputs(t,x,u,K) |
控制器输出值计算函数如上所示。 其中xx对应\(x_i(k)\)
sys的第一个参数是控制器输出值,对应公式:
\(u(k)=u(k-1)+K\sum\limits_{i=1}^3
\omega_i^{'}(k)x_i(k)\)
sys的后面三个输出值为PID控制器参数\(K_i,K_p,K_d\),对应公式为:
\(K_i=K \omega_1^{'}(k)\)
\(K_p=K \omega_2^{'}(k)\)
\(K_d=K \omega_3^{'}(k)\)
注:这里的xx是行向量,x是列向量,只有这样向量相乘才会得到一个数。
参考资料
- 邱锡鹏. 神经网络与深度学习[M]. 北京:机械工业出版社,2020
- 李捷菲. 基于BP神经网络的PID控制系统研究与设计[D]. 吉林大学,2019
- CSDN—小师兄1995—单神经元PID控制+Simulink控制系统仿真
- CSDN—小师兄1995—Matlab S-function 使用总结
- CSDN—Mr. 邹—几种神经网络整定PID参数原理剖析及simulink案例仿真