当前位置:   article > 正文

GA-BP遗传优化神经网络预测改动(新版本MATLAB中神经网络训练窗口的一些变化)_如何设置bp里用于训练的比例

如何设置bp里用于训练的比例

又经过几个月的学习

在之前发布的文章中可以改进一下

之前没有对收集的数据划分训练集和测试集

BP神经网络算法模块中

训练时将所有输入数据和输出数据当成了训练集

因此,才在BP神经网络梯度训练设置了for循环

for循环很大程度上提高了网络中的训练集的性能

并存储了每次循环训练的误差和仿真预测结果

在for循环结束后

才根据最小误差索引到对应的仿真预测数据

☆☆☆

按道理来说神经网络应该自行划分了比例

所以,之前的模型应该是

将所有输入、输出数据当成了训练集来训练

然后网络又默认选取了35%比例的数据来验证

(显然没有意义了)

训练效果也挺好

经查阅资料

该模型是一种短时间内的时间序列预测模型

意思就是仅仅只是在数据拟合方面做得很好

在长时间上

数据的预测是没有依据性的

因为神经网络学习数据特征训练时

会忘记先前学习的特征

所以每次训练完预测的结果相差会很大

下面将按一定比例随机划分数据

以及仿真预测后

将训练出的数据和仿真预测的数据

运用索引的操作矩阵重组

从而与真实数据作一比较

↓↓↓↓↓

  1. clear;
  2. clc;
  3. close all;
  4. %% 实验数据导入及整理
  5. data1=[1.87,2.07,2.25,2.4,2.5,2.64,2.7,2.9,3.1,3.25,3.4,3.72,3.95];%2009年~2021年的机动车数量/(亿辆)
  6. data2=[41.19,42.05,45.33,47.49,50.96,52.88,56.18,60.86,65.12,67.34,69.33,70.44,70.94];%2009年~2021年的公共汽电车数量/(万辆)
  7. data3=[25460,32237,35884,38243,41738,45052,48905,52789,56786,60590,65730,70643,75770];%2009年~2021年的公共汽电车线路数/(条)
  8. data4=[28.92,63.37,67.29,71.46,74.89,81.78,89.43,98.12,106.9,119.9,133.6,148.21,159.38];%2009年~2021年的公共汽电车线路网里程/(万公里)
  9. data5=[186.63,317.86,331.73,346.82,348.96,346.69,352.33,358.32,355.2,346.1,354.13,302.79,335.27];%2009年~2021年的公共汽电车运营里程/(亿公里)
  10. data6=[742.91,670.12,715.79,749.8,771.17,781.88,765.4,745.23,722.87,697,691.76,442.36,489.16];%2009年~2021年的公共汽电车客流量/(亿人次)
  11. newdata=[4.3;70.45;76550;170;340];%每个值分别为2022年的:机动车数量、公共汽电车数量、线路数、线路网里程、运营里程
  12. x1=2009:1:2021; %定义实际值年份
  13. x2=2009:1:2022; %定义预测值年份
  14. P=[data1;data2;data3;data4;data5]; %特征数据
  15. T=data6; %目标数据
  16. nP=newdata; %预测特征数据

以上是和之前一样操作的数据整理操作

接下来会对整理好的数据按一定的比例随机划分

  1. %% 输入数据和输出数据数据的比例划分
  2. [~,g]=size(P);
  3. randIndex=randperm(g);
  4. k=ceil(0.75*g); %设置75%比例的数据作为训练数据
  5. trainIndex=sort(randIndex(1:k)); %随机选出特征数据的75%比例作为训练数据(这里先选出数据的序号)
  6. testIndex=sort(randIndex(k+1:g)); %将剩下的数据作为检验数据(这里先选出数据的序号)
  7. inputData_train=P(:,trainIndex); % 根据序号选出75%比例数据用于训练的输入
  8. inputData_test=P(:,testIndex); % 根据序号选出25%比例数据用于测试的输入
  9. outputData_train=T(:,trainIndex); % 根据序号选出75%比例数据用于训练的输出
  10. outputData_test=T(:,testIndex); % 根据序号选出25%比例数据用于测试的输出

有13组完整的数据

需要预测另1组中的1个数据

以上输入数据即特征数据

输出数据即目标数据

随机划分了13组数据中75%的比例作为训练集

(输入数据和输出数据各75%)

另外25%比例的数据作为测试集

