解决Matlab 调用训练好的BP网络的权值和阀值算出来的预测值和调用sim得到的值不一样的办法 |
您所在的位置:网站首页 › matlab优化模型怎么导出结果数据 › 解决Matlab 调用训练好的BP网络的权值和阀值算出来的预测值和调用sim得到的值不一样的办法 |
解决方法
解决方法很简单:自己通过训练好的权值和阈值计算时,归一化和反归一化的范围应该设为(-1,1),而不是(0,1)。 也就是从原来的: [p_train, ps_input] = mapminmax(Id',0,1); [t_train, ps_output] = mapminmax(train_y',0,1);改为: [p_train, ps_input] = mapminmax(Id',-1,1); [t_train, ps_output] = mapminmax(train_y',-1,1);本文在这篇论坛上得到提示:Matlab训练好BP神经网络后,怎么根据权值和阈值来计算呢? 此方法仅供参考,可能大家的情况有所不同,希望对大家有帮助。 以上为原回答 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 以下为10月10日更新 之前在评论区答应了过几天就补全回答,没想到一下子耽搁了3个月,实在是抱歉! 之前的答案这一句话“自己通过训练好的权值和阈值计算时”有误,应该是在一开始训练BP神经网络的时候就把归一化和反归一化的范围设为(-1,1),而不是采用(0,1),对了,我用的matlab版本为2019b。 以下将以经典的BP神经网络——基于近红外光谱的汽油辛烷值预测为例原始的程序和数据集大家可以自行百度、google或者在github上寻找,我在文中也会给出程序,找不到数据集的人可以说自己邮箱,我看到的话会回,不过我后面也挺忙的,不保证及时性。 原始的BP神经网络程序如下: %% I. 清空环境变量 clear all close all clc %% II. 训练集/测试集产生 %% % 1. 导入数据 load spectra_data.mat %% % 2. 随机产生训练集和测试集 temp = randperm(size(NIR,1)); % 训练集——50个样本 P_train = NIR(temp(1:50),:)'; T_train = octane(temp(1:50),:)'; % 测试集——10个样本 P_test = NIR(temp(51:end),:)'; T_test = octane(temp(51:end),:)'; N = size(P_test,2); %% III. 数据归一化 [p_train, ps_input] = mapminmax(P_train,0,1); p_test = mapminmax('apply',P_test,ps_input); [t_train, ps_output] = mapminmax(T_train,0,1); %% IV. BP神经网络创建、训练及仿真测试 %% % 1. 创建网络 net = newff(p_train,t_train,8); %% % 2. 设置训练参数 net.trainParam.epochs = 1000;%最大训练次数设置 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); %% V. 性能评价 %% % 1. 相对误差error error = abs(T_sim - T_test)./T_test; %% % 2. 决定系数R^2 R2 = (N * sum(T_sim .* T_test) - sum(T_sim) * sum(T_test))^2 / ((N * sum((T_sim).^2) - (sum(T_sim))^2) * (N * sum((T_test).^2) - (sum(T_test))^2)); %% % 3. 结果对比 result = [T_test' T_sim' error'] %% VI. 绘图 figure plot(1:N,T_test,'b:*',1:N,T_sim,'r-o') legend('真实值','预测值') xlabel('预测样本') ylabel('辛烷值') string = {'测试集辛烷值含量预测结果对比';['R^2=' num2str(R2)]}; title(string)从上述程序中我们可以发现,在数据归一化的位置是将范围设定在(0,1)之间,但是我在实际操作中发现,在照搬根据(0,1)归一化的mapminmax函数的参数后,计算出来的神经网络输出值和原神经网络的不同,那么怎么解决这个问题呢,就像我前面说的,我们只需要将上面的原始BP神经网络的归一化范围改为(-1,1)。具体的原因我也没想明白,我猜也许matlab内部的调用函数不太一样,如果有大佬知道的请多多指教。 现在让我们将上述程序中的这部分: %% III. 数据归一化 [p_train, ps_input] = mapminmax(P_train,0,1); p_test = mapminmax('apply',P_test,ps_input); [t_train, ps_output] = mapminmax(T_train,0,1);改为 %% III. 数据归一化 [p_train, ps_input] = mapminmax(P_train,-1,1); p_test = mapminmax('apply',P_test,ps_input); [t_train, ps_output] = mapminmax(T_train,-1,1);这样改变归一化范围并不会对神经网络预测精确度产生什么影响。 运行更改后的BP神经网络主程序之后,我们就可以得到如下的预测结果图: 同时我们在工作区中会得到大量的计算变量,如下图: 方法二就不细说了,其他文章中已经有提到过,想弄明白的同学可以参看help中“network”的文档。 方法一则是运行genFunction函数,然后点击命令行窗口的“edit neural_function”: 和sigmoid的传递函数: % Sigmoid Symmetric Transfer Function function a = tansig_apply(n,~) a = 2 ./ (1 + exp(-2*n)) - 1; end我在后续自行建立训练好的神经网络时既是参考的上图的循环算式。具体程序如下: % clear all % close all % clc %% 创建神经网络参数 % Layer 1;b1:隐含层偏移量;IW1_1:隐含层权值 b1 = [1.3748057355138554314;-1.0270389076505417325]; IW1_1 = [-0.033329920682804686782 -0.046980249869347533165]; % Layer 2;b2:输出层偏移量;LW2_1:输出层权值 b2 = -0.70620702517192035508; LW2_1 = [-0.50069237473355243662 -0.31059943234833836678]; %% 计算 p_test1 = mapminmax('apply',P_test,ps_input); a1 = tansig(b1+IW1_1*p_test1); a2 =b2+LW2_1*a1; T_sim_t = mapminmax('reverse',a2,ps_output); %% 作图 figure(1) plot(1:N,T_sim,'r-o'); hold on plot(1:N,T_sim_t,'b-*');上述代码中,前三行加引号是因为还需要使用之前得到的变量“ps_input”和“ps_output”,避免直接点运行按钮就把之前的变量都删除掉了,另外,这里的b1、b2、IW、LW这么短是因为本来的变量参数有401列,全部放出来太长了,在这里我就略去了,大家自己弄的时候注意。 以下是运行结果图,其中红色是原始神经网络的计算结果,蓝色是我们提取出训练好的net参数的计算结果: 可以看到和原始训练好的神经网络结果完全一致,但是假如我们还是采用(0,1)的归一化范围的话,得到的对比图则如下: |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |