精华内容
下载资源
问答
  • Matlab基于BPPID神经网络控制-基于BP PID神经网络控制.rar 基于BP PID神经网络控制,不错的!!!
  • 常规PID模糊PID神经网络PID控制效果比较-success.rar 最近做毕设,题目是智能励磁,做了个模糊PID和神经网络PID励磁控制,说白了,和励磁没任何关系,就是对一个三阶模型进行控制,现在与大家分享下。其中常规PID...
  • PID神经网络改进研究

    2014-04-24 13:13:06
    PID神经网络改进研究
  • 为了实现 PID 神经网络的硬件平台搭建,新型纳米器件———自旋忆阻器,由于其独特的记忆特性和纳米级尺寸,被用来模拟电子突触,以实现神经元之间的相互连接 . 最后,通过对强耦合系统进行解耦控制验证了该方案的有效性...
  • 首先,针对平流层飞艇运行特点建立了完整六自由度动力学模型,随后在模型基础上提出PID神经网络的组成结构和计算方法,并利用粒子群算法对神经元网络初始权值进行了优化。仿真计算结果表明,通过PID神经网络对控制率...
  • 针对PID神经网络能根据控制效果进行在线自学习调整及具有无静差控制效果等特点,通过分析PIDNN控制算法存在的局限性,提出了对误差进行分级的改进算法.对改进的算法进行仿真,结果证明该方法能有效地改善网络的性能.
  • PID神经网络控制的手术机器人导管操作系统_马旭.pdf
  • 为提高热电偶的测温精度...设计了实际多路电偶数据采集电路,并对采集的数据进行了分析处理,运用PID神经网络建立热电偶的数学模型。通过实验验证,这种方法的测温精度较高,能满足实际对宽范围高精度的温度测量需要。
  • pid神经网络控制器的设计
  • 针对工业控制领域中非线性系统采用传统的控制方法不能达到满意的控制效果,提出一种基于PID神经网络的控制方案,以对其进行辨识和控制。将PID神经网络引入控制系统中,既具有常规PID控制结构简单、参数物理意义明确...
  • PID神经网络解耦的实用程序,非常适用初学者参考学习!
  • 针对人们在室内不同区域对于光照强度的不同要求,提出了一种基于PID神经网络的光照强度控制算法。同时,利用改进的粒子群算法对PIDNN的连接权值进行了优化。为了验证算法的有效性,将该算法应用于一个实例模型,并...
  • 为了消除变风量空调系统各回路之间存在的耦合,以便对该系统进行有效控制,建立了变风量空调机组部分变频器....实际运行结果表明,PID神经网络解耦控制技术可以有效地对变风量空调系统中2个回路进行解耦控制。
  • 为了克服该问题,应用PID神经网络系统,提出了一种实时滞回补偿控制策略,以实现GMA的精密位移跟踪控制。PID神经网络是依据GMA的滞回特性构造的,通过反馈误差学习方案在线自适应学习GMA的逆滞回模型。通过仿真,...
  • 针对上述问题,在对球磨机制粉系统动态特性进行分析的基础上,提出了一种不依赖于被控对象数学模型的多变量PID神经网络解耦控制策略;为进一步提高控制器性能,利用一种改进的PSO算法对PID神经网络的权值初值进行离线...
  • 针对氨氮浓度和硝态氮浓度之间相互耦合,以及常规的PID控制方法难以获得满意控制效果的特点,以溶解氧浓度和内循环流量为操作变量,采用PID神经网络对氨氮浓度和硝态氮浓度进行解耦控制;针对PID神经网络连接权值...
  • 针对以上问题,借鉴传统静态神经网络的逆系统控制方法,并根据非线性自回归平均模型(NARMA-L2),给出了基于合作粒子群算法(CPSO)的PID神经网络控制策略(PIDNNC),并基于该策略设计了PIDNNC积分合成控制系统,...
  • 针对BP优化PID神经网络(BP-PDNN)易陷入局部极小的不足,提出了一种变尺度混沌优化PID神经网络设计方法,即MSCOA-PIDNN,将其应用于机械臂轨迹跟踪控制中。利用混沌运动的遍历性优化网络权值,通过压缩优化变量取值区间...
  • 基于麻雀搜索的PID神经网络解耦控制算法 文章目录基于麻雀搜索的PID神经网络解耦控制算法1.PID神经元网络结构2.控制律计算3.权值修正4.控制对象5.模型建立6.基于麻雀搜索的PID神经网络解耦控制算法7.算法结果:8....

    基于麻雀搜索的PID神经网络解耦控制算法


    摘要:PID 神经元网络采用的学习算法是梯度学习法,初始权值随机得到,权值在学习过程中可能陷入局部最优值。采用麻雀搜索算法优化神经元网络初始权值。

    1.PID神经元网络结构

    PID 神经元网络从结构上可以分为输入层、隐含层和输出层三层, n 个控制量的 PID 神经 元网络包含 n 个并列的相同子网络 , 各子网络间既相互独立 , 又通过网络连接权值相互联系。 每个子网络的输入层有两个神经元,分别接收控制量的目标值和当前值。每个子网络的隐含 层 由比例元、积分元和微分元构成,分别对应着 PID 控制器中的比例控制、积分控制和微分控制。 PID 神经元网络按被控系统控制量的个数可以分为控制单变量系统的单控制量神经元网 络和控制多变量系统的多控制量神经元网络。其中单控制量神经元网络是PID 神经元网络的基本形式,多控制量神经元网络可以看成是多个单控制量神经元网络的组合形式。单控制量神经元网络的拓扑结构如图1所示。

    在这里插入图片描述

    图1.单控制量神经元网络的拓扑结构

    图 1中X1X_1是控制量的控制目标 , X2X_2是控制量当前值 , YY 是神经元网络计算得到的控制律,wijw_{ij}wjkw_{jk}是网络权值,从中可以看到单控制量神经元网络是一个三层前向神经元网络,网络结构为 2-3- 1 ,隐含层包含比例元、积分元和微分元三个神经元。多控制量神经元网络可 以看成多个单控制量网络的并联连接,多控制量神经元网络拓扑结构如图 2 所示。图中, $X_{11} , X_{21} , … , X_{n1} $是控制量的控制目标 ; X12,X22Xn2X_{12} , X_{22} , …, X_{n2} 是控制量的当前值;Y1,..,YnY_1,..,Y_n是多控制量神经元网络计算得到的控制律 ;wijw_{ij}wjkw_{jk}是网络权值。

    在这里插入图片描述

    图2.多控制量神经元拓扑网络

    2.控制律计算

    PID 神经元网络分为输入层、隐含层和输出层,网络输入量为控制量当前值和控制目标, 输出蛊为控制律,各层输入输出计算公式如下 。

    (1) 输入层

    输入层中包含2n个神经元,输出数据xsix_{si}等于输入数据 XsiX_{si} 计算公式为:
    xsi(k)=Xsi(k)(1) x_{si}(k) = X_{si}(k) \tag{1}
    (2) 隐含层

    隐含层有 3n 个神经元,包括 n 个比例神经元、n 个积分神经元和 n 个微分神经元。这些神经元的输入值相同,计算公式为 :
    netij(k)=i=12wijxsi(k),j=1,2,3(2) net_{ij}(k) = \sum_{i =1}^2 w_{ij}x_{si}(k),j = 1,2,3 \tag{2}
    隐含层各神经元输出的计算公式如下:

    比例神经元:us1(k)=nets1(k)u_{s1}(k) = net_{s1}(k)

    积分神经元:us2(k)=nets2(k)+us2(k1)u_{s2}(k) = net_{s2}(k) + u_{s2}(k-1)

    微分神经元:us3(k)=nets3(k)nets3(k1)u_{s3}(k) = net_{s3}(k) - net_{s3}(k-1)

    式中 ,s 为并联子网络的序号; j为子网络中隐含层神经元序号,xsi(k)x_{si}(k) 为各子网络输入层神经元输出值 ;wijw_{ij}为各子网络输入层至隐含层的连接权重值 。

    (3)输出层

    输出层有 n 个神经元 ,构成 n 维输出量,输出层的输出为隐含层全部神经元的输出值加权和,计算公式如下:
    yh(k)=s=1nj=13wjkusj(k)(3) y_h(k) = \sum_{s=1}^{n} \sum_{j=1}^3 w_{jk}u_{sj}(k) \tag{3}
    式中,h 为输出层神经元序号;s为子网的序号;j为子网的隐含层神经元序号 ; usj(k)u_{sj}(k)为隐含层各神经元输出值 ;wjkw_{jk}为隐含层至输出层的连接权重值。

    3.权值修正

    PID 神经元网络在控制的过程中根据控制量误差按照梯度修正法修正权值,使得控制量不断接近控制目标值 ,权值修正的过程如下 。

    误差计算公式如下:
    J=E=k=1n[yh(k)r(k)]2(4) J = \sum E = \sum_{k=1}^n[y_h(k) - r(k)]^2 \tag{4}
    式中,n为输出节点个数,yh(k)y_h(k)为预测输出;r(k)r(k)为控制目标。

    PID神经元网络权值修正公式如下:

    a.输出层到隐含层:
    wjk(k+1)=wjk(k)ηδJδwjk(5) w_{jk}(k+1) = w_{jk}(k) - \eta\frac{\delta J}{ \delta w_{jk}} \tag{5}
    b.输入层到输出层
    wij(k+1)=wij(k)ηδJδwij(6) w_{ij}(k+1) = w_{ij}(k) - \eta\frac{\delta J}{ \delta w_{ij}} \tag{6}
    其中η\eta为学习速率。

    4.控制对象

    PID 神经元网络的控制对象是一个 3 输入 3 输出的复杂耦合系统,系统的传递函数如下:
    {y1(k)=0.4y1(k1)+u1(k1)/[1+u1(k1)2]+0.2u1(k1)3+0.5u2(k1)+0.3y2(k1)y2(k)=0.2y2(k1)+u2(k1)/[1+u2(k1)2]+0.4u2(k1)3+0.2u1(k1)+0.3y3(k1)y3(k)=0.3y3(k1)+u3(k1)/[1+u3(k1)2]+0.4u3(k1)3+0.4u2(k1)+0.3y1(k1)(7) \begin{cases} y_1(k) = 0.4*y_1(k-1)+u_1(k-1)/[1+u_1(k-1)^2] + 0.2u_1(k-1)^3+0.5u_2(k-1)+0.3y_2(k-1)\\ y_2(k) = 0.2*y_2(k-1)+u_2(k-1)/[1+u_2(k-1)^2] + 0.4u_2(k-1)^3+0.2u_1(k-1)+0.3y_3(k-1)\\ y_3(k) = 0.3*y_3(k-1)+u_3(k-1)/[1+u_3(k-1)^2] + 0.4u_3(k-1)^3+0.4u_2(k-1)+0.3y_1(k-1)\\ \end{cases}\tag{7}
    从式7中可以看出该系统的控制量相互搞合,用 一般的控制方法难以取得理想的控制效果。

    5.模型建立

    PID 神经元网络控制器和被控系统构成的闭环控制系统如图 3所示:

    在这里插入图片描述

    图3.PID神经元网络闭环控制系统

    图中,r1,...,rnr_1,...,r_n是控制量控制目标 ,u1,...,unu_1,...,u_n为控制器控制律,y1,...,yny_1,...,y_n为控制量当前值。对于本案例来说,由于被控对象有三个控制量,所以选择包含三个单神经元网络组成的多神经元网络作为系统控制器. 网络权值随机初始化,控制量初始值为[0,0,0],目标为[0.7,0.4,0.6],控制时间间隔为0.001s。

    6.基于麻雀搜索的PID神经网络解耦控制算法

    麻雀搜索算法的具体原理参考博客:https://blog.csdn.net/u011835903/article/details/108830958。

    PID 神经元网络采用的学习算法是梯度学习法,初始权值随机得到,权值在学习过程中可能陷入局部最优值。采用麻雀搜索算法优化神经元网络初始权值。适应度函数即为控制误差和。

    麻雀算法参数设置如下:

    pop=50; % 种群数量
    Max_iteration=40; % 设定最大迭代次数
    dim = 3*6 + 3*9;% 权值维度
    lb = -0.3;%上边界
    ub = 0.3;%下边界
    fobj = @(x) fun(x);%适应度函数
    
    

    7.算法结果:

    在这里插入图片描述

    在这里插入图片描述

    从结果上来看,改进后的麻雀算法收敛速度快,控制精度明显高于基础的PID网络,且控制时间明显优于基础PID网络误差。

    8.参考文献:

    书籍《MATLAB神经网络43个案例分析》,上文基本原理均摘自该书籍。

    9.Matlab代码

    https://mianbaoduo.com/o/bread/YZWVmJ5x

    展开全文
  • PID神经网络控制

    千次阅读 热门讨论 2018-12-11 17:20:04
      采用增量PID神经网络的输入层有三个量 x1(k)=e(k)=r(k)−y(k)x_1(k)=e(k)=r(k)-y(k)x1​(k)=e(k)=r(k)−y(k) x2(k)=Δe(k)=e(k)−e(k−1)x_2(k)=\Delta e(k)=e(k)-e(k-1)x2​(k)=Δe(k)=e(k)−e(k−1) x3(k...

      采用增量PID的神经网络有三层,分别为i,j,li,j,l层,输入层有三个量
    x1(k)=e(k)=r(k)y(k)x_1(k)=e(k)=r(k)-y(k)
    x2(k)=Δe(k)=e(k)e(k1)x_2(k)=\Delta e(k)=e(k)-e(k-1)
    x3(k)=Δ2e(k)=Δe(k)Δe(k1)=e(k)2e(k1)+e(k2)x_3(k)=\Delta^2 e(k)=\Delta e(k)-\Delta e(k-1)=e(k)-2e(k-1)+e(k-2)
    其中e(k)e(k)表示kk时刻的误差,r(k)r(k)表示kk时刻的目标值,y(k)y(k)表示kk时刻的实际值。
      输出层有一个量
    Δu(k)=k1x1(k)+k2x2(k)+k3x3(k)\Delta u(k)=k_1x_1(k)+k_2x_2(k)+k_3x_3(k)
    表示kk时刻控制器应当给出的输入控制量的增量。
      训练的目标函数为
    J=12(r(k+1)y(k+1))2J=\frac{1}{2}(r(k+1)-y(k+1))^2
      训练系数时的导数为
    Jw=λJy(k+1)y(k+1)u(k)u(k)w\frac{\partial J}{\partial w}=-\lambda\frac{\partial J}{\partial y(k+1)}\frac{\partial y(k+1)}{\partial u(k)}\frac{\partial u(k)}{\partial w}
      当系统未知时,y(k+1)u(k)\frac{\partial y(k+1)}{\partial u(k)}无法求出,采用NNI辨识对象模型,估计出y^(k+1)u(k)\frac{\partial \hat{y}(k+1)}{\partial u(k)},如果不采用辨识器,则用sgn(y(k+1)u(k))sgn(\frac{\partial y(k+1)}{\partial u(k)})y(k+1)y(k)u(k)u(k1)\frac{y(k+1)-y(k)}{u(k)-u(k-1)}代替,由此带来的计算不精确可通过调整学习率η\eta来补偿。
      通过计算可以知道网络输出层权系数的学习算法为
    Δwjl3(k)=αΔwjl3(k1)+ηδl3Oj2(k)\Delta w_{jl}^3(k)=\alpha\Delta w_{jl}^3(k-1)+\eta\delta_l^3O_j^2(k)
    δl3=e(k)sign(yout(k)u(k))u(k)Ol3(k)g(netl3(k))\delta_l^3=e(k)sign(\frac{\partial yout(k)}{\partial u(k)})\cdot\frac{\partial u(k)}{\partial O_l^3(k)}\cdot g'(net_l^3(k))
    同样,隐层学习算法为
    Δwij3=aΔwij2(k1)+ηδi2Ojl(k)\Delta w_{ij}^3=a\Delta w_{ij}^2(k-1)+\eta\delta_i^2O_j^l(k)
    δj2(k)=f(netj2(k))l=13δl3wjl3(k)\delta_j^2(k)=f'(net_j^2(k))\sum_{l=1}^3\delta_l^3w_{jl}^3(k)
    f(x)=exp(x)exp(x)exp(x)+exp(x)f(x)=\frac{exp(x)-exp(-x)}{exp(x)+exp(-x)}
    g(x)=exp(x)exp(x)+exp(x)g(x)=\frac{exp(x)}{exp(x)+exp(-x)}
    其中
    O13(k)=Kp,O23(k)=Ki,O33(k)=KdO_1^3(k)=K_p,O_2^3(k)=K_i,O_3^3(k)=K_d
    u(k)O13(k)=e(k)\frac{\partial u(k)}{\partial O_1^3(k)}=e(k)
    u(k)O23(k)=e(k)e(k)\frac{\partial u(k)}{\partial O_2^3(k)}=e(k)-e(k)
    u(k)O33(k)=e(k)2e(k1)+e(k2)\frac{\partial u(k)}{\partial O_3^3(k)}=e(k)-2e(k-1)+e(k-2)

    NNI辨识器

      输入层为
    u(k),u(k1),,u(knu+1),y(k),y(k1),,y(kny+1)u(k),u(k-1),\dots,u(k-n_u+1),y(k),y(k-1),\dots,y(k-n_y+1)
      输出层为一个量,训练的目标函数为
    J=12(y(k+1)y^(k+1))2J=\frac{1}{2}(y(k+1)-\hat{y}(k+1))^2

    %% 定义神经网络结构
    classdef PID_NN
        properties               %PID_NN网络参数
            num_neuron_1=3;      %神经元个数1
            num_neuron_2=0;      %神经元个数2
            num_neuron_3=3;      %神经元个数3
            W_1=[];              %权重1
            W_2=[];              %权重2
            b_1=[];              %偏置1
            b_2=[];              %偏置2
            delta_2=[];          %梯度1
            delta_3=[];          %梯度2
            net_2=[];            %网络节点值1
            net_3=[];            %网络节点值2
            eta=10;             %学习率
    %         f=@(x)(tanh(x));%激活函数1
    %         df=@(x)(4*exp(2*x))./(1+exp(4*x)+2*exp(2*x));  %导函数1
    %         g=@(x)(logsig(x));                    %激活函数2
    %         dg=@(x)((1./(1+exp(-x))).*(1-(1./(1+exp(-x)))));                   %导函数2
            trainData_x=[];      %训练数据x
            trainData_y=[];      %训练数据y
            batch_size=100;      %训练批次的大小
            N_sample=0;          %训练数据的总量
        end
        methods
            function obj=PID_NN(num)                         %构造函数
                obj.num_neuron_2=num;
            end
            function [obj]=train(obj,trainData_x,trainData_e,Iter,model)%训练
                %输入参数为,训练数据x,训练数据y,辨识器数据y_partial_u,迭代次数Iter,模型model
                %初始化参数
                obj.num_neuron_1=size(trainData_x,2);
    %             obj.num_neuron_3=size(trainData_e,2);
                obj.N_sample=size(trainData_x,1);
                obj.b_1=rand(1,obj.num_neuron_2);
                obj.b_2=rand(1,obj.num_neuron_3);
                obj.W_1=rand(obj.num_neuron_1,obj.num_neuron_2);
                obj.W_2=rand(obj.num_neuron_2,obj.num_neuron_3);
                obj.batch_size=1;
                y_partial_u=model.df(model.input(2:end))';
                %训练
                for i=1:Iter
                    rand_index=randperm(obj.N_sample , obj.batch_size);
                    trainData_x_batch=trainData_x(rand_index,:);
                    trainData_e_batch=-trainData_e(rand_index,:);
                    y_partial_u_batch=y_partial_u(rand_index,:);
                    [net_2_,~,net_20,net_30]=Forward_propagation(obj,trainData_x_batch);%计算向前传播
                    
                    
                    delta_3_=repmat(trainData_e_batch.*y_partial_u_batch,1,obj.num_neuron_3).*dg(net_30).*trainData_x_batch;
                    delta_w_3=obj.eta*net_2_'*delta_3_;
                    delta_2_=df(net_20).*repmat((sum(delta_3_,1)*obj.W_2'),obj.batch_size,1);
                    delta_w_2=obj.eta*trainData_x_batch'*delta_2_;
                    
                    obj.W_1=obj.W_1-delta_w_2;
                    obj.W_2=obj.W_2-delta_w_3;
                    obj.b_1=obj.b_1-obj.eta*sum(delta_2_,1);
                    obj.b_2=obj.b_2-obj.eta*sum(delta_3_,1);
    %                 disp(sum(delta_3_,1))
                end
                obj.delta_2=delta_2_;
                obj.delta_3=delta_3_;
            end
            
            function [obj]=train2(obj,trainData_x,trainData_y,Iter)%训练
                %输入参数为,训练数据x,训练数据y,辨识器数据y_partial_u,迭代次数Iter,模型model
                %初始化参数
                obj.num_neuron_1=size(trainData_x,2);
                obj.num_neuron_3=size(trainData_y,2);
                obj.N_sample=size(trainData_x,1);
                obj.b_1=rand(1,obj.num_neuron_2);
                obj.b_2=rand(1,obj.num_neuron_3);
                obj.W_1=rand(obj.num_neuron_1,obj.num_neuron_2)*0.01;
                obj.W_2=rand(obj.num_neuron_2,obj.num_neuron_3)*0.01;
                obj.batch_size=obj.N_sample;
                obj.batch_size=1;
                %训练
                for i=1:Iter
                    rand_index=randperm(obj.N_sample , obj.batch_size);
                    trainData_x_batch=trainData_x(rand_index,:);
                    trainData_y_batch=trainData_y(rand_index,:);
                    [net_2_,net_3_,net_20,net_30]=Forward_propagation(obj,trainData_x_batch);%计算向前传播
                    
                    trainData_e_batch=net_3_-trainData_y_batch;
    %                 net_30
    %                 dg(net_30)
                    delta_3_=trainData_e_batch.*dg(net_30);
                    delta_w_3=obj.eta*net_2_'*delta_3_;
    %                 net_20
    %                 df(net_20)
                    delta_2_=df(net_20).*repmat((sum(delta_3_,1)*obj.W_2'),obj.batch_size,1);
                    delta_w_2=obj.eta*trainData_x_batch'*delta_2_;
                    
                    obj.W_1=obj.W_1-delta_w_2;
                    obj.W_2=obj.W_2-delta_w_3;
                    obj.b_1=obj.b_1-obj.eta*sum(delta_2_,1);
                    obj.b_2=obj.b_2-obj.eta*sum(delta_3_,1);
                end
                obj.delta_2=delta_2_;
                obj.delta_3=delta_3_;
            end
            
            function [net_2,net_3,net_20,net_30]=Forward_propagation(obj,trainData_x_batch)
                net_20=trainData_x_batch*obj.W_1+obj.b_1;
                net_2=tanh(net_20);
                net_30=net_2*obj.W_2+obj.b_2;
                net_3=logsig(net_30);
            end
            %--------------------------
            function obj=output(obj,e)                       %输出对象被调量
                obj.e=e;
                obj.delta_u=obj.K_P*obj.e(end) + obj.K_I*sum(obj.e,2) + ...
                    obj.K_D*(obj.e(end)-obj.e(end-1));
            end
        end
    end
    
    pidnn=PID_NN(10);
    %% 设置参数
    trainData_x_batch=([0 0 0]);
    num_thread=size(trainData_x_batch,1);%设置并行模拟的线程数
    input=0;                             %系统对象的输入
    model=Model(input);                  %创建系统对象
    pid(1:num_thread)=PID(0.1,0.7,0.003);        %创建PID控制器
    targetValue=repmat([ones(1,20) zeros(1,20)],1,20);
    model(1:num_thread).targetValue=targetValue;       %设置系统输出目标值
    %% 产生训练数据
    [trainData_x,trainData_y]=PID_Data(model(1),pid);
    %% 训练网络
    pidnn=pidnn.train(trainData_x,trainData_y,10);
    %% 仿真
    model_list=simulink_with_NN(pidnn,pid,model,trainData_x_batch);
    %% 绘制动态图
    close all;
    figureout(model_list(1));
    
    %% 定义PID控制器结构
    classdef PID
        properties               %PID控制器参数
    %         k=10;
            e=[];        %长度为k的列表,存储了最近k步的偏差记录
            K_P=0;               %比例元系数
            K_I=0;               %积分元系数
            K_D=0;               %微分元系数
            delta_u=0;
        end
        methods
            function obj=PID(K_P,K_I,K_D)   %构造函数
                obj.K_P=K_P;
                obj.K_I=K_I;
                obj.K_D=K_D;
            end
            function obj=output_1(obj,e)%输出对象被调量——位置式
                obj.e=e;
                obj.delta_u=obj.K_P*obj.e(end) + obj.K_I*sum(obj.e,2) + ...
                    obj.K_D*(obj.e(end)-obj.e(end-1));
            end
            function obj=output_2(obj,e)%输出对象被调量——增量式
                obj.e=e;
                obj.delta_u=obj.K_P*(obj.e(end)-obj.e(end-1)) + ...
                    obj.K_I*sum(obj.e(end)) + ...
                    obj.K_D*(obj.e(end)-2*obj.e(end-1)+obj.e(end-2));
            end
        end
    end
    
    %% 定义模型
    classdef Model
        properties               %系统模型参数
            input=0;             %模型输入
            output=0;            %模型输出
            e_list=[];           %模型误差
            K_list=[];
            targetValue=0;
            f=@(x)(x);        %模型函数
            df=@(x)(1+x*0);
        end
        methods
            function obj=Model(input)   %构造函数
                obj.input=input;
                obj.output=obj.f(input);
            end
            function obj=step(obj,input)%步进输出函数
                obj.input=[obj.input input];
                obj.output=[obj.output obj.f(input)];
            end
            function obj=target(obj,targetValue)%步进输出函数
                obj.targetValue=targetValue;
            end
        end
    end
    
    function [model,trainData_x,trainData_y]=simulink_with_NN(obj,pid,model,trainData_x_batch)
    %% PID控制过程
    num_thread=size(trainData_x_batch,1);%设置并行模拟的线程数
    % k=3;                                 %误差长度
    e=trainData_x_batch;                 %误差
    size(model(1).targetValue,2)
    for j=1:size(model(1).targetValue,2)
        for i=1:num_thread               %依次对每个线程进行计算
            [~,net_3]=Forward_propagation(obj,e);
            model.K_list=[model.K_list;net_3];
            pid(i).K_P=net_3(i,1)*0.05;
            pid(i).K_I=net_3(i,2)*0.05;
            pid(i).K_D=net_3(i,3)*0.05;
    %         pid(i).K_P=0.1;
    %         pid(i).K_D=0.005;
            e0=model(i).targetValue(j)-model(i).output(end);
            model(i).e_list=[model(i).e_list e0];
            e=[e(2:end) e0];
            pid(i)=pid(i).output_2(e);
            input0=model(i).input(end) + pid(i).delta_u(end);
            model(i)=model(i).step(input0);
        end
    end
    %% 整理出系统对象运行的训练数据
    x1=model.e_list(3:end);
    x2=model.e_list(3:end)-model.e_list(2:end-1);
    x3=model.e_list(3:end)-2*model.e_list(2:end-1)+model.e_list(1:end-2);
    trainData_x=[x1' x2' x3'];
    trainData_y=x1';
    trainData_x(end,:)=[];
    trainData_y(1,:)=[];
    end
    
    %% 为PID_NN提供系统对象的训练数据和辨识器输出——离线训练
    function [model,trainData_x,trainData_y]=PID_Data(model,pid)
    % tic
    %% PID控制过程
    k=5;%误差长度
    e=zeros(1,k);%误差
    for i=1:size(model.targetValue,2)
        e0=model.targetValue(i)-model.output(end);
        model.e_list=[model.e_list e0];
        e=[e(2:end) e0];
        pid=pid.output_2(e);
        input0=model.input(end);% + pid.delta_u(end);
        model=model.step(input0);
    end
    toc
    %% 整理出系统对象运行的训练数据
    x1=model.e_list(3:end);
    x2=model.e_list(3:end)-model.e_list(2:end-1);
    x3=model.e_list(3:end)-2*model.e_list(2:end-1)+model.e_list(1:end-2);
    trainData_x=[x1' x2' x3'];
    trainData_y=x1';
    trainData_x(end,:)=[];
    trainData_y(1,:)=[];
    %% 给出辨识器数据
    % [y_partial_u]=Identifier(model.df,model.input(3:end-1));
    end
    
    %% 定义动态图展示函数
    function figureout(model)
    figure;
    %设置图像背景
    colordef white;
    set(gcf,'Units','normalized','Position',[0 0 1 1]);
    for i=1:size(model.input,2)-1
    %     plot(1:i,model.output(i:-1:1),'b-')
        plot([1:i;1:i]',[model.output(i:-1:1);model.targetValue(i:-1:1)]')
        %画出轨迹上的点
        line('xdata',1,'ydata',model.output(:,i),'Color','b','Marker','.','MarkerSize',40);
        filed_y=[min(model.output) max(model.output) max(model.output)-min(model.output)];
        axis([0,size(model.input,2),filed_y(1)-0.15*filed_y(3),filed_y(2)+0.15*filed_y(3)]);
        drawnow;
    end
    legend('实际值','目标值')
    end
    
    展开全文
  • PID神经网络原理与MATLAB实现(SISO)

    热门讨论 2021-01-19 22:09:37
    最近想实现一下PID神经网络,但是书籍和博客都令人头疼,主要是卡在误差反向传播的计算过程中。找一篇通俗易懂的文章实在不易,最终,只能自己静下心,仔细琢磨。只要每一步在逻辑上都是合理的,我们有理由相信能够...

    最近想实现一下PID神经网络,但是书籍和博客都令人头疼,主要是卡在误差反向传播的计算过程中。找一篇通俗易懂的文章实在不易,最终,只能自己静下心,仔细琢磨。只要每一步在逻辑上都是合理的,我们有理由相信能够得到正确的结果。抱着这样的心态,由浅入深,来实现一下。


    一、网络结构定义

    简单起见,假设一个受控系统单输入 uu 单输出 xx ,使用一个PID神经网络来作为控制器,使得系统输出达到目标值 zz

    网络结构定义

    其中,W3×2W_{3\times 2}V1×3V_{1\times 3}分别为输入层—隐含层权重矩阵和隐含层—输出层权重矩阵。yiy_iyoy_o分别是PID计算前后向量。z,x,uz, x, u分别为期望值、实际值和网络输出,都是数。


    1.1 前向传播

    根据以上结构,容易得出前向传播如下。注意简介起见,第(k)(k)次的标注省略。

    yi1=w11z+w12xyi2=w21z+w22xyi3=w31z+w32x(1)\begin{aligned} & y_{i1} = w_{11} z + w_{12} x \\ & y_{i2} = w_{21} z + w_{22} x \\ & y_{i3} = w_{31} z + w_{32} x \tag{1} \end{aligned}

    yo1=yi1yo2=yo2(k1)+yi2yo3=yi3(k)yi3(k1)(2)\begin{aligned} & y_{o1} = y_{i1} \\ & y_{o2} = y_{o2}(k-1) + y_{i2} \\ & y_{o3} = y_{i3}(k) - y_{i3}(k-1) \tag{2} \end{aligned}

    u=v11yo1+v12yo2+v13yo3(3) u = v_{11} y_{o1} + v_{12} y_{o2} + v_{13} y_{o3} \tag{3}

    不妨设受控对象为一个类似二次函数的时变系统(用于仿真),则输出及损失函数为

    x=u2(k)+0.1x(k1)(4) x = u^2(k) + 0.1x(k-1) \tag{4}

    J=12(zx)2(5) J = \frac{1}{2} (z-x)^2 \tag{5}


    1.2 反向传播

    前向传播计算完成,以下开始反向传播。首先考虑权重 VV 对误差 JJ 的影响,也即计算 JV\frac{\partial J}{\partial V},根据前向传递函数关系,易得

    Jv11=Jxxuuv11=(zx)xuyo1(6)\begin{aligned} \frac{\partial J}{\partial v_{11}} &= \frac{\partial J}{\partial x} \frac{\partial x}{\partial u} \frac{\partial u}{\partial v_{11}} \\ &= -(z-x) \cdot \frac{\partial x}{\partial u}\cdot y_{o1} \end{aligned} \tag{6}

    由于受控对象的数学模型往往不知道或者偏导难以计算,中间的 xu\frac{\partial x}{\partial u} 常用下式子代替

    xu=signx(k)x(k1)u(k)u(k1)(7) \frac{\partial x}{\partial u} ={\rm sign} \frac{x(k) - x(k-1)}{u(k) - u(k-1)} \tag{7}

    以下xu\frac{\partial x}{\partial u}皆由式(7)得出,不在赘述。

    其中 sign(){\rm sign}(\cdot)是符号函数,输入正数输出11,输入负数输出1-1,输入00输出00。使用符号函数的好处是归一化到 [1,1][-1,1],避免分母很接近0导致输出很大的问题。

    同理易得

    Jv12=(zx)xuyo2(8)\frac{\partial J}{\partial v_{12}} = -(z-x) \cdot \frac{\partial x}{\partial u} \cdot y_{o2} \tag{8}

    Jv13=(zx)xuyo3(9) \frac{\partial J}{\partial v_{13}} = -(z-x) \cdot \frac{\partial x}{\partial u} \cdot y_{o3} \tag{9}


    接下来,计算真正的难点 JW\frac{\partial J}{\partial W}

    Jw11=Jxxuuyo1yo1yi1yi1w11=(zx)xuv111z(10)\begin{aligned} \frac{\partial J}{\partial w_{11}} &= \frac{\partial J}{\partial x} \frac{\partial x}{\partial u} \frac{\partial u}{\partial y_{o1}} \frac{\partial y_{o1}}{\partial y_{i1}} \frac{\partial y_{i1}}{\partial w_{11}} \\ &=-(z-x) \cdot\frac{\partial x}{\partial u} \cdot v_{11} \cdot 1 \cdot z \end{aligned} \tag{10}

    同理易得

    Jw12=Jxxuuyo1yo1yi1yi1w12=(zx)xuv111x(11)\begin{aligned} \frac{\partial J}{\partial w_{12}} &= \frac{\partial J}{\partial x} \frac{\partial x}{\partial u} \frac{\partial u}{\partial y_{o1}} \frac{\partial y_{o1}}{\partial y_{i1}} \frac{\partial y_{i1}}{\partial w_{12}} \\ &=-(z-x) \cdot\frac{\partial x}{\partial u} \cdot v_{11} \cdot 1 \cdot x \end{aligned} \tag{11}


    Jw21=Jxxuuyo2yo2yi2yi2w21=(zx)xuv12yo2yi2z(12)\begin{aligned} \frac{\partial J}{\partial w_{21}} &= \frac{\partial J}{\partial x} \frac{\partial x}{\partial u} \frac{\partial u}{\partial y_{o2}} \frac{\partial y_{o2}}{\partial y_{i2}} \frac{\partial y_{i2}}{\partial w_{21}} \\ &=-(z-x) \cdot \frac{\partial x}{\partial u} \cdot v_{12} \cdot \frac{\partial y_{o2}}{\partial y_{i2}} \cdot z \end{aligned} \tag{12}

    其中

    yo2yi2=Δyo2Δyi2=yo2(k)yo2(k1)yi2(k)yi2(k1)=yi2(k)yi2(k)yi2(k1) \frac{\partial y_{o2}}{\partial y_{i2}} = \frac{\Delta y_{o2}}{\Delta y_{i2}} = \frac{y_{o2}(k) - y_{o2}(k-1)}{y_{i2}(k) - y_{i2}(k-1)} = \frac{y_{i2}(k) }{y_{i2}(k) - y_{i2}(k-1)}

    和之前一样,使用符号函数计算可得

    yo2yi2=signyi2(k)yi2(k)yi2(k1)(13) \frac{\partial y_{o2}}{\partial y_{i2}} = {\rm sign}\frac{y_{i2}(k) }{y_{i2}(k) - y_{i2}(k-1)} \tag{13}

    同理

    Jw22=Jxxuuyo2yo2yi2yi2w22=(zx)xuv12yo2yi2x(14)\begin{aligned} \frac{\partial J}{\partial w_{22}} &= \frac{\partial J}{\partial x} \frac{\partial x}{\partial u} \frac{\partial u}{\partial y_{o2}} \frac{\partial y_{o2}}{\partial y_{i2}} \frac{\partial y_{i2}}{\partial w_{22}} \\ &=-(z-x) \cdot \frac{\partial x}{\partial u} \cdot v_{12} \cdot \frac{\partial y_{o2}}{\partial y_{i2}} \cdot x \end{aligned} \tag{14}


    Jw31=Jxxuuyo3yo3yi3yi3w31=(zx)xuv13yo3yi3z(15)\begin{aligned} \frac{\partial J}{\partial w_{31}} &= \frac{\partial J}{\partial x} \frac{\partial x}{\partial u} \frac{\partial u}{\partial y_{o3}} \frac{\partial y_{o3}}{\partial y_{i3}} \frac{\partial y_{i3}}{\partial w_{31}} \\ &=-(z-x) \cdot \frac{\partial x}{\partial u} \cdot v_{13} \cdot \frac{\partial y_{o3}}{\partial y_{i3}} \cdot z \end{aligned} \tag{15}

    其中

    yo3yi3=Δyo3Δyi3=yo3(k)yo3(k1)yi3(k)yi3(k1)=yo3(k)yo3(k1)yo3(k) \frac{\partial y_{o3}}{\partial y_{i3}} = \frac{\Delta y_{o3}}{\Delta y_{i3}} = \frac{y_{o3}(k) - y_{o3}(k-1)}{y_{i3}(k) - y_{i3}(k-1)} = \frac{y_{o3}(k) - y_{o3}(k-1)}{y_{o3}(k)}

    依旧使用符号函数归一化

    yo3yi3=signyo3(k)yo3(k1)yo3(k) \frac{\partial y_{o3}}{\partial y_{i3}} ={\rm sign} \frac{y_{o3}(k) - y_{o3}(k-1)}{y_{o3}(k)}

    同理

    Jw32=Jxxuuyo3yo3yi3yi3w32=(zx)xuv13yo3yi3x(16)\begin{aligned} \frac{\partial J}{\partial w_{32}} &= \frac{\partial J}{\partial x} \frac{\partial x}{\partial u} \frac{\partial u}{\partial y_{o3}} \frac{\partial y_{o3}}{\partial y_{i3}} \frac{\partial y_{i3}}{\partial w_{32}} \\ &=-(z-x) \cdot \frac{\partial x}{\partial u} \cdot v_{13} \cdot \frac{\partial y_{o3}}{\partial y_{i3}} \cdot x \end{aligned} \tag{16}


    1.3 权值更新

    如果使用传统的梯度下降法,则更新公式为

    W=Wα1JW(17) W = W - \alpha_1 \frac{\partial J}{\partial W} \tag{17}

    V=Vα2JV(18) V = V - \alpha_2 \frac{\partial J}{\partial V} \tag{18}

    其中,α1,α2\alpha_1, \alpha_2为学习率。

    有时,也增加动量项,则更新公式为

    Wd(k)=β1Wd(k1)+(1β1)JWW=Wα1Wd(19)\begin{aligned} & W_d(k) = \beta_1 W_d(k-1) + (1-\beta_1)\frac{\partial J}{\partial W}\\ & W = W - \alpha_1 W_d \tag{19} \end{aligned}

    Vd(k)=β2Vd(k1)+(1β2)JVV=Vα2Vd(20)\begin{aligned} & V_d(k) = \beta_2 V_d(k-1) + (1-\beta_2)\frac{\partial J}{\partial V}\\ & V = V - \alpha_2 V_d \tag{20} \end{aligned}

    其中,β1,β2\beta_1, \beta_2为动量因子,一般取 0.9;Wd,VdW_d, V_d 可取初始值为0进行迭代。

    1.4 实际问题

    以上算法纯属理论,在仿真中可能都会遇到问题。一个典型的问题是除数为0的情况,在这里很容易发生,例如 u(k)=u(k1)u(k) = u(k-1) 就是如此。另一个问题是数值过大,比如除数很小就很容易导致这种现象。因此有必要规避除数为0,也要做好限幅工作。写程序时需要注意这些细节。


    二、仿真

    现假设受控系统是一个式(4) 描述的系统,设期望值为一个阶梯信号,整个程序如下

    %% 参数初始化
    % 初始化
    rng(1);                         % 设置随机数种子
    z = 1;                          % 目标值
    x = 0;                          % 实际值初始化
    W = 0.3*(rand(3,2) - 0.5);      % 隐含层—输入层权重矩阵
    V = 0.3*(rand(3,1) - 0.5);      % 输出层—隐含层权重矩阵
    
    %学习率
    alpha1 = 0.06;                  % W权重相关学习率
    alpha2 = 0.02;                  % V权重相关学习率
    
    % 动量因子
    beta1 = 0.9;
    beta2 = 0.9;
    
    % 限幅值
    xmax = 1;
    ymax = 1;
    umax = 1;
    
    % 变量初始化,_1 结尾为上一次的值,_2 结尾表示上两个时刻值
    yi3_1 = 0;                      
    u_1 = 0;
    u_2 = 0;
    x_1 = 0;
    yi2_1 = 0;
    yo3_1 = 0;
    dW = 0;                         % W变化量,初始化为0
    dV = 0;
    yo = zeros(3,1);     
    
    xdata = [];                     % 记录实际值
    zdata = [];                     % 记录期望值
    
    N = 2000;                       % 迭代次数
    for k=1:N
        %% 设置目标值
        if k <500
            z = 0.5;
        elseif k < 1000
            z = 0.2;
        elseif k < 1500 
            z = 0.8;
        else
            z = 0;
        end
        
        %% 正向传播
        % 隐含层输入
        yi = W * [z; x];                
        
        % 隐含层输出
        yo(1) = yi(1);                  % P  
        yo(2) = yo(2) + yi(2);          % I
        yo(3) = yi(3) - yi3_1;          % D
        yo(find(yo>ymax)) = ymax;       % 限幅
        yo(find(yo<-ymax)) = -ymax;
        
        % 输出层输出
        u = V' * yo;                    
        u(find(u>umax)) = umax;
        u(find(u<-umax)) = -umax;
        
        % 受控对象输出
        x = u^2 + 0.1*x_1;                  
        x(find(x>xmax)) = xmax;         
        x(find(x<-xmax)) = -xmax;
        
        % 损失函数
        J = 1/2 * (z-x)^2;              
    
        %% 反向传播
        
        % 计算J对V的偏导数 pJ_pV
        pJ_px = -(z-x);
        
        temp = u - u_1;                     % u(k)-u(k-1)
        if temp >= 0 && temp < 1e-20        % 除数限幅在(-,-1e-20][1e-20,+)
            temp = 1e-20;                   % 防止除数为0
        elseif temp < 0 && temp > -1e-20
            temp = -1e-20;
        end
        px_pu = sign((x - x_1) / temp);     % 使用sign,限幅在{-1,0,1}
        
        pJ_pV = pJ_px * px_pu * yo;         % 误差对V的偏导,yo为3x1向量
        
        % 计算J对W的偏导数 pJ_pW
        pJ_pw11 = pJ_px * px_pu * V(1) * 1 * z;
        pJ_pw12 = pJ_px * px_pu * V(1) * 1 * x;
        
        temp = yi(2) - yi2_1;               % yi(k) - yi(k-1)
        if temp >= 0 && temp < 1e-20        % 除数限幅在(-,-1e-20][1e-20,+)
            temp = 1e-20;                   % 防止除数为0
        elseif temp < 0 && temp > -1e-20
            temp = -1e-20;
        end
        pJ_pw21 = pJ_px * px_pu * V(2) * (sign(yi(2)/temp)) * z;
        pJ_pw22 = pJ_px * px_pu * V(2) * (sign(yi(2)/temp)) * x;
    
        temp = yo(3) ;                      % yo(k)
        if temp >= 0 && temp < 1e-20        % 除数限幅在(-,-1e-20][1e-20,+)
            temp = 1e-20;                   % 防止除数为0
        elseif temp < 0 && temp > -1e-20
            temp = -1e-20;
        end
        pJ_pw31 = pJ_px * px_pu * V(3) * (sign((yo(3) - yo3_1)/temp)) * z;
        pJ_pw32 = pJ_px * px_pu * V(3) * (sign((yo(3) - yo3_1)/temp)) * x;
      
        pJ_pW = [pJ_pw11, pJ_pw12; pJ_pw21, pJ_pw22; pJ_pw31, pJ_pw32]; % 误差对W的偏导
        
        %% 动量法权重更新
        dW = beta1 * dW + (1-beta1) * pJ_pW;        % 动量法计算增量
        dV = beta2 * dV + (1-beta2) * pJ_pV;
        
        W = W - alpha1 * dW;                        % 权重更新
        V = V - alpha2 * dV;
        
        %% 其他数据更新
        u_2 = u_1;
        u_1 = u;                                    % u(k-1)
        x_1 = x;                                    % x(k-1)
        yi2_1 = yi(2);                              % yi2_1 为上一次 yi(2)
        yo3_1 = yo(3);                              % yo3_1 为上一次 yo(3)
        
        xdata = [xdata; x];                         % 记录数据方便绘图
        zdata = [zdata; z];
    end
    
    %% 可视化
    plot(1:N, zdata, 'LineWidth',1.5);hold on;      % 目标值
    plot(1:N, xdata, '.'); hold off                 % 实际值
    legend('目标值','实际值')                        % 标注
    title('PID神经网络');                           % 标题
    

    运行结果如下

    在这里插入图片描述

    可见,跟踪效果很不错。不过,和所有神经网络一样,参数要小心谨慎,如果设置不合理,就达不到期望的效果。


    四、总结与展望

    和PID和神经网络相比,PID神经网络有什么美妙之处呢?其实,它结合了两者的优势,PID使用了反馈控制,好的PID参数使得实际值快速稳定地接近目标值,但是有时候很难调节出一组好的PID参数。神经网络的优势是,通过误差反馈传播调整权值,这个过程是自动完成的。PID参数已经通过权值的方式隐藏在网络结构中,使用反向传播时该参数自动得到优化。

    其实,PID神经网络大显身手的地方是多输入多输出的耦合系统的控制,下一次,就用来做一个无人机姿态控制器。

    — 完 —

    展开全文
  • PID应用实例,神经网络温控,PID的经典应用,PID深入学习不可多得的好资料
  • PID神经网络控制算法具有较好的动态和稳态性能、很强的解藕能力和杭干扰能力,适用于非线性多变量藕合系统的解藕控制。在对PID神经网络控制算法研究的基础上,提出了基于量子粒子群权值修正多变量PID神经网络...
  • 改进PID 神经网络控制用于湿法烟气脱硫,实现高度自适应,低超调
  • 设计了一种基于比例、积分、微分的神经网络(single-out PID proportion integral derivative neural network,SPIDNN)自适应网络功率机制来动态调整无线体域网中传感器节点的发射功率控制方法,利用具有自学习的...
  • 带钢热连札机活套系统是一个耦合的多...利用基于蚁群优化多个单神经元和RBF神经网络相结合的自适应控制策略以减弱系统的耦合影响.最后的仿真结果验证了本方法的有效性,表明解耦后的活套控制系统可获得更好的控制效果.
  • PIDControl神经网络PID PIDControl神经网络PID
  • 神经网络PID论文

    2018-05-16 14:26:40
    神经网络PID论文神经网络PID论文神经网络PID论文神经网络PID论文神经网络PID论文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 717
精华内容 286
关键字:

pid神经网络