天天看點

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

1.遺傳算法理論基礎

第一次接觸遺傳算法,覺得這個算法很是神奇啊!遺傳算法模拟自然界中“優勝劣汰,适者生存”的法則,形成了一種随機搜尋最優化方法。本文主要是講遺傳算法用于優化BP算法,BP算法在拟合非線性函數時,雖然可以收斂,但是有可能收斂到局部最小點,這是源于它的搜尋是串行搜尋,而遺傳算法的并行性,能夠使其更容易收斂到全局最小點。在訓練神經網絡時,目的就是通過不斷的優化每一層的權值和偏置值,使最終網絡輸出與期望輸出之間的誤差小到我們所期望的值,而這個優化的過程,就是權值和偏置值不斷“進化”的過程,在每一次疊代過程中,權值與偏置值由于“自然環境”發生選擇,突變,交叉,然後留下優的品種(權值和偏置值使輸出誤差最小),淘汰劣的品種,進而經過多次疊代,權值與偏置值的“基因”會越來越好,進而達到訓練目的。下面介紹幾個概念:

1.種群:一個種群中有許多個體,個體之間有差異,有的個體攜帶的權值和偏置值誤差小,有的個體攜帶的誤差大。進化過程以種群為基本機關。

2.編碼:就是個體攜帶的基因型,在BP網絡中就是權值和偏置值。

3.适應性:個體優劣程度,在BP網絡中,誤差大的适應性差,誤差小的适應性好。

4.選擇:以一定機率在種群中選取若幹個體,模拟優勝劣汰過程。

5.交叉:兩個個體的編碼“基因重組”。

6.變異:個體編碼“基因突變”。

遺傳算法的進化過程如何實作呢?

1.物種初始化

個體編碼攜帶各層權值與偏置值,種群規模自定義。

2.适應性值

每一個個體都有獨特的權值與偏置值,把該個體網絡輸出與期望輸出之間的誤差作為個體的适應性。

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

3.選擇

輪盤賭選擇法:

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

f是适應性值的倒數,f越小,适應性越差,p是每個個體被選中的機率,f越大,适應性值越好,被選中的機率也就越大。注意:所有個體機率相加為1,這對了解輪盤賭選擇法很重要。

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

如上圖,每一個個體都有被選中的機率,機率和為1。随機産生0~1之間的一個數字x,落在上圖哪個區間,哪個個體就被選中,因為0~1數字是随機産生,是以落在區間大的區域的機率更大,區域機率大代表什麼?代表這個個體适應性好,好的個體被多次選中,自然“基因”就好了。

4.交叉

選中的優秀個體,組成了新的種群,新種群之間的“雜交”是必要的,可以産生更優秀的“基因”。随機選中兩個個體的兩個“基因”進行“雜交”(相同段基因)。

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

5.變異

生物進化隻有“雜交”是不行的,有時候需要“基因突變”。

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab
遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

r是0~1之間的随機數,g是目前疊代次數,Gmax是最大疊代次數。

2.具體程式設計實作Matlab

main.m

clc,clear,close all
%%
%導入資料
data  = load('data.mat');
input_data = (data.input)';
output_data = data.output;

%訓練使用資料
input_data_tr = input_data(:,1:1900);
output_data_tr  = output_data(:,1:1900);

%測試使用資料
input_data_te = input_data(:,1901:2000);
output_data_te = output_data(:,1901:2000);

%訓練資料歸一化
[input_tr,p] = mapminmax(input_data_tr);
[output_tr,q] = mapminmax(output_data_tr);
%%
%生成網絡
input_number = 2;
hide_number = 5;
output_number = 1;
net = newff(input_tr,output_tr,5);
%%
%遺傳算法
%定義參數
size = 10;%種群規模 10
time = 50;%疊代次數
pcross = 0.4;%交叉機率
pvariation = 0.2;%變異機率
l = hide_number*input_number+output_number*hide_number+hide_number+output_number;%編碼長度

%定義種群結構體
individuals = struct('fitness',zeros(1,size),'chorm',[]);%chorm編碼資訊 fitness适應度

