
十一月匆匆過去,每天依然在忙碌著與文檔相關(guān)的東西,在寒假前一個多月里,努力做好手頭上的事的前提下多學(xué)習(xí)專業(yè)知識,依然是堅持學(xué)習(xí)與素質(zhì)提高并重,依然是堅持鍛煉身體,為明年找工作打下基礎(chǔ)。
遺傳算法優(yōu)化的BP神經(jīng)網(wǎng)絡(luò)建模借鑒別人的程序做出的仿真,最近才有時間整理。
目標(biāo):
對y=x1^2+x2^2非線性系統(tǒng)進行建模,用1500組數(shù)據(jù)對網(wǎng)絡(luò)進行構(gòu)建網(wǎng)絡(luò),500組數(shù)據(jù)測試網(wǎng)絡(luò)。由于BP神經(jīng)網(wǎng)絡(luò)初始神經(jīng)元之間的權(quán)值和閾值一般隨機選擇,因此容易陷入局部最小值。本方法使用遺傳算法優(yōu)化初始神經(jīng)元之間的權(quán)值和閾值,并對比使用遺傳算法前后的效果。
步驟:
未經(jīng)遺傳算法優(yōu)化的BP神經(jīng)網(wǎng)絡(luò)建模
1、隨機生成2000組兩維隨機數(shù)(x1,x2),并計算對應(yīng)的輸出y=x1^2+x2^2,前1500組數(shù)據(jù)作為訓(xùn)練數(shù)據(jù)input_train,后500組數(shù)據(jù)作為測試數(shù)據(jù)input_test。并將數(shù)據(jù)存儲在data中待遺傳算法中使用相同的數(shù)據(jù)。
2、 數(shù)據(jù)預(yù)處理:歸一化處理。
3、 構(gòu)建BP神經(jīng)網(wǎng)絡(luò)的隱層數(shù),次數(shù),步長,目標(biāo)。
4、使用訓(xùn)練數(shù)據(jù)input_train訓(xùn)練BP神經(jīng)網(wǎng)絡(luò)net。
5、用測試數(shù)據(jù)input_test測試神經(jīng)網(wǎng)絡(luò),并將預(yù)測的數(shù)據(jù)反歸一化處理。
6、 分析預(yù)測數(shù)據(jù)與期望數(shù)據(jù)之間的誤差。
遺傳算法優(yōu)化的BP神經(jīng)網(wǎng)絡(luò)建模
1、 讀取前面步驟中保存的數(shù)據(jù)data;
2、 對數(shù)據(jù)進行歸一化處理;
3、 設(shè)置隱層數(shù)目;
4、 初始化進化次數(shù),種群規(guī)模,交叉概率,變異概率
5、對種群進行實數(shù)編碼,并將預(yù)測數(shù)據(jù)與期望數(shù)據(jù)之間的誤差作為適應(yīng)度函數(shù);
6、循環(huán)進行選擇、交叉、變異、計算適應(yīng)度操作,直到達到進化次數(shù),得到最優(yōu)的初始權(quán)值和閾值;
7、 將得到最佳初始權(quán)值和閾值來構(gòu)建BP神經(jīng)網(wǎng)絡(luò);
8、使用訓(xùn)練數(shù)據(jù)input_train訓(xùn)練BP神經(jīng)網(wǎng)絡(luò)net;
9、用測試數(shù)據(jù)input_test測試神經(jīng)網(wǎng)絡(luò),并將預(yù)測的數(shù)據(jù)反歸一化處理;
10、分析預(yù)測數(shù)據(jù)與期望數(shù)據(jù)之間的誤差。
算法流程圖如下:
運行后使用遺傳算法改進前后誤差的對比圖:
程序:
1、未經(jīng)遺傳算法優(yōu)化的BP神經(jīng)網(wǎng)絡(luò)建模
clear;
clc;
%%%%%%%%%%%%%輸入?yún)?shù)%%%%%%%%%%%%%%
N=2000;%數(shù)據(jù)總個數(shù)
M=1500;%訓(xùn)練數(shù)據(jù)
%%%%%%%%%%%%%訓(xùn)練數(shù)據(jù)%%%%%%%%%%%%%%
for i=1:N
input(i,1)=-5+rand*10;
input(i,2)=-5+rand*10;
end
output=input(:,1).^2+input(:,2).^2;
save data input output
load data.mat
%從1到N隨機排序
k=rand(1,N);
[m,n]=sort(k);
%找出訓(xùn)練數(shù)據(jù)和預(yù)測數(shù)據(jù)
input_train=input(n(1:M),:)';
output_train=output(n(1:M),:)';
input_test=input(n((M+1):N),:)';
output_test=output(n((M+1):N),:)';
%數(shù)據(jù)歸一化
[inputn,inputs]=mapminmax(input_train);
[outputn,outputs]=mapminmax(output_train);
%構(gòu)建BP神經(jīng)網(wǎng)絡(luò)
net=newff(inputn,outputn,5);
net.trainParam.epochs=100;
net.trainParam.lr=0.1;
net.trainParam.goal=0.0000004;
%BP神經(jīng)網(wǎng)絡(luò)訓(xùn)練
net=train(net,inputn,outputn);
%測試樣本歸一化
inputn_test=mapminmax('apply',input_test,inputs);
%BP神經(jīng)網(wǎng)絡(luò)預(yù)測
an=sim(net,inputn_test);
%%網(wǎng)絡(luò)得到數(shù)據(jù)反歸一化
BPoutput=mapminmax('reverse',an,outputs);
figure(1)
%plot(BPoutput,':og');
scatter(1:(N-M),BPoutput,'rx');
hold on;
%plot(output_test,'-*');
scatter(1:(N-M),output_test,'o');
legend('預(yù)測輸出','期望輸出','fontsize',12);
title('BP網(wǎng)絡(luò)預(yù)測輸出','fontsize',12);
xlabel('樣本','fontsize',12);
xlabel('優(yōu)化前輸出的誤差','fontsize',12);
figure(2)
error=BPoutput-output_test;
plot(1:(N-M),error);
xlabel('樣本','fontsize',12);
ylabel('優(yōu)化前輸出的誤差','fontsize',12);
%save net net inputs outputs
2、遺傳算法優(yōu)化的BP神經(jīng)網(wǎng)絡(luò)建模
(1)主程序
%清空環(huán)境變量
clc
clear
%讀取數(shù)據(jù)
load data.mat
%節(jié)點個數(shù)
inputnum=2;
hiddennum=5;
outputnum=1;
%訓(xùn)練數(shù)據(jù)和預(yù)測數(shù)據(jù)
input_train=input(1:1500,:)';
input_test=input(1501:2000,:)';
output_train=output(1:1500)';
output_test=output(1501:2000)';
%選連樣本輸入輸出數(shù)據(jù)歸一化
[inputn,inputps]=mapminmax(input_train);
[outputn,outputps]=mapminmax(output_train);
%構(gòu)建網(wǎng)絡(luò)
net=newff(inputn,outputn,hiddennum);
%% 遺傳算法參數(shù)初始化
maxgen=10;%進化代數(shù),即迭代次數(shù)
sizepop=30;%種群規(guī)模
pcross=[0.3];%交叉概率選擇,0和1之間
pmutation=[0.1];%變異概率選擇,0和1之間
%節(jié)點總數(shù)
numsum=inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum;
lenchrom=ones(1,numsum);
bound=[-3*ones(numsum,1)3*ones(numsum,1)];%數(shù)據(jù)范圍
%------------------------------------------------------種群初始化------------------------------%------------------
--------
individuals=struct('fitness',zeros(1,sizepop),'chrom',[]); %將種群信息定義為一個結(jié)構(gòu)體
%avgfitness=[];%每一代種群的平均適應(yīng)度
bestfitness=[];%每一代種群的最佳適應(yīng)度
bestchrom=[];%適應(yīng)度最好的染色體
%初始化種群
for i=1:sizepop
%隨機產(chǎn)生一個種群
individuals.chrom(i,:)=Code(lenchrom,bound);%編碼
x=individuals.chrom(i,:);
%計算適應(yīng)度
individuals.fitness(i)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);%染色體的適應(yīng)度
end
%找最好的染色體
[bestfitnessbestindex]=min(individuals.fitness);
bestchrom=individuals.chrom(bestindex,:);%最好的染色體
%avgfitness=sum(individuals.fitness)/sizepop;%染色體的平均適應(yīng)度
% 記錄每一代進化中最好的適應(yīng)度和平均適應(yīng)度
%trace=[avgfitness bestfitness];
%% 迭代求解最佳初始閥值和權(quán)值
% 進化開始
for i=1:maxgen
i
% 選擇
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);
% 計算適應(yīng)度
forj=1:sizepop
x=individuals.chrom(j,:); %解碼
individuals.fitness(j)=fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn);
end
%找到最小和最大適應(yīng)度的染色體及它們在種群中的位置
[newbestfitness,newbestindex]=min(individuals.fitness);
[worestfitness,worestindex]=max(individuals.fitness);
%代替上一次進化中最好的染色體
ifbestfitness>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]; %記錄每一代進化中最好的適應(yīng)度和平均適應(yīng)度
end
%% 遺傳算法結(jié)果分析
%figure(3)
%[r c]=size(trace);
%plot([1:r]',trace(:,2),'b--');
%title(['適應(yīng)度曲線 ' '終止代數(shù)='num2str(maxgen)]);
%xlabel('進化代數(shù)');ylabel('適應(yīng)度');
%legend('平均適應(yīng)度','最佳適應(yīng)度');
disp('適應(yīng)度變量');
x=bestchrom;
%% 把最優(yōu)初始閥值權(quán)值賦予網(wǎng)絡(luò)預(yù)測
% %用遺傳算法優(yōu)化的BP網(wǎng)絡(luò)進行值預(yù)測
w1=x(1:inputnum*hiddennum);
B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);
w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);
B2=x
(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);
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網(wǎng)絡(luò)訓(xùn)練
%網(wǎng)絡(luò)進化參數(shù)
net.trainParam.epochs=100;
net.trainParam.lr=0.1;
%net.trainParam.goal=0.00001;
%網(wǎng)絡(luò)訓(xùn)練
[net,per2]=train(net,inputn,outputn);
%% BP網(wǎng)絡(luò)預(yù)測
%數(shù)據(jù)歸一化
inputn_test=mapminmax('apply',input_test,inputps);
an=sim(net,inputn_test);
test_simu=mapminmax('reverse',an,outputps);
error=test_simu-output_test;
%figure(4);
hold on;plot(1:500,error,'r');
legend('優(yōu)化前的誤差','優(yōu)化后的誤差','fontsize',12)
(2)編碼子程序code.m
function ret=Code(lenchrom,bound)
%本函數(shù)將變量編碼成染色體,用于隨機初始化一個種群
% lenchrominput : 染色體長度
%boundinput : 變量的取值范圍
%retoutput: 染色體的編碼值
flag=0;
while flag==0
pick=rand(1,length(lenchrom));
ret=bound(:,1)'+(bound(:,2)-bound(:,1))'.*pick;%線性插值,編碼結(jié)果以實數(shù)向量存入ret中
flag=test(lenchrom,bound,ret);%檢驗染色體的可行性
end
(3)適應(yīng)度函數(shù)fun.m
function error =fun(x,inputnum,hiddennum,outputnum,net,inputn,outputn)
%該函數(shù)用來計算適應(yīng)度值
%xinput個體
%inputnuminput輸入層節(jié)點數(shù)
%outputnuminput隱含層節(jié)點數(shù)
%netinput網(wǎng)絡(luò)
%inputninput訓(xùn)練輸入數(shù)據(jù)
%outputninput訓(xùn)練輸出數(shù)據(jù)
%erroroutput個體適應(yīng)度值
%提取
w1=x(1:inputnum*hiddennum);
B1=x(inputnum*hiddennum+1:inputnum*hiddennum+hiddennum);
w2=x(inputnum*hiddennum+hiddennum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum);
B2=x(inputnum*hiddennum+hiddennum+hiddennum*outputnum+1:inputnum*hiddennum+hiddennum+hiddennum*outputnum+outputnum);
net=newff(inputn,outputn,hiddennum);
%網(wǎng)絡(luò)進化參數(shù)
net.trainParam.epochs=20;
net.trainParam.lr=0.1;
net.trainParam.goal=0.00001;
net.trainParam.show=100;
net.trainParam.showWindow=0;
%網(wǎng)絡(luò)權(quán)值賦值
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;
%網(wǎng)絡(luò)訓(xùn)練
net=train(net,inputn,outputn);
an=sim(net,inputn);
error=sum(abs(an-outputn));
(4)選擇操作Select.m
function ret=select(individuals,sizepop)
% 該函數(shù)用于進行選擇操作
% individualsinput種群信息
%sizepopinput種群規(guī)模
%retoutput 選擇后的新種群
%求適應(yīng)度值倒數(shù)
[a bestch]=min(individuals.fitness);
%b=individuals.chrom(bestch);
%c=individuals.fitness(bestch);
fitness1=10./individuals.fitness;%individuals.fitness為個體適應(yīng)度值
%個體選擇概率
sumfitness=sum(fitness1);
sumf=fitness1./sumfitness;
%采用輪盤賭法選擇新個體
index=[];
for i=1:sizepop%sizepop為種群數(shù)
pick=rand;
whilepick==0
pick=rand;
end
fori=1:sizepop
pick=pick-sumf(i);
ifpick<0
index=[indexi];
break;
end
end
end
%index=[index bestch];
%新種群
individuals.chrom=individuals.chrom(index,:);%individuals.chrom為種群中個體
individuals.fitness=individuals.fitness(index);
%individuals.chrom=[individuals.chrom;b];
%individuals.fitness=[individuals.fitness;c];
ret=individuals;
(5)交叉操作cross.m
functionret=Cross(pcross,lenchrom,chrom,sizepop,bound)
%本函數(shù)完成交叉操作
%pcorssinput : 交叉概率
%lenchrominput : 染色體的長度
%chrominput : 染色體群
%sizepopinput : 種群規(guī)模
%retoutput : 交叉后的染色體
for i=1:sizepop%每一輪for循環(huán)中,可能會進行一次交叉操作,染色體是隨機選擇的,交叉位置也是隨機選擇的,%但該輪for循環(huán)中是否進行交叉操作則由交叉概率決定(continue控制)
% 隨機選擇兩個染色體進行交叉
pick=rand(1,2);
while prod(pick)==0
pick=rand(1,2);
end
index=ceil(pick.*sizepop);
% 交叉概率決定是否進行交叉
pick=rand;
while pick==0
pick=rand;
end
if pick>pcross
continue;
end
flag=0;
while flag==0
% 隨機選擇交叉位
pick=rand;
while pick==0
pick=rand;
end
pos=ceil(pick.*sum(lenchrom));%隨機選擇進行交叉的位置,即選擇第幾個變量進行交叉,注意:兩個染色體交叉的位置相同
pick=rand; %交叉開始
v1=chrom(index(1),pos);
v2=chrom(index(2),pos);
chrom(index(1),pos)=pick*v2+(1-pick)*v1;
chrom(index(2),pos)=pick*v1+(1-pick)*v2; %交叉結(jié)束
flag1=test(lenchrom,bound,chrom(index(1),:));%檢驗染色體1的可行性
flag2=test(lenchrom,bound,chrom(index(2),:));%檢驗染色體2的可行性
if flag1*flag2==0
flag=0;
else flag=1;
end%如果兩個染色體不是都可行,則重新交叉
end
end
ret=chrom;
(6)變異操作Mutation.m
functionret=Mutation(pmutation,lenchrom,chrom,sizepop,num,maxgen,bound)
% 本函數(shù)完成變異操作
%pcorssinput : 變異概率
%lenchrominput : 染色體長度
%chrominput : 染色體群
%sizepopinput : 種群規(guī)模
%optsinput : 變異方法的選擇
%popinput : 當(dāng)前種群的進化代數(shù)和最大的進化代數(shù)信息
%boundinput : 每個個體的上屆和下屆
%maxgeninput :最大迭代次數(shù)
%numinput : 當(dāng)前迭代次數(shù)
%retoutput : 變異后的染色體
for i=1:sizepop%每一輪for循環(huán)中,可能會進行一次變異操作,染色體是隨機選擇的,變異位置也是隨機選擇的,
%但該輪for循環(huán)中是否進行變異操作則由變異概率決定(continue控制)
%隨機選擇一個染色體進行變異
pick=rand;
whilepick==0
pick=rand;
end
index=ceil(pick*sizepop);
%變異概率決定該輪循環(huán)是否進行變異
pick=rand;
ifpick>pmutation
continue;
end
flag=0;
whileflag==0
% 變異位置
pick=rand;
whilepick==0
pick=rand;
end
pos=ceil(pick*sum(lenchrom));%隨機選擇了染色體變異的位置,即選擇了第pos個變量進行變異
pick=rand;%變異開始
fg=(rand*(1-num/maxgen))^2;
if pick>0.5
chrom(i,pos)=chrom(i,pos)+(bound(pos,2)-chrom(i,pos))*fg;
else
chrom(i,pos)=chrom(i,pos)-(chrom(i,pos)-bound(pos,1))*fg;
end %變異結(jié)束
flag=test(lenchrom,bound,chrom(i,:));%檢驗染色體的可行性
end
end
ret=chrom;
愛華網(wǎng)