这样就导致最后将测试数据代入网络

仿真预测出的结果只有25%比例的数据

所以最后还需要将划分的75%比例的数据

代入到网络中训练得到训练集训练出来的数据

另外也要将预测特征(输入)数据代入网络

得到预测的数据

因此,在测试数据代入仿真出结果

再计算误差后

就要将3组仿真的数据按一开始随机划分比例的顺序

排列成完整的输出数据(sim仿真后的)

↓↓↓↓↓

  1. %调用trainlm算法训练网络
  2. [net,tr]=train(net,inputdata_train_regular,outputdata_train_regular);
  3. %放入到网络输出数据
  4. outputData_train_regular=sim(net,inputdata_train_regular); %训练集的输出数据
  5. outputData_test_regular=sim(net,inputdata_test_regular); %测试集的输出数据
  6. nT_regular=sim(net,nP_regular); %预测数据
  7. for rr=i
  8. q1=figure(1);
  9. plotperform(tr);
  10. set(q1,'Position',[280 610 560 420])
  11. q2=figure(2);
  12. plottrainstate(tr);
  13. set(q2,'Position',[1080 610 560 420])
  14. drawnow update;
  15. end
  16. %将得到的数据反归一化
  17. GA_BP_train=mapminmax('reverse',outputData_train_regular,PS2);
  18. GA_BP_test=mapminmax('reverse',outputData_test_regular,PS2);
  19. nT=mapminmax('reverse',nT_regular,PS2);
  20. %训练集、测试集、预测的输出数据矩阵重组
  21. GA_BP_data=ones(output_num,g);
  22. GA_BP_data(:,trainIndex)=GA_BP_train;
  23. GA_BP_data(:,testIndex)=GA_BP_test;
  24. %计算每次实验误差
  25. errors_nn=sum(abs(GA_BP_data-T)./(T))/length(T);
  26. n_EcRMSE=sqrt(sum((errors_nn).^2)/length(errors_nn));

上面是重组后再计算整体训练的误差

其中的for循环次数是根据梯度训练次数i同步的

循环的内容是将神经网络每次训练的性能和状态窗口显示出来

3c088be37cdf44dcbf935ebc660c5e52.png

8271ee3f8cb446afa948239efbb23bc7.png

 模型运行时可观察上面两个图

来判断训练是否过拟合

即训练数据上表现良好但在验证数据或测试数据上表现不佳

  1. %设置训练参数
  2. net.trainParam.lr=0.0001; %学习率
  3. net.trainparam.show=400; %每训练400次展示一次结果
  4. net.trainParam.goal=0.0001; %目标误差
  5. net.trainparam.epochs=15000; %最大训练次数
  6. net.trainParam.showWindow=1; %BP训练窗口
  7. net.divideParam.trainRatio=0.8; % 用于训练的数据比例
  8. net.divideParam.valRatio=0.2; % 用于验证过拟合的数据比例
  9. net.divideParam.testRatio=0; % 注意要关掉测试数据占比

可以调试上面训练参数

来指导神经网络进行训练

防止神经网络训练时一直处于过拟合情况出现

因为一开始对数据划分过比例

所以要将测试数据占比给关掉

b42005e1a04b41b78f481f03ebdab14f.png

 这是新版本MATLAB2022b

神经网络训练窗口改成这样了

若打开的话,不建议再在神经网络算法模块中

添加for循环多次训练

因为新版本MATLAB的神经网络训练窗口

每循环一次都会关闭上一次的训练窗口

然后再打开该次的训练窗口

会花费比较久的时间

不会像之前版本的训练窗口每循环一次窗口数据更新一次

就起不到人为强制干涉神经网络训练次数的作用了

或者可以关闭神经网络训练窗口

1459902f3825457c9d2fbe463ec588eb.png

这是新版本的神经网络结构图 

总之,新版版MATLAB

对于智能算法优化、数据运算方面运行快了很多

也有很多辅助检查分析的工具

据本人测试

好像是新版本MATLAB不需要对变量大小先前设置

设置前和设置后运行时间差不多

甚至设置变量大小后消耗时间还多一点点

但是不设置的话

目前新版本还是会警告提醒建议你设置变量迭代大小

附上源代码:(可结合之前发的一版对比看)