%初始化種群
lenchrom = ones(1,l);
bound = [-3*ones(l,1) 3*ones(l,1)];
for i = 1:size
    individuals.chorm(i,:) = Code(lenchrom,bound);
    x = individuals.chorm(i,:);
    individuals.fitness(1,i) = fitness_fun(x,input_number,hide_number,output_number,net,input_tr,output_tr);
end
best_fitness = 10;%最優個體适應度
best_chorm = zeros(1,l);%最優個體染色體編碼
trace = zeros(1,time);
b = [];
%進化
for i = 1:time
    i
    %擇優
    individuals = Select(individuals,size);
    %交叉
    individuals = Cross(size,individuals,pcross,l);
    %變異
    individuals = Variation(size,pvariation,l,i,time,individuals,3,-3);
    %進化之後的适應度
    for j = 1:size
        x = individuals.chorm(j,:);
        individuals.fitness(1,j) = fitness_fun(x,input_number,hide_number,output_number,net,input_tr,output_tr);
    end
    %最優個體
    [new_best_fitness,index] = min(individuals.fitness);
    new_best_chorm = individuals.chorm(index,:);
    %最差個體
    [worst_fitness,index] = max(individuals.fitness);
    if new_best_fitness<best_fitness
       best_fitness = new_best_fitness;
       best_chorm = new_best_chorm;
    end
    b = [b best_fitness];
    %淘汰最差個體
    individuals.fitness(1,index) = best_fitness;
    individuals.chorm(index,:) = best_chorm;
    %平均适應度
    trace(1,i) = sum(individuals.fitness)/size;
end
%%
%測試
%生成神經網絡權值與偏置值
x = best_chorm;
w1 = x(1,1:input_number*hide_number);
b1 = x(1,input_number*hide_number+1:input_number*hide_number+hide_number);
w2 = x(1,input_number*hide_number+hide_number+1:input_number*hide_number+hide_number+hide_number*output_number);
b2 = x(1,input_number*hide_number+hide_number+hide_number*output_number+1:input_number*hide_number+hide_number+hide_number*output_number+output_number);
%生成神經網絡
net.iw{1,1} = reshape(w1,hide_number,input_number);
net.lw{2,1} = reshape(w2,output_number,hide_number);
net.b{1} = reshape(b1,hide_number,1);
net.b{2} = reshape(b2,output_number,1);
%設定神經網絡參數
net.trainparam.epochs = 100;
net.trainparam.lr = 0.1;%learn rate
net.trainparam.goal = 0.00001;
%訓練神經網絡
net = train(net,input_tr,output_tr);
%歸一化輸入測試資料
input_te = mapminmax('apply',input_data_te,p);
%輸入神經網絡
o = sim(net,input_te);
output = mapminmax('reverse',o,q);
error = output_data_te-output;
plot(error);
           

1.首先導入資料,根據要拟合的非線性函數,得到2000組輸入輸出資料。其中1900組用于網絡訓練,100組用于網絡測試。訓練資料歸一化。

2.構造神經網絡,輸入變量為2,輸出變量為1,三層網絡結構,設定隐層節點為5。

3.遺傳算法優化BP網絡訓練,定義種群結構體包含編碼與适應性值。初始化種群個體的編碼(權值和偏置值),計算出适應性值。進化過程:每一次疊代過程,都要進行個體選擇,交叉和變異操作。然後計算進化之後的個體适應性值,進行優勝劣汰。

4.疊代完成之後,選取種群中最優的編碼作為網絡參數,測試資料。

code.m

function ret=Code(lenchrom,bound)
%本函數将變量編碼成染色體,用于随機初始化一個種群
% lenchrom   input : 染色體長度
% bound      input : 變量的取值範圍
% ret        output: 染色體的編碼值
pick=rand(1,length(lenchrom));
ret=bound(:,1)'+(bound(:,2)-bound(:,1))'.*pick; %線性插值,編碼結果以實數向量存入ret中
end
        
           

fitness_fun.m

function error = fitness_fun(x,input_number,hide_number,output_number,net,input_data,output_data)
%每一個個體都有獨立的權值與偏置值組成的編碼資訊,errer評估目前個體x的适應度
%x                 個體
%input_number      輸入層節點個數
%hide_number       隐層節點個數
%output_number     輸出層節點個數
%net               
%input_data        資料輸入
%output_data       資料輸出

