Matlab神經網絡函數newff()新舊用法差異

原文鏈接:https://www.cnblogs.com/xxfcz/p/4482813.html

摘要

  在Matlab R2010a版中,如果要創建一個具有兩個隱含層、且神經元數分別爲5、3的前向BP網絡,使用舊的語法可以這樣寫:

        net1 = newff(minmax(P), [5 3 1]);

注意minmax()函數的使用,還有對輸出層神經元數(1)的指定。

  當然也可以採用新的語法,更簡潔(請留意差異):

        net2 = newff(PT, [5 3]);

不用求minmax,也不用人工指定輸出層神元數了(newff會根據參數T自行推導)。

不過,爲了得到與書本示例接近的結果,接下來需要清除net2.divideFcn等屬性再訓練,否則結果相去甚遠,且遠不止一個數量級。

    net2.divideFcn = '';

    net2.inputs{1}.processFcns = {};  % 1是輸入層所在網絡層編號

    net2.outputs{3}.processFcns = {};    % 3 是輸出層所在網絡層編號

 

 

正文

  最近在看朱凱的《精通Matlab神經網絡》,到第10章例10-3時,發現newff()的新舊用法得到的結果相去甚遠。

  書中例10-3採用了舊式寫法,代碼如下:

% 例10-3,舊式寫法

 

clear all

P = [-1 -1 2 2; 0 5 0 5];

T = [-1 -1 2 2];

 

%% 舊式語法

net1 = newff(minmax(P),[5 1],{'tansig', 'purelin'}, 'traingd'); % 隱含層有5個神經元

 

net1.trainParam.goal = 1e-5;

net1.trainParam.epochs = 300;

net1.trainParam.lr = 0.05;

net1.trainParam.showWindow = 1;

net1= train(net1,P,T);

 

Y1 = sim(net1,P);

disp(['舊式語法 mse: ' num2str(mse(T-Y1))]);

 

  訓練窗口最終如下:

 

 

  程序輸出如下:

Warning: NEWFF used in an obsolete way.

> In nntobsu at 18

In newff at 86

See help for NEWFF to update calls to the new argument list.

 

舊式語法 mse: 9.8073e-006

 

  很明顯,達到了設定的1e-5的目標。

 

  不過我們也收到了警告,建議我們採用新的參數列表。於是查幫助,改成新的寫法,代碼如下:

% 例10-3,新式寫法

 

clear all

P = [-1 -1 2 2; 0 5 0 5];

T = [-1 -1 2 2];

 

%% 新式語法

net2 = newff(P,T,5,{'tansig', 'purelin'}, 'traingd'); % 隱含層有5個神經元

 

net2.trainParam.goal = 1e-5;

net2.trainParam.epochs = 300;

net2.trainParam.lr = 0.05;

net2.trainParam.showWindow = 1;

net2 = train(net2,P,T);

 

Y2 = sim(net2,P);

disp(['新式語法 mse: ' num2str(mse(T-Y2))]);

 

  訓練窗口:

  程序輸出:

新式語法 mse: 10.7499

 

  可見,遠遠沒有達到1e-5的目標。

  這是爲什麼呢?QQ羣諮詢無果,無奈之下自行研究源碼。

  newff.m分成三大塊:主程序、新版實現子函數 new_5p1()、舊版實現子函數 new_5p0()。通過仔細比較新舊這兩個子函數,發現新版設置了 net.divideFcn 屬性,其值爲'dividerand'。該函數把樣本數據三分爲訓練集、驗證集和測試集,默認比例是6:2:2。於是在我的程序中清除該屬性再訓練:

 

% 例10-3,新寫法,改進

 

clear all

P = [-1 -1 2 2; 0 5 0 5];

T = [-1 -1 2 2];

 

%% 新式語法

net2 = newff(P,T,5,{'tansig', 'purelin'}, 'traingd'); % 隱含層有5個神經元

 

net2.trainParam.goal = 1e-5;

net2.trainParam.epochs = 300;

net2.trainParam.lr = 0.05;

net2.trainParam.showWindow = 1;

net2.divideFcn = ''; % 爲和書本一致,對於樣本極少的情況,不要再三分了

net2 = train(net2,P,T);

 

Y2 = sim(net2,P);

disp(['新式語法,改進 mse: ' num2str(mse(T-Y2))]);

 

  訓練窗口:

 

  程序輸出:

新式語法,改進 mse: 9.8129e-006

 

    也達到了預期目標。

 

    其實,新舊兩次的訓練窗口和Performance窗口也可以發現端倪的,此處不再細說,請各位看官自行對比。

    當然,至於新版爲什麼要引入divideFcn必有其道理,我是初學者,有所揣測暫不表,先跟着書走。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章