↓↓↓↓↓

  1. clear;
  2. clc;
  3. close all;
  4. %% 实验数据导入及整理
  5. data1=[1.87,2.07,2.25,2.4,2.5,2.64,2.7,2.9,3.1,3.25,3.4,3.72,3.95];%2009年~2021年的机动车数量/(亿辆)
  6. data2=[41.19,42.05,45.33,47.49,50.96,52.88,56.18,60.86,65.12,67.34,69.33,70.44,70.94];%2009年~2021年的公共汽电车数量/(万辆)
  7. data3=[25460,32237,35884,38243,41738,45052,48905,52789,56786,60590,65730,70643,75770];%2009年~2021年的公共汽电车线路数/(条)
  8. data4=[28.92,63.37,67.29,71.46,74.89,81.78,89.43,98.12,106.9,119.9,133.6,148.21,159.38];%2009年~2021年的公共汽电车线路网里程/(万公里)
  9. data5=[186.63,317.86,331.73,346.82,348.96,346.69,352.33,358.32,355.2,346.1,354.13,302.79,335.27];%2009年~2021年的公共汽电车运营里程/(亿公里)
  10. data6=[742.91,670.12,715.79,749.8,771.17,781.88,765.4,745.23,722.87,697,691.76,442.36,489.16];%2009年~2021年的公共汽电车客流量/(亿人次)
  11. newdata=[4.3;70.45;76550;170;340];%每个值分别为2022年的:机动车数量、公共汽电车数量、线路数、线路网里程、运营里程
  12. x1=2009:1:2021; %定义实际值年份
  13. x2=2009:1:2022; %定义预测值年份
  14. P=[data1;data2;data3;data4;data5]; %特征数据
  15. T=data6; %目标数据
  16. nP=newdata; %预测特征数据
  17. %% 输入数据和输出数据数据的比例划分
  18. [~,g]=size(P);
  19. randIndex=randperm(g);
  20. k=ceil(0.75*g); %设置75%比例的数据作为训练数据
  21. trainIndex=sort(randIndex(1:k)); %随机选出特征数据的75%比例作为训练数据(这里先选出数据的序号)
  22. testIndex=sort(randIndex(k+1:g)); %将剩下的数据作为检验数据(这里先选出数据的序号)
  23. inputData_train=P(:,trainIndex); % 根据序号选出75%比例数据用于训练的输入
  24. inputData_test=P(:,testIndex); % 根据序号选出25%比例数据用于测试的输入
  25. outputData_train=T(:,trainIndex); % 根据序号选出75%比例数据用于训练的输出
  26. outputData_test=T(:,testIndex); % 根据序号选出25%比例数据用于测试的输出
  27. %% 实验数据归一化
  28. [inputdata_train_regular,PS1]=mapminmax(inputData_train,-1,1);
  29. [outputdata_train_regular,PS2]=mapminmax(outputData_train,-1,1);
  30. inputdata_test_regular=mapminmax('apply',inputData_test,PS1);
  31. nP_regular=mapminmax('apply',nP,PS1);
  32. %% 实验参数初始化
  33. input_num=size(inputData_train,1); %输入特征个数
  34. output_num=size(outputData_train,1); %输出特征个数
  35. hidden_num1=6; %第一层隐藏层神经元个数
  36. hidden_num2=5; %第二层隐藏层神经元个数
  37. group_num=500; %种群规模
  38. cross_pro=0.6; %交叉概率
  39. mutation_pro=0.04; %变异概率,相对来说比较小
  40. %这个优化的主要思想就是优化网络参数的初始选择,初始选择对于效果好坏是有较大影响的
  41. num_all=input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2+hidden_num2*output_num+output_num; %节点总数
  42. lenchrom=ones(1,num_all); %种群总长度
  43. limit=[-1*ones(num_all,1) 1*ones(num_all,1)]; %初始参数给定范围
  44. %% 实验参数设置
  45. num_iter_all=35; %GA-BP实验次数
  46. iter_num=300; %GA迭代循环次数
  47. num=1; %BP梯度下降训练循环次数
  48. input_data=inputdata_train_regular;
  49. output_data=outputdata_train_regular;
  50. % 实验变量存储
  51. TIME=ones(1,num_iter_all);
  52. test=ones(num_iter_all,length(x2));
  53. EMS_all=ones(1,num_iter_all);
  54. %% 实验开始
  55. titlestr='实验运行中,请稍等......';
  56. mm=waitbar(0,titlestr);
  57. set(mm,'Position',[280 376.8750 270 56.2500])
  58. for NN=1:num_iter_all
  59. str=['实验运行第',num2str(NN),'次中,请稍等......'];
  60. waitbar(NN/num_iter_all,mm,str); %实验进度条
  61. t1=datetime('now');%每次实验开始的时间
  62. %% 基因编译
  63. %GA变量存储设置
  64. trace=ones(iter_num+1,2);
  65. initial_chrom=ones(group_num,num_all);
  66. fitness_group=ones(group_num,1);
  67. %GA种群初始化
  68. for i=1:group_num
  69. initial=rand(1,length(lenchrom)); %产生0-1的随机数
  70. initial_chrom(i,:)=limit(:,1)'+(limit(:,2)-limit(:,1))'.*initial; %变成染色体的形式,一行为一条染色体
  71. fitness_value=fitness(initial_chrom(i,:),input_num,hidden_num1,hidden_num2,output_num,input_data,output_data);%计算初始适应度
  72. fitness_group(i)=fitness_value;
  73. end
  74. [bestfitness,bestindex]=min(fitness_group);
  75. bestchrom=initial_chrom(bestindex,:); %最好的染色体
  76. avgfitness=sum(fitness_group)/group_num; %染色体的平均适应度
  77. trace(1,:)=[avgfitness bestfitness]; %记录每一代进化中最好的适应度和平均适应度
  78. %% 迭代过程
  79. input_chrom=initial_chrom;
  80. titlestr=('GA迭代中,请稍等......');
  81. kk=waitbar(0,titlestr);
  82. set(kk,'Position',[890 376.8750 270 56.2500])
  83. % 开始迭代
  84. for numa=1:iter_num
  85. str=['GA迭代第',num2str(numa),'次中,请稍等......',num2str(round(numa/iter_num*100)),'%'];
  86. waitbar(numa/iter_num,kk,str); %GA迭代进度条
  87. % 选择
  88. [new_chrom,new_fitness]=select(input_chrom,fitness_group,group_num); %把表现好的挑出来,还是和种群数量一样
  89. % 交叉
  90. new_chrom=Cross(cross_pro,lenchrom,new_chrom,group_num,limit);
  91. % 变异
  92. new_chrom=Mutation(mutation_pro,lenchrom,new_chrom,group_num,numa,iter_num,limit);
  93. % 计算每次迭代后的适应度
  94. for j=1:group_num
  95. sgroup=new_chrom(j,:); %个体
  96. new_fitness(j)=fitness(sgroup,input_num,hidden_num1,hidden_num2,output_num,input_data,output_data);
  97. end
  98. %找到最小和最大适应度的染色体及它们在种群中的位置
  99. [newbestfitness,newbestindex]=min(new_fitness);
  100. [worestfitness,worestindex]=max(new_fitness);
  101. % 代替上一次进化中最好的染色体
  102. if newbestfitness<bestfitness
  103. bestfitness=newbestfitness;
  104. bestchrom=new_chrom(newbestindex,:);
  105. end
  106. new_chrom(worestindex,:)=bestchrom;
  107. new_fitness(worestindex)=bestfitness;
  108. avgfitness=sum(new_fitness)/group_num;
  109. trace(numa+1,:)=[avgfitness bestfitness]; %记录每一代进化中最好的适应度和平均适应度
  110. end
  111. close(kk)
  112. %% 绘制适应度曲线图并保存
  113. nplot1(trace,iter_num,NN);
  114. %% 把遗传算法优化的最优初始阀值权值赋予网络预测
  115. %构建网络结构
  116. net=newff(inputdata_train_regular,outputdata_train_regular,[hidden_num1 hidden_num2],{'tansig','tansig','purelin'},'trainlm');
  117. %权值初始化
  118. w1=bestchrom(1:input_num*hidden_num1); %输入层和第一层隐藏层之间的权重参数
  119. B1=bestchrom(input_num*hidden_num1+1:input_num*hidden_num1+hidden_num1); %第一层隐藏层神经元的偏置
  120. w2=bestchrom(input_num*hidden_num1+hidden_num1+1:input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2); %第一层隐藏层和第二层隐藏层之间的权重参数
  121. B2=bestchrom(input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+1:input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2); %第二层隐藏层神经元的偏置
  122. w3=bestchrom(input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2+1:input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2+hidden_num2*output_num);%第二层隐藏层和输出层之间的权值参数
  123. B3=bestchrom(input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2+hidden_num2*output_num+1:input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2+hidden_num2*output_num+output_num);%输出层神经元的偏执
  124. %网络权值赋值
  125. net.iw{1,1}=reshape(w1,hidden_num1,input_num);
  126. net.lw{2,1}=reshape(w2,hidden_num2,hidden_num1);
  127. net.lw{3,2}=reshape(w3,output_num,hidden_num2);
  128. net.b{1}=reshape(B1,hidden_num1,1);
  129. net.b{2}=reshape(B2,hidden_num2,1);
  130. net.b{3}=reshape(B3,output_num,1);
  131. %设置训练参数
  132. net.trainParam.lr=0.0001; %学习率
  133. net.trainparam.show=400; %每训练400次展示一次结果
  134. net.trainParam.goal=0.0001; %目标误差
  135. net.trainparam.epochs=15000; %最大训练次数
  136. net.trainParam.showWindow=1; %BP训练窗口
  137. net.divideParam.trainRatio=0.8; % 用于训练的数据比例
  138. net.divideParam.valRatio=0.2; % 用于验证过拟合的数据比例
  139. net.divideParam.testRatio=0; % 注意要关掉测试数据占比
  140. %% 神经网络初始化
  141. %BP初始预测值
  142. outputData_test_regular=sim(net,inputdata_test_regular);
  143. %初始预测值反归一化
  144. GA_BP_test=mapminmax('reverse',outputData_test_regular,PS2);
  145. %计算初始预测误差
  146. errors_nn=sum(abs(GA_BP_test-outputData_test)./(outputData_test))/length(outputData_test);
  147. EcRMSE=sqrt(sum((errors_nn).^2)/length(errors_nn));
  148. %% 调用神经网络工具箱开始训练
  149. titlestr='BP训练中,请稍等......';
  150. nn=waitbar(0,titlestr);
  151. set(nn,'Position',[890 376.8750 270 56.2500])
  152. %训练变量存储
  153. ems_all=ones(1,num);
  154. Test=ones(num,length(x2));
  155. for i=1:num
  156. str=['BP梯度下降训练第',num2str(i),'次中,请稍等......',num2str(round(i/num*100)),'%'];
  157. waitbar(i/num,nn,str); %训练进度条
  158. %调用trainlm算法训练网络
  159. [net,tr]=train(net,inputdata_train_regular,outputdata_train_regular);
  160. %放入到网络输出数据
  161. outputData_train_regular=sim(net,inputdata_train_regular); %训练集的输出数据
  162. outputData_test_regular=sim(net,inputdata_test_regular); %测试集的输出数据
  163. nT_regular=sim(net,nP_regular); %预测数据
  164. for rr=i
  165. q1=figure(1);
  166. plotperform(tr);
  167. set(q1,'Position',[180 610 560 420])
  168. q2=figure(2);
  169. plottrainstate(tr);
  170. set(q2,'Position',[1180 610 560 420])
  171. drawnow update;
  172. end
  173. %将得到的数据反归一化
  174. GA_BP_train=mapminmax('reverse',outputData_train_regular,PS2);
  175. GA_BP_test=mapminmax('reverse',outputData_test_regular,PS2);
  176. nT=mapminmax('reverse',nT_regular,PS2);
  177. %训练集、测试集、预测的输出数据矩阵重组
  178. GA_BP_data=ones(output_num,g);
  179. GA_BP_data(:,trainIndex)=GA_BP_train;
  180. GA_BP_data(:,testIndex)=GA_BP_test;
  181. %计算每次实验误差
  182. errors_nn=sum(abs(GA_BP_data-T)./(T))/length(T);
  183. n_EcRMSE=sqrt(sum((errors_nn).^2)/length(errors_nn));
  184. %替代
  185. if n_EcRMSE<EcRMSE
  186. EcRMSE=n_EcRMSE;
  187. end
  188. %存储每次网络训练数据并选择最优值
  189. GA_BP_data=cat(2,GA_BP_data,nT);
  190. ems_all(:,i)=EcRMSE;
  191. Test(i,:)=GA_BP_data;
  192. [p,q]=min(ems_all); %q最小训练误差的次数
  193. EcRMSE=p;%p最小训练误差值
  194. GA_BP_data=Test(q,:);
  195. end
  196. close(nn)
  197. %% 绘制每次BP误差曲线图并保存
  198. h=nplot2(num,ems_all,NN);
  199. %% 存储每次实验相关数据
  200. EMS_all(:,NN)=EcRMSE;%存储每次实验误差
  201. test(NN,:)=GA_BP_data;
  202. %% 每次实验所耗时间存储
  203. t2=datetime('now'); %每次实验结束的时间
  204. dur=t2-t1;
  205. Time_all=seconds(dur);%实验所耗时间
  206. TIME(:,NN)=Time_all;%存储每次实验所耗时间
  207. time=sum(TIME);%实验总共所耗时间计算
  208. end
  209. close(mm)
  210. close all
  211. view(net) %显示网络拓扑图
  212. %% 实验结果整理
  213. %GA-BP迭代优化择优
  214. [m,n]=min(EMS_all); %索引最小误差的实验次数
  215. GA_BP_data=test(n,:);
  216. % 输出2022年的预测数据
  217. GA_BP=GA_BP_data(:,end);
  218. disp('2022年的预测客流量为:')
  219. disp(GA_BP)
  220. % 绘制曲线图
  221. [j,k]=nplot3(EMS_all,x1,x2,GA_BP_data,T,GA_BP);
  222. % 绘制结果提示窗口
  223. message=msgBox(num_iter_all,time,n,m,GA_BP);
  224. %% fitness函数
  225. function fitness_value=fitness(input_chrom,input_num,hidden_num1,hidden_num2,output_num,input_data,output_data)
  226. %该函数用来计算适应度值
  227. %input_chrom 输入种群
  228. %input_num 输入层的节点数,即数据特征数量
  229. %output_num 隐含层节点数,隐藏层神经元的个数
  230. %input_data 训练输入数据
  231. %output_data 训练输出数据
  232. %fitness_value 个体适应度值
  233. w1=input_chrom(1:input_num*hidden_num1); %输入层和第一层隐藏层之间的权重参数
  234. B1=input_chrom(input_num*hidden_num1+1:input_num*hidden_num1+hidden_num1); %第一层隐藏层神经元的偏置
  235. w2=input_chrom(input_num*hidden_num1+hidden_num1+1:input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2); %第一层隐藏层和第二层隐藏层之间的权重参数
  236. B2=input_chrom(input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+1:input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2); %第二层隐藏层神经元的偏置
  237. w3=input_chrom(input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2+1:input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2+hidden_num2*output_num);%第二层隐藏层和输出层之间的权值参数
  238. B3=input_chrom(input_num*hidden_num1+hidden_num1+hidden_num1*hidden_num2+hidden_num2+hidden_num2*output_num+1:end);%输出层神经元的偏执
  239. %网络权值赋值
  240. W1=reshape(w1,hidden_num1,input_num);
  241. W2=reshape(w2,hidden_num2,hidden_num1);
  242. W3=reshape(w3,output_num,hidden_num2);
  243. B1=reshape(B1,hidden_num1,1);
  244. B2=reshape(B2,hidden_num2,1);
  245. B3=reshape(B3,output_num,1);
  246. [~,n]=size(input_data);
  247. A1=tansig(W1*input_data+repmat(B1,1,n)); %需与main函数中激活函数相同
  248. A2=tansig(W2*A1+repmat(B2,1,n)); %需与main函数中激活函数相同
  249. A3=purelin(W3*A2+repmat(B3,1,n));
  250. error=sumsqr(output_data-A3);
  251. fitness_value=error; %误差即为适应度
  252. end
  253. %% select函数
  254. function [new_chrom,new_fitness]=select(input_chrom,fitness_group,group_num)
  255. % 用轮盘赌在原来的函数里选择
  256. % fitness_group 种群信息
  257. % group_num 种群规模
  258. % newgroup 选择后的新种群
  259. %求适应度值倒数
  260. fitness1=fitness_group; %个体适应度值
  261. %个体选择概率
  262. sumfitness=sum(fitness1);
  263. sumf=fitness1./sumfitness;
  264. %采用轮盘赌法选择新个体
  265. index=ones(1,group_num);
  266. for i=1:group_num %group_num为种群数
  267. pick=rand;
  268. while pick==0
  269. pick=rand;
  270. end
  271. for j=1:group_num
  272. pick=pick-sumf(j);
  273. if pick<0
  274. index(1,i)=j;
  275. break;
  276. end
  277. end
  278. end
  279. %新种群
  280. new_chrom=input_chrom(index,:);
  281. new_fitness=fitness_group(index);
  282. end
  283. %% Cross函数
  284. function new_chrom=Cross(cross_pro,lenchrom,input_chrom,group_num,limit)
  285. %随机选择两个染色体位置交叉
  286. % cross_pro 交叉概率
  287. % lenchrom 染色体的长度,即所有参数的数量
  288. % input_chrom 染色体群,经过选择遗传下来的表现比较好的
  289. % group_num 种群规模
  290. % new_chrom 交叉后的染色体
  291. for i=1:group_num %每一轮for循环中,可能会进行一次交叉操作,染色体是随机选择的,交叉位置也是随机选择的,
  292. %但该轮for循环中是否进行交叉操作则由交叉概率决定(continue控制)
  293. pick=rand(1,2); % 随机选择两个染色体进行交叉
  294. while prod(pick)==0 %连乘
  295. pick=rand(1,2);
  296. end
  297. index=ceil(pick.*group_num); % 交叉概率决定是否进行交叉
  298. pick=rand;
  299. while pick==0
  300. pick=rand;
  301. end
  302. if pick>cross_pro
  303. continue;
  304. end
  305. % 随机选择交叉位
  306. pick=rand;
  307. while pick==0
  308. pick=rand;
  309. end
  310. flag=0;
  311. while flag==0
  312. pos=ceil(pick*length(lenchrom)); %随机选择进行交叉的位置,即选择第几个变量进行交叉,注意:两个染色体交叉的位置相同
  313. pick=rand; %交叉开始
  314. v1=input_chrom(index(1),pos);
  315. v2=input_chrom(index(2),pos);
  316. input_chrom(index(1),pos)=pick*v2+(1-pick)*v1;
  317. input_chrom(index(2),pos)=pick*v1+(1-pick)*v2; %交叉结束
  318. %判断交叉后的两条染色体可不可行
  319. limit1=mean(limit);
  320. f11=isempty(find(input_chrom(index(1),:)>limit1(2), 1));
  321. f12=isempty(find(input_chrom(index(1),:)<limit1(1), 1));
  322. if f11*f12==0
  323. flag1=0;
  324. else
  325. flag1=1;
  326. end
  327. f21=isempty(find(input_chrom(index(2),:)>limit1(2), 1));
  328. f22=isempty(find(input_chrom(index(2),:)<limit1(1), 1));
  329. if f21*f22==0
  330. flag2=0;
  331. else
  332. flag2=1;
  333. end
  334. if flag1*flag2==0
  335. flag=0;
  336. else
  337. flag=1;
  338. end %如果两个染色体不是都可行,则重新交叉
  339. end
  340. end
  341. new_chrom=input_chrom;
  342. end
  343. %% Mutation函数
  344. function new_chrom=Mutation(mutation_pro,lenchrom,input_chrom,group_num,num,iter_num,limit)
  345. % 本函数完成变异操作
  346. % mutation_pro 变异概率
  347. % lenchrom 染色体长度
  348. % input_chrom 输入交叉过后的染色体
  349. % group_num 种群规模
  350. % iter_num 最大迭代次数
  351. % limit 每个个体的上限和下限
  352. % num 当前迭代次数
  353. % new_chrom 变异后的染色体
  354. for i=1:group_num %每一轮for循环中,可能会进行一次变异操作,染色体是随机选择的,变异位置也是随机选择的,
  355. %但该轮for循环中是否进行变异操作则由变异概率决定(continue控制)
  356. % 随机选择一个染色体进行变异
  357. pick=rand;
  358. while pick==0
  359. pick=rand;
  360. end
  361. index=ceil(pick*group_num);
  362. % 变异概率决定该轮循环是否进行变异
  363. pick=rand;
  364. if pick>mutation_pro
  365. continue;
  366. end
  367. flag=0;
  368. while flag==0
  369. % 变异位置
  370. pick=rand;
  371. while pick==0
  372. pick=rand;
  373. end
  374. pos=ceil(pick*sum(lenchrom)); %随机选择了染色体变异的位置,即选择了第pos个变量进行变异
  375. pick=rand; %变异开始
  376. fg=(pick*(1-num/iter_num))^2;
  377. if pick>0.5
  378. input_chrom(index,pos)=input_chrom(index,pos)+(limit(pos,2)-input_chrom(index,pos))*fg;
  379. else
  380. input_chrom(index,pos)=input_chrom(index,pos)-(input_chrom(index,pos)-limit(pos,1))*fg;
  381. end %变异结束
  382. limit1=mean(limit);
  383. f1=isempty(find(input_chrom(index,:)>limit1(2), 1));
  384. f2=isempty(find(input_chrom(index,:)<limit1(1), 1));
  385. if f1*f2==0
  386. flag=0;
  387. else
  388. flag=1;
  389. end
  390. end
  391. end
  392. new_chrom=input_chrom;
  393. end
  394. %% nplot1函数
  395. function h=nplot1(trace,iter_num,NN)
  396. %该函数用来绘制GA适应度迭代曲线图
  397. h=figure('visible','off');
  398. [r ,~]=size(trace);
  399. plot((1:r)',trace(:,2),'b--');
  400. titlestr=['GA适应度曲线 ','终止代数=',num2str(iter_num),'',num2str(NN),'次实验优化'];
  401. title(titlestr);
  402. xlabel('进化代数');ylabel('适应度');
  403. legend('最佳适应度');
  404. set(gca,'xlim',[0,iter_num])
  405. titlestr=['',num2str(NN),'次实验GA适应度'];
  406. print(h,'-dpng',titlestr)
  407. end
  408. %% nplot2函数
  409. function h=nplot2(num,ems_all,NN)
  410. %该函数用来绘制BP误差训练图
  411. h=figure('visible','off');
  412. plot((1:num),ems_all,'b--');
  413. titlestr=['BP误差曲线 ','终止次数=',num2str(num),'',num2str(NN),'次实验优化'];
  414. title(titlestr);
  415. xlabel('训练次数');ylabel('误差百分比/(%)');
  416. legend('BP训练误差');
  417. set(gca,'xlim',[0,num])
  418. titlestr=['',num2str(NN),'次实验BP误差'];
  419. print(h,'-dpng',titlestr)
  420. end
  421. %% nplot3函数
  422. function [j,k]=nplot3(EMS_all,x1,x2,GA_BP_data,T,GA_BP)
  423. %该函数用来绘制GA-BP实验误差曲线图
  424. j=figure('visible','on');
  425. plot(EMS_all,'LineWidth',2)
  426. xlabel('实验优化次数')
  427. ylabel('误差/(%)')
  428. titlestr=('GA-BP实验误差曲线');
  429. title(titlestr)
  430. %绘制目标数据与预测数据曲线图
  431. k=figure;
  432. axy3=plot(x1,T,'b-o','linewidth',1);
  433. hold on
  434. axy4=plot(x2,GA_BP_data,'r--+','linewidth',1);
  435. xlabel('年份')
  436. ylabel('客流量/亿人次')
  437. titlestr=['GABP预测——我国城市公交系统车站客流量',' 2022年预测客流量为:',num2str(GA_BP),'亿人次'];
  438. title(titlestr)
  439. set(gca,'xtick',2009:1:2022);
  440. legend([axy3(1),axy4(1)],'真实数据','预测数据')
  441. axis([2009 2022 400 800])
  442. grid on
  443. end
  444. %% msgBox函数
  445. function message=msgBox(num_iter_all,time,n,m,GA_BP)
  446. %该函数用来显示实验结果提示窗口
  447. titlestr1=['实验',num2str(num_iter_all),'','所耗时间:',num2str(time),'',' 最小均方误差为: 第 ',num2str(n(1)),' 次的 ',num2str(m(1))];
  448. titlestr2=['2022年预测客流量为 : ',num2str(GA_BP),' 亿人次'];
  449. disp(titlestr1)
  450. disp(titlestr2)
  451. message=msgbox({titlestr1;titlestr2},'GA-BP模型预测结果');
  452. % 文本居中
  453. th = findall(0, 'Tag','MessageBox' );
  454. boxPosition = get(message,'position');
  455. textPosition = get(th, 'position');
  456. set(th, 'position', [boxPosition(3).*0.5 textPosition(2) textPosition(3)]);
  457. set(th, 'HorizontalAlignment', 'center');
  458. end

运行结果图

↓↓↓↓↓

22df1f50f6be4e90b9c3bb1cd4a7ba78.png47347e55ac1c4318ba20faa3b84b91eb.png

仅供学习参考

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/105588
推荐阅读
相关标签
  

闽ICP备14008679号