%從個體編碼資訊中得出權值與偏置值
w1 = x(1,1:input_number*hide_number);
b1 = x(1,input_number*hide_number+1:input_number*hide_number+hide_number);
w2 = x(1,input_number*hide_number+hide_number+1:input_number*hide_number+hide_number+hide_number*output_number);
b2 = x(1,input_number*hide_number+hide_number+hide_number*output_number+1:input_number*hide_number+hide_number+hide_number*output_number+output_number);

net.iw{1,1} = reshape(w1,hide_number,input_number);
net.lw{2,1} = reshape(w2,output_number,hide_number);
net.b{1} = reshape(b1,hide_number,1);
net.b{2} = reshape(b2,output_number,1);

%設定神經網絡參數
net.trainparam.epochs = 20;
net.trainparam.lr = 0.1;%learn rate
net.trainparam.goal = 0.00001;
net.trainparam.show = 100;%
net.trainparam.showWindow = 0;%

%訓練神經網絡
net = train(net,input_data,output_data);

%得出預測值
p_out = sim(net,input_data);

%計算誤差作為目前個體的适應度
error = sum(abs(output_data-p_out));
end

           

Select.m

function ret = Select(individuals,size)
%輪盤賭法
%individuals        種群
%size               規模大小

%個體被選中的機率
k = 10;
f = k./individuals.fitness;%
p = f./sum(f);
%定義優選序列
select_index = zeros(1,size);
for i = 1:size
   p_rand = rand;%産生随機數
   while(p_rand == 0)
       p_rand = rand;
   end
   for j = 1:size
      p_rand = p_rand-p(1,j);
      if p_rand<0
          select_index(1,i) = j;%第j個被選中
          break;
      end
   end
end
individuals.chorm = individuals.chorm(select_index,:);%
individuals.fitness = individuals.fitness(1,select_index);
ret = individuals;
end

           

Cross.m

function ret = Cross(size,individuals,pcross,l)
%染色體交叉
for i = 1:size
    %随機産生要交叉的兩個個體序号
    index = rand(1,2);
    while prod(index) == 0
       index = rand(1,2); 
    end
    index = ceil(index.*size);
    %是否交叉?
    p = rand;
    while p == 0
        p = rand;
    end
    if p>pcross
        %選擇交叉位置
        position = rand;
        while position == 0
           position = rand; 
        end
        position = ceil(position*l);
        %交叉
        b = rand;%設定交叉權值
        a_adjust = individuals.chorm(index(1,1),position)*(1-b)+individuals.chorm(index(1,2),position)*b;
        b_adjust = individuals.chorm(index(1,1),position)*b+individuals.chorm(index(1,2),position)*(1-b);
        individuals.chorm(index(1,1),position) = a_adjust;
        individuals.chorm(index(1,2),position) = b_adjust;
    end
end
ret = individuals;
end

           

Variation.m

function ret = Variation(size,pvariation,l,g,time,individuals,max,min)
%染色體變異
for i = 1:size
    %選擇變異的個體
    index = rand;
    while index == 0;
       index = rand; 
    end
    index = ceil(index*size);
    %是否變異
    p = rand;
    while p==0
       p = rand; 
    end
    if p>pvariation
        %變異位置
        position = rand;
        while position == 0
           position = rand; 
        end
        position = ceil(position*l);
        fg = rand*((1-g/time)^2);
        pick = rand;
        if pick>0.5
            individuals.chorm(index,position) = individuals.chorm(index,position)+(individuals.chorm(index,position)-max)*fg;
        else
            individuals.chorm(index,position) = individuals.chorm(index,position)+(min-individuals.chorm(index,position))*fg;
        end
    end
end
ret = individuals;
end

           

測試結果:

均方誤差:

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

适應性值:

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

誤差:

遺傳算法優化BP神經網絡拟合非線性函數1.遺傳算法理論基礎2.具體程式設計實作Matlab

更:仿真源于《MATLAB 神經網絡43個案例分析》,代碼和資料https://download.csdn.net/download/v13910/20036311,也可以去北航出版社搜這本書然後下載下傳免費資源;

pdf書有需要發郵箱;

繼續閱讀