本贴内容如题所示,如何将训练好的BP神经网络加入到simulink中去运行,这只是我个人使用的,能够正常运行的办法,肯定不是最优的,大佬们请赐教。
以一个简单的sin函数曲线拟合为例,先在simulink中创建一个模型:
clock模块用于生成sin函数输入值,sin模块生成sin函数输出值,用to workspace模块将这两组数据导入到工作区,就可以在.m文件中训练神经网络,直接给出代码,具体不再赘述:
clear all
close all
clc%% 加载数据集 一阶
train_x1(:,1)=time.signals.values;%% 数据归一化[p_train, ps_input] = mapminmax(train_x1',-1,1);%归一化到0~1,ps_input用于记录规范方式
[t_train, ps_output] = mapminmax(value.signals.values',-1,1); %选择对应的预期输出
p_test = mapminmax('apply',train_x1',ps_input);%使用和P_train相同的规范方式,加apply便于恢复%% 创建BP神经网络
net=newff(p_train,t_train,20);%隐含层神经元个数设为20%%
% 2. 设置训练参数
net.trainParam.epochs = 10000;%最大训练次数设置
net.trainParam.goal = 1e-3;%训练目标设置,及要求精度
net.trainParam.lr = 0.01;%学习率设置,应设置为较小值%%
% 3. 训练网络
net = train(net,p_train,t_train);%%
% 4. 仿真测试
t_sim = sim(net,p_test);%%
% 5. 数据反归一化
T_sim = mapminmax('reverse',t_sim,ps_output);%% 作图
figure(1)
plot(train_x1,value.signals.values,'r-'); %选择对应预期输出
hold on
plot(train_x1,T_sim,'b-');
grid on
legend('原数据','BP拟合');
输出的拟合图为:
现在的问题就是如何将训练好的BP神经网络提取出来,加入到simulink中去,此处参考我上一篇帖:解决Matlab 调用训练好的BP网络的权值和阀值算出来的预测值和调用sim得到的值不一样的办法
先提取出训练好的BP神经网络的权值和阈值,然后,不同的是,还需要提取出数据归一化和反归一化的函数参数,也就是这两个结构体:
为了避免不必要的错误,我直接将其中的内容完整复制出来:
需要的全部网络数据明确之后,下面就是在simulink中创建神经网络函数,这里我选用的MATLAB Function函数:
将其拖动到model中后,双击打开,进行编辑,具体代码如下:
function sys = BP_net(u1) %有几个输入就定义几个变量,例如2个输入:fcn(u1,u2)coder.extrinsic('mapminmax');%不将mapminmax翻译成C代码
coder.extrinsic('tansig');persistent b1 IW1_1 b2 LW2_1 ps_input ps_output %生成固定变量,在调用计算过程中不变% Layer 1;b1:隐含层偏移量;IW1_1:隐含层权值
b1 = [27.420986881857594142;-24.035306170152026084;-21.48982045114150452;18.118421638180077338;15.864187530977879703;-12.270858280260254602;10.162559254726184932;-6.5065879166277476031;4.6143489594881925697;-0.91995155952595752957;0.88446681727870790635;4.6511614019105227413;6.5574536128762499487;10.152529191225546867;-12.278170895630950099;15.822363204867803788;18.104641849968665213;21.099791230150902521;-23.885361613907630129;27.39136905043323722];
IW1_1 = [-28.303152569733860844;28.765055085725990125;27.976290533978836805;-28.597119579577132242;-27.898512867355304223;28.339650509273319301;-27.675489633829634784;28.022886336353849401;-27.658714805300217421;27.732029694139118448;27.704122686704440781;27.756404515943916778;28.118241843490956455;27.541458059161005423;-28.268307275911229937;27.950935389110387774;28.731646365610316707;27.123395035695370581;-28.971112770175157181;28.287588676328923043];% Layer 2;b2:输出层偏移量;LW2_1:输出层权值
b2 = 0.015261982214380853673;
LW2_1 = [-0.56915827690484899204 -0.4786645496342156747 -0.53806089296510162256 -0.49244972088251748321 -0.5262527475867443405 -0.50898229938079053714 0.5114179326252423774 0.51601063159244642264 -0.50853440295316543196 -0.50866904990590033897 -0.51474685465147063113 0.51775186515479987293 0.50088019511102221948 -0.52537057536577713712 0.49075125044764195126 0.49211607894673420338 0.50744104200323847387 -0.56580761348584462933 0.43017099192472918467 0.55054317136357910911];%创建归一化参数结构体:
ps_input.gain=[20];%
ps_input.xoffset=[0];%
ps_input.ymin=[-1];
ps_input.ymax=[1];
ps_input.name=['mapminmax'];
ps_input.xrows=[3];
ps_input.xmax=[0.100000000000000];%
ps_input.xmin=[0];%
ps_input.xrange=[0.1];%
ps_input.yrows=[1];
ps_input.yrange=[2];
ps_input.no_change=[false];%创建反归一化参数结构体:
ps_output.gain=[1];%
ps_output.xoffset=[-1];%
ps_output.ymin=[-1];
ps_output.ymax=[1];
ps_output.name=['mapminmax'];
ps_output.xrows=[1];
ps_output.xmax=[1];%
ps_output.xmin=[-1];%
ps_output.xrange=[2];%
ps_output.yrows=[1];
ps_output.yrange=[2];
ps_output.no_change=[false];%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%初始化变量
p_test=zeros(1,1); %此处的行数要等于BP神经网络输入层神经元个数
a1=zeros(20,1); %此处的行数要等于BP神经网络隐含层神经元个数
a2=0;
Parameter_value=0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%z=zeros(1,1); %此处的行数要等于BP神经网络输入层神经元个数z(1,1)=u1; %每行对应一个输入变量,如果两个输入,还应加上:z(2,1)=u2;p_test = mapminmax('apply',z,ps_input);a1 = tansig(b1+IW1_1*p_test); a2 =b2+LW2_1*a1;Parameter_value = mapminmax('reverse',a2,ps_output);f=Parameter_value;sys=f;
代码内容就不再进行详细解释,有必要的地方都注释出来了。
最后在simulink中检验效果:
示波器输出为:
讲解完毕,有问题请评论。