一、遗传算法简介
1 引言
2 遗传算法理论
2.1 遗传算法的生物学基础
2.2 遗传算法的理论基础
2.3 遗传算法的基本概念
2.4 标准的遗传算法
2.5 遗传算法的特点
2.6 遗传算法的改进方向
3 遗传算法流程
4 关键参数说明
二、BP神经网络简介
1 BP神经网络预测原理简介
BP 神经网络是一种多层前馈神经网络,常用的为输入层-单隐含层-输出层的三层结构,如下图所示。
BP神经网络训练的主要思想:输入的信号特征数据先映射到隐含层(激活函数实现),再映射到输出层(默认采用线性传递函数),得到期望输出值。将期望输出值和实际测量值做比较,计算误差函数J,再将误差反向传播,通过梯度下降等算法来调节BP网络的权值和阈值。重复该过程,直到满足设定的目标误差或者最大迭代次数等终止准则,停止训练。
通过下面的例子来理解每一层的作用。
1)输入层:相当于人的五官,五官获取外部信息,对应神经网络模型input端口接收输入数据的过程。 2)隐含层:对应人的大脑,大脑对五官传递来的数据进行分析和思考,神经网络的隐含层hidden Layer对输入层传来的数据x进行映射,简单理解为一个公式hiddenLayer_output=F(w*x+b)。其中,w、b叫做权重、阈值参数,F()为映射规则,也叫激活函数,hiddenLayer_output是隐含层对于传来的数据映射的输出值。换句话说,隐含层对于输入的影响因素数据x进行了映射,产生了映射值。 3)输出层:可以对应为人的四肢,大脑对五官传来的信息经过思考(隐含层映射)之后,再控制四肢执行动作(向外部作出响应)。类似地,BP神经网络的输出层对hiddenLayer_output再次进行映射,outputLayer_output=w *hiddenLayer_output+b。其中,w、b为权重、阈值参数,outputLayer_output是神经网络输出层的输出值(也叫仿真值、预测值)(理解为,人脑对外的执行动作,比如婴儿拍打桌子)。 4)梯度下降算法:通过计算outputLayer_output和神经网络模型传入的y值之间的偏差,使用算法来相应调整权重和阈值等参数。这个过程,可以理解为婴儿拍打桌子,打偏了,根据偏离的距离远近,来调整身体使得再次挥动的胳膊不断靠近桌子,最终打中。
BP神经网络所实现的功能作用
“能尽数天星,便能尽知棋势”。围棋体现着大自然的道法,而在AlphaGo击败人类围棋冠军,则是使用算法来寻求围棋的道,实现人机对战。BP神经网络训练的结果:得到多维数据x与y之间存在的规律,即实现由x来映射逼近y。而BP训练出来得到的模型是否可靠,表现为对其他未经过训练的数据,输入到BP中,是否能输出较为准确的预测值。对此,在BP神经网络训练之后,还需要再给指标因素x1到训练好的bp network中,得到相应的BP输出值(预测值)predict1,通过作图等,计算Mse,Mape,R方等指标,来对比predict1和y1的接近程度,就可以知道模型是否预测准确。这是BP模型的测试过程,即预测过程。
小结 BP神经网络实现了:a). 根据训练集数据,训练得到一个模型,b). 对模型的可靠性与准确性进行测试集(不同于训练样本数据)预测,和实际值对比,检验预测的精度。c). 只给输入,得到预测值(可理解为测试集的数据丢了实测值,本质一样,给输入到BP中,得到输出)。由于该情况无输出,纯预测,无法检验精度是否合格,写论文时无太大意义而不必实现该情况的步骤。
2 遗传算法GA优化BP神经网络原理
在BP神经网络训练的过程中,通过前向传播数据与误差反向传递,使用算法来更新权重阈值。一方面,在该过程中,第一次前向传播过程的权重和阈值该如何确定,即如何初始化权重和阈值。深度学习的方法是采用随机化方法得到初始的权值与阈值参数。另一方面,选定了初始参数后,梯度下降算法将初始参数值作为起点,进行参数优化与更新。
在优化算法的发展中,有两类:确定性算法与启发式算法。确定性算法指使用数学方法求最优问题,找到的结果与求导的初始点有关,一般为确定值。启发式算法则是灵感源于自然界生物进化的规律,主要思想为迭代逼近最优,优化的结果为满足工程精度要求的可变值(无限接近理论最优值)。
在上述过程中,作为一种确定性算法,梯度下降算法的收敛性是得到了证明的,但收敛值并非一定是全局最优,与初始的参数值(梯度下降算法的起点)有关。由于随机初始的参数未必是最优的起点(指既训练准确,又预测可靠),因此训练的模型可靠性和稳定性受到了初始随机参数的很大影响。作为启发式算法,遗传算法GA具体很好的全局搜索能力,引入GA用来解决此问题。
主要思想 将参数作为问题的决策变量,模型的精度作为问题的目标函数。遗传算法GA优化BP神经网络的算法流程图如下:
3 GA-BP模型建立
3.1 模型与数据介绍
下面以MATLAB官方提供的化学传感器的数据集为例,进行建模。
数据介绍:采集某个化学实验过程的数据,将8个传感器的采样数据作为输入(x),第9个传感器的采样数据作为输出(y)。
数据格式如下:
读取数据:
%% 读取读取
data=xlsread('数据.xlsx','Sheet1','A1:I498'); %%使用xlsread函数读取EXCEL中对应范围的数据即可
%输入输出数据
input=data(:,1:end-1); %data的第一列-倒数第二列为特征指标
output=data(:,end); %data的最后面一列为输出的指标值
N=length(output); %全部样本数目
testNum=100; %设定测试样本数目
trainNum=N-testNum; %计算训练样本数目
3.2 GA与BP参数设置 1) BP参数设置
对权重和阈值有关的参数进行说明: a). 输入层和输出层节点使用size函数直接获取。函数用法:[M,N]=size(A),M为A的行数,N为A的列数。size(A,2)得到的是第二个参数N,即列数。此数据中,输入8个维度指标,输出的为1个维度指标。即输入层节点为8,输出层节点为1。
inputnum=size(input,2); %输入层神经元节点个数
outputnum=size(output,2); %输出层神经元节点个数
b). 隐含层节点的确定过程,使用循环来遍历范围内的隐含层节点与训练误差情况。因为要找最小的误差,所以初始化训练误差时,将MSE设置较大的数字,用于在循环中确定最佳的隐含层节点。
%确定隐含层节点个数
%采用经验公式hiddennum=sqrt(m+n)+a,m为输入层节点个数,n为输出层节点个数,a一般取为1-10之间的整数
MSE=1e+5; %初始化最小误差
for hiddennum=fix(sqrt(inputnum+outputnum))+1:fix(sqrt(inputnum+outputnum))+10
c). 其他BP参数,学习速率,训练次数,训练的目标误差等
% 网络参数
net.trainParam.epochs=1000; % 训练次数
net.trainParam.lr=0.01; % 学习速率
net.trainParam.goal=0.000001; % 训练目标最小误差
2)遗传算法GA参数设置
%初始化ga参数
PopulationSize_Data=30; %初始种群规模
MaxGenerations_Data=50; %最大进化代数
CrossoverFraction_Data=0.8; %交叉概率
MigrationFraction_Data=0.2; %变异概率
3.3 遗传算法优化BP的设计 1)优化变量的设计 使用遗传算法求解优化问题时,对于决策变量(优化变量)有三种编码方式:二进制编码,向量形式编码,矩阵形式编码。
由于权重和阈值分别以m×n维的矩阵,向量形式存在与BP神经网络结构(net)中。为方便对每个元素都进行优化,先将元素分别取出,然后按取的顺序放入到向量(染色体)中,完成编码。权重和阈值的经验范围为[-1,1],可适当将寻优的范围放宽,取[-3,3]。 优化变量(元素)个数的计算如下:
nvars=inputnum*hiddennum_best+hiddennum_best+hiddennum_best*outputnum+outputnum; %变量维度
lb=repmat(-3,nvars,1); %自变量下限 %repmat得到一个nvars×1维的向量,每个元素的值都为-3,即优化变量下限
ub=repmat(3,nvars,1); %自变量上限
2)适应度函数的设计
采用以下公式计算适应度值。
式中,TraingingSet,TestingSet,分别为训练集和测试集的样本。因为预测精度越高,说明误差越低,所以公式设计为求解最小的均方误差。使用遗传算法后,适应度函数值越小,表明训练越准确,且兼顾模型的预测精度更好。
3)算法设计
将遗传算法视为一个“黑箱”优化器。在确定了优化的变量与目标适应度函数后,只需要经过该“黑箱”,即可输出最小的误差(精度最好值)和最优解变量,再把变量赋给BP神经网络的权值矩阵与阈值向量的相应位置,进行优化后的BP训练与测试即可。说明:在遗传算法的“黑箱”求解器中进行的算法操作为:选择、交叉与变异。
二、部分源代码
% 清空环境变量
clc;
clear;
close all;
%% 样本数据生成
jizhanid=load('anchorCfg.mat');
data=load('area_sample_test.mat');
location=zeros(499,83);
location1={'A0000','A83F2','A8418','A8420','A841C'};
[al,bl]=size(location1);
for ii=1:499
[shoudaogeshu,useless]=size(data.blink_frame(ii).anchor_array);
for ii2=1:shoudaogeshu
for kk=1:82
if strcmp(jizhanid.anchorCfg{kk,1},data.blink_frame(ii).anchor_array{ii2, 1}.id)
location(ii,kk)=data.blink_frame(ii).anchor_array{ii2, 1}.csi(2);
end
end
end
for ii3=1:bl
if strcmp(location1(ii3),data.detected_area{ii, 1})
location(ii,83)=ii3;
end
end
end
rowrank = randperm(size(location, 1)); % 随机打乱行
locationend = location(rowrank, :);%%按照rowrank打乱矩阵的行数
[a22,b22]=size(locationend);
for i=1:a22 %二值化
for j=1:b22-1
if locationend(i,j)~=0
locationend(i,j)=1;
end
end
end
%% BP算法
%输入数据
data=locationend;
%训练预测数据
data_train=data(1:220,1:83);
data_test=data(221:499,1:83);
input_train=data_train(:,1:82)';
output_train=data_train(:,83)';
input_test=data_test(:,1:82)';
output_test=data_test(:,83)';
%数据归一化
[inputn,mininput,maxinput,outputn,minoutput,maxoutput]=premnmx(input_train,output_train); %对p和t进行字标准化预处理
net=newff(minmax(inputn),[10,1],{'tansig','purelin'},'trainlm');
net.trainParam.epochs=1000;
net.trainParam.lr=0.1;
net.trainParam.goal=0.001;
net.trainParam.show=200;
%网络训练
net=train(net,inputn,outputn);
%数据归一化
inputn_test = tramnmx(input_test,mininput,maxinput);
an=sim(net,inputn_test);
test_simu=postmnmx(an,minoutput,maxoutput);
Yn=test_simu;
Yn=round(Yn);
figure %绘图
plot(Yn,'r*-') %绘制预测值曲线
hold on %继续绘图
plot(output_test,'bo-') %实际值曲线
legend('BP预测值','实际值') %图例
wucha1=ones(1,79); %BP时预测误差
for ii1=1:79
wucha1(ii1)=(Yn(ii1)-output_test(ii1));
end
figure
plot(wucha1,'b^-')
% %% GABP算法
% %% 网络结构建立
% %读取数据
% data=locationend;
%
% %节点个数
% inputnum=10;
% hiddennum=65;
% outputnum=1;
% data_train=data(1:420,1:83);
% data_test=data(421:499,1:83);
%
% input_train=data_train(:,1:82)';
% output_train=data_train(:,83)';
%
% input_test=data_test(:,1:82)';
% output_test=data_test(:,83)';
%
%
% %% 遗传算法参数初始化
% maxgen=10; %进化代数,即迭代次数
% sizepop=6; %种群规模
% pcross=[0.3]; %交叉概率选择,0和1之间
% pmutation=[0.1]; %变异概率选择,0和1之间
%
% %节点总数
% numsum=inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum;
%
% lenchrom=ones(1,numsum);
% bound=[-3*ones(numsum,1) 3*ones(numsum,1)]; %数据范围
%
% %------------------------------------------------------种群初始化--------------------------------------------------------
% individuals=struct('fitness',zeros(1,sizepop), 'chrom',[]); %将种群信息定义为一个结构体
% avgfitness=[]; %每一代种群的平均适应度
% bestfitness=[]; %每一代种群的最佳适应度
% bestchrom=[]; %适应度最好的染色体
% %初始化种群
% for i=1:sizepop
% %随机产生一个种群
% individuals.chrom(i,:)=Code(lenchrom,bound); %编码(binary和grey的编码结果为一个实数,float的编码结果为一个实数向量)
% x=individuals.chrom(i,:);
% %计算适应度
% individuals.fitness(i)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn); %染色体的适应度
% end
%
% %找最好的染色体
% [bestfitness, bestindex]=min(individuals.fitness);
% bestchrom=individuals.chrom(bestindex,:); %最好的染色体
% avgfitness=sum(individuals.fitness)/sizepop; %染色体的平均适应度
% % 记录每一代进化中最好的适应度和平均适应度
% trace=[avgfitness bestfitness];
%
% %% 迭代求解最佳初始阀值和权值
% % 进化开始
% for i=1:maxgen
%
% % 选择
% individuals=Select(individuals,sizepop);
% avgfitness=sum(individuals.fitness)/sizepop;
% %交叉
% individuals.chrom=Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);
% % 变异
% individuals.chrom=Mutation(pmutation,lenchrom,individuals.chrom,sizepop,i,maxgen,bound);
%
% % 计算适应度
% for j=1:sizepop
% x=individuals.chrom(j,:); %解码
% individuals.fitness(j)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);
% end
%
% %找到最小和最大适应度的染色体及它们在种群中的位置
% [newbestfitness,newbestindex]=min(individuals.fitness);
% [worestfitness,worestindex]=max(individuals.fitness);
% % 代替上一次进化中最好的染色体
% if bestfitness>newbestfitness
% bestfitness=newbestfitness;
% bestchrom=individuals.chrom(newbestindex,:);
% end
% individuals.chrom(worestindex,:)=bestchrom;
% individuals.fitness(worestindex)=bestfitness;
%
% avgfitness=sum(individuals.fitness)/sizepop;
%
% trace=[trace;avgfitness bestfitness]; %记录每一代进化中最好的适应度和平均适应度
%
% end
% %% 遗传算法结果分析
% figure
% [r, c]=size(trace);
% plot([1:r]',trace(:,2),'b--');
% title(['适应度曲线 ' '终止代数=' num2str(maxgen)]);
% xlabel('进化代数');ylabel('适应度');
% legend('平均适应度','最佳适应度');
% x=bestchrom;
%
% %% 把最优初始阀值权值赋予网络预测
% % %用遗传算法优化的BP网络进行值预测
% w1=x(1:inputnum*hiddennum);
% B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);
%
%
% net.iw{1,1}=reshape(w1,hiddennum,inputnum);
% net.lw{2,1}=reshape(w2,outputnum,hiddennum);
% net.b{1}=reshape(B1,hiddennum,1);
% net.b{2}=B2;
%
% %% BP网络训练
% %网络进化参数
% net.trainParam.epochs=3000;
% net.trainParam.lr=0.1;
% net.trainParam.goal=0.001;
%
% %网络训练
% [net,per2]=train(net,inputn,outputn);
%
% %% BP网络预测
% %数据归一化
% inputn_test2=mapminmax('apply',input_test,inputps);
% an2=sim(net,inputn_test2);
% test_simu2=mapminmax('reverse',an2,outputps);
%
%
% Yn2=test_simu2;
% Yn2=round(Yn2);
% figure %绘图
% plot(Yn2,'r*-') %绘制预测值曲线
% hold on %继续绘图
% plot(output_test,'bo-') %实际值曲线
% legend('GABP预测值','实际值') %图例
% wucha2=ones(1,79); %GABP时预测误差
% for ii1=1:79
% wucha2(ii1)=((Yn2(ii1)-output_test(ii1))/output_test(ii1));
% end
% figure
% plot(wucha2,'r*--')
% %% 画对比图
% figure %绘图
% plot(Yn,'r*-') %绘制预测值曲线
% hold on %继续绘图
% plot(Yn2,'g^--') %绘制预测值曲线
% hold on
% plot(output_test,'bo-') %实际值曲线
% legend('BP预测值','GABP预测值','实际值') %图例
% figure
% plot(wucha1,'b^-')
% hold on
% plot(wucha2,'r*--')
% legend('BP预测误差','GABP预测误差') %图例
% % %% 数据存储
% % fid=fopen('shuchu.txt','w');
% % fprintf(fid,'%g\t',Yn);
% % fprintf(fid,'%g\t',Yn2);
% % fprintf(fid,'%g\t',wucha1);
% % fprintf(fid,'%g\t',wucha2);
% % fclose(fid);
三、运行结果
四、matlab版本及参考文献
1 matlab版本 2014a
2 参考文献 [1] 包子阳,余继周,杨杉.智能优化算法及其MATLAB实例(第2版)[M].电子工业出版社,2016. [2]张岩,吴水根.MATLAB优化算法源代码[M].清华大学出版社,2017. [3]周品.MATLAB 神经网络设计与应用[M].清华大学出版社,2013. [4]陈明.MATLAB神经网络原理与实例精解[M].清华大学出版社,2013. [5]方清城.MATLAB R2016a神经网络设计与应用28个案例分析[M].清华大学出版社,2018.