PID神经网络控制

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

NNI辨识器

  输入层为
u ( k ) , u ( k − 1 ) , … , u ( k − n u + 1 ) , y ( k ) , y ( k − 1 ) , … , y ( k − n y + 1 ) u(k),u(k-1),\dots,u(k-n_u+1),y(k),y(k-1),\dots,y(k-n_y+1) u(k),u(k1),,u(knu+1),y(k),y(k1),,y(kny+1)
  输出层为一个量,训练的目标函数为
J = 1 2 ( y ( k + 1 ) − y ^ ( k + 1 ) ) 2 J=\frac{1}{2}(y(k+1)-\hat{y}(k+1))^2 J=21(y(k+1)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

猜你喜欢

转载自blog.csdn.net/wanchaochaochao/article/details/84958493
今日推荐