4.1 案例背景
\[y = {x_1}^2 + {x_2}^2\]
4.2 模型建立
神經網絡訓練擬合根據尋優函數的特點構建合適的BP神經網絡,用非線性函數的輸入輸出數據訓練BP神經網絡,訓練后的BP神經網絡就可以預測函數輸出。遺傳算法極值尋優把訓練后的 BP 神經網絡預測結果作為個體適應度值,通過選擇、交叉和變異操作尋找函數的全局最優值及對應輸入值。
網絡結構:2-5-1
訓練數據:3900,測試數據:100
4.3 編程實現
%% 基於神經網絡遺傳算法的系統極值尋優 %% 清空環境變量 clc clear input=2*randn(2,2000); output=sum(input.*input); [inputn,inputps]=mapminmax(input); [outputn,outputps]=mapminmax(output); %% BP網絡訓練 % %初始化網絡結構 net=newff(inputn,outputn,[10,5]); % 配置網絡參數(迭代次數,學習率,目標) net.trainParam.epochs=500; net.trainParam.lr=0.1; net.trainParam.goal=0.000004; %網絡訓練 net=train(net,inputn,outputn);
%% 初始化遺傳算法參數 %初始化參數 maxgen=200; %進化代數,即迭代次數 sizepop=20; %種群規模 pcross=[0.4]; %交叉概率選擇,0和1之間 pmutation=[0.2]; %變異概率選擇,0和1之間 lenchrom=[1 1]; %每個變量的字串長度,如果是浮點變量,則長度都為1 bound=[-5 5;-5 5]; %數據范圍 individuals=struct('fitness',zeros(1,sizepop), 'chrom',[]); %將種群信息定義為一個結構體 avgfitness=[]; %每一代種群的平均適應度 bestfitness=[]; %每一代種群的最佳適應度 bestchrom=[]; %適應度最好的染色體 %% 初始化種群計算適應度值 % 初始化種群 for i=1:sizepop %隨機產生一個種群 individuals.chrom(i,:)=Code(lenchrom,bound); x=individuals.chrom(i,:); %計算適應度 individuals.fitness(i)=fun(x,inputps,outputps,net); %染色體的適應度 end %找最好的染色體 [bestfitness bestindex]=min(individuals.fitness); bestchrom=individuals.chrom(bestindex,:); %最好的染色體 avgfitness=sum(individuals.fitness)/sizepop; %染色體的平均適應度 % 記錄每一代進化中最好的適應度和平均適應度 trace=[avgfitness bestfitness];
%% 迭代尋優 % 進化開始 for i=1:maxgen if(mod(i,10)==0) i end % 選擇 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,inputps,outputps,net); 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
function fitness = fun(x,inputps,outputps,net) % 函數功能:計算該個體對應適應度值 % x input 個體 % fitness output 個體適應度值 %數據歸一化 x=x'; inputn_test=mapminmax('apply',x,inputps); %網絡預測輸出 an=sim(net,inputn_test); %網絡輸出反歸一化 fitness=mapminmax('reverse',an,outputps);
%% 結果分析 [r,c]=size(trace); plot(trace(:,2),'r-'); title('適應度曲線','fontsize',12); xlabel('進化代數','fontsize',12);ylabel('適應度','fontsize',12); axis([0,200,0,1])
x=bestchrom; disp([bestfitness x]);
fun([0,0],inputps,outputps,net) ans = 0.0507
在遺傳算法中沒有$y = {x_1}^2 + {x_2}^2$函數的原型,由於神經網絡的誤差,最后的計算值離真實值有一定偏差。
若將fun函數改為fitness=sum(x.*x);,則可以看到遺傳算法取得良好效果,因此能用函數原型就一定要用,如果要用神經網絡一定要有充足的訓練數據,並指定足夠小的誤差。