1. 程式人生 > >matlab實現簡單BP神經網路(不使用工具箱),兩種求誤差方式

matlab實現簡單BP神經網路(不使用工具箱),兩種求誤差方式

BP網路實現y=1+x+x*x函式模擬,輸入層一個節點,隱含層8個節點,輸出層1個節點

將資料分為測試集合和訓練集合兩部分

%% BP演算法模擬 y = 1 + x + x*x
%作者:msl 時間:2017-10-07
clc;
clear;
%% step0:定義
TrainCount = 1000;%最大訓練次數為2000次
DataNum = 1001;%訓練的資料有1001個
Hide_Out = zeros(1,8);%初始化隱含層輸出
Hide_OutTest = zeros(1,8);
Rata_H = 0.2;%隱含層學習速率
Rata_O = 0.1;%輸出層學習速率
%% step1:取資料
x = -5:0.01:6;%x的訓練資料
y = 1 + x + x.*x;%y對應於x的資料
%% step2:訓練資料歸一化和初始化權值
x_Nor = (x -(-5) + 1)/(5 - (-5) + 1);%x歸一化後得到的資料
y_Nor = (y - 0.75 + 1)/(31 - 0.75 + 1);%y歸一化後得到的資料
w = 2*(rand(1,8)-0.5);%得到輸入層到隱含層的8個權值初始化
v = 2*(rand(1,8)-0.5);%得到隱含層到輸出層的8個權值初始化
dw = zeros(1,8);%隱含層權值調整量初始化 0
dv = zeros(1,8);%輸出層權值調整量初始化 0
%%  CH  建立訓練集和測試集
xNum=length(x);
Itest=1:11:xNum;
Xtest_Nor=x_Nor(Itest);
Ytest_Nor=y_Nor(Itest);

Xtrain_Nor=x_Nor;
Ytrain_Nor=y_Nor;
Xtrain_Nor(Itest)=[];
Ytrain_Nor(Itest)=[];

%% step3:訓練神經網路
Count = 0;%迴圈次數計數器
e2 = 0;
while(1)
    %% 主體迴圈
    for i = 1:1000
        e1 = 0;
       %% 前向傳播
            for j = 1:8
               sum1 = w(j)*Xtrain_Nor(i);%隱含層輸入
               Hide_Out(j) = 1/(1 + exp(-1*sum1)); %隱含層輸出
            end
            sum2 = 0;
            for k = 1:8
                sum2 = sum2 + v(k)*Hide_Out(k);%輸出層輸入
            end
            OutputData = sum2;%輸出層輸出
            
            e1 = e1 + abs(OutputData - Ytrain_Nor(i));
       %% 反向更新
            for s = 1:8
                alfa = 0;
                alfa = alfa + (Ytrain_Nor(i) - OutputData) * v(s);
                dv(s) = Rata_O * (Ytrain_Nor(i) - OutputData) * Hide_Out(s);%更新輸出層權值
                v(s) = v(s) + dv(s);
                
                dw(s) = Rata_H * alfa * Hide_Out(s) * (1 - Hide_Out(s))*Xtrain_Nor(i);%更新隱含層權值
                w(s) = v(s) + dw(s);
            end
    end
    %%CH 計算訓練集誤差 START
    e11 = e1 / 1000;%測試樣本的平均誤差
    myErr1(Count+1)=e11; 
    %%CH 計算訓練集誤差 END
    
    %% 計算測試集
    %%% CH STRAT
    e2=0;
    %%% CH END
    for p = 1:100
        for l = 1:8
            sum3 = w(l)* Xtest_Nor(p);%測試的隱含層輸入
            Hide_OutTest(l) =  1/(1 + exp(-1*sum3));%測試的隱含層輸出
        end
        sum4 = 0;
        for m = 1:8
            sum4 = sum4 + v(m)*Hide_OutTest(m);%測試的輸出層輸入
        end                             
        OutputData_Test = sum4;%輸出層輸出
        e2 = e2 + abs(OutputData_Test - Ytest_Nor(p));
    end
    %%CH 計算測試集誤差 STRAT
    e12 = e2 / 100;%測試樣本的平均誤差
    myErr2(Count+1)=e12;
    %%CH 計算測試集誤差 END
    %%
    Count = Count + 1;%訓練次數
    
    %% 作圖
    figure(1);
    hold on
    plot(Count,e11,'r',Count,e12,'b');
    hold off
    

    if(Count >TrainCount || e12 < 0.0001)%如果訓練次數大於最大訓練次數或者誤差小於目標值,則退出訓練
        break; 
    end
end

%plot(myErr,'r');
%stop = 1;%進入測試
%% step4:測試神經網路(輸入-5到5之間資料)
% while(stop)
%     n = input('請輸入資料n =\n');
%     A = [];%儲存測試結果
%     
%     fprintf('計算的結果為:%lf\n',A);    
%      stop = input('\n輸入1繼續測試,輸入0退出測試 stop =\n ');
% end
% fprintf('程式執行結束\n');
    


第一種藍色的誤差曲線是將測試集合100個數據的輸出值減去期望再除以100得到的

第二種是訓練集合的全域性誤差 採用 e = e + | Output - y |(e為誤差,Output為測試集輸出,y為對應的期望輸出)