MATLAB人工神經網路ANN程式碼

2023-02-09 12:01:40

  本文介紹基於MATLAB實現人工神經網路ANN)迴歸的詳細程式碼與操作。

  在之前的文章MATLAB實現隨機森林(RF)迴歸與自變數影響程度分析中,我們對基於MATLAB隨機森林(RF)迴歸與變數影響程度(重要性)排序的程式碼加以詳細講解與實踐。本次我們繼續基於MATLAB,對另一種常用的機器學習方法——神經網路方法加以程式碼實戰。

  首先需要註明的是,在MATLAB中,我們可以直接基於「APP」中的「Neural Net Fitting」工具箱實現在無需程式碼的情況下,對神經網路演演算法加以執行。

  基於工具箱的神經網路方法雖然方便,但是一些引數不能調整;同時也不利於我們對演演算法、程式碼的理解。因此,本文不利用「Neural Net Fitting」工具箱,而是直接通過程式碼將神經網路方法加以執行——但是,本文的程式碼其實也是通過上述工具箱執行後生成的;而這種生成神經網路程式碼的方法也是MATLAB官方推薦的方式。

  另外,需要注意的是,本文直接進行神經網路演演算法的執行,省略了前期資料處理、訓練集與測試集劃分、精度衡量指標選取等。因此建議大家先將文章MATLAB實現隨機森林(RF)迴歸與自變數影響程度分析閱讀後,再閱讀本文。

  本文分為兩部分,首先是將程式碼分段、詳細講解,方便大家理解;隨後是完整程式碼,方便大家自行嘗試。

1 分解程式碼

1.1 迴圈準備

  由於機器學習往往需要多次執行,我們就在此先定義迴圈。

%% ANN Cycle Preparation

ANNRMSE=9999;
ANNRunNum=0;
ANNRMSEMatrix=[];
ANNrAllMatrix=[];
while ANNRMSE>400

  其中,ANNRMSE是初始的RMSEANNRunNum是神經網路演演算法當前執行的次數;ANNRMSEMatrix用來儲存每一次神經網路執行後所得到的RMSE結果;ANNrAllMatrix用來儲存每一次神經網路執行後所得到的皮爾遜相關係數結果;最後一句表示當所得到的模型RMSE>400時,則停止迴圈。

1.2 神經網路構建

  接下來,我們對神經網路的整體結構加以定義。

%% ANN

x=TrainVARI';
t=TrainYield';
trainFcn = 'trainlm';
hiddenLayerSize = [10 10 10];
ANNnet = fitnet(hiddenLayerSize,trainFcn);

  其中,TrainVARITrainYield分別是我這裡訓練資料的自變數(特徵)與因變數(標籤);trainFcn為神經網路所選用的訓練函數方法名稱,其名稱與對應的方法對照如下表:

  hiddenLayerSize為神經網路所用隱層與各層神經元個數,[10 10 10]代表共有三層隱層,各層神經元個數分別為101010

1.3 資料處理

  接下來,對輸入神經網路模型的資料加以處理。

ANNnet.input.processFcns = {'removeconstantrows','mapminmax'};
ANNnet.output.processFcns = {'removeconstantrows','mapminmax'};
ANNnet.divideFcn = 'dividerand';
ANNnet.divideMode = 'sample';
ANNnet.divideParam.trainRatio = 0.6;
ANNnet.divideParam.valRatio = 0.4;
ANNnet.divideParam.testRatio = 0.0;

  其中,ANNnet.input.processFcnsANNnet.output.processFcns分別代表輸入模型資料的處理方法,'removeconstantrows'表示刪除在各樣本中數值始終一致的特徵列,'mapminmax'表示將資料歸一化處理;divideFcn表示劃分資料訓練集、驗證集與測試集的方法,'dividerand'表示依據所給定的比例隨機劃分;divideMode表示對資料劃分的維度,我們這裡選擇'sample',也就是對樣本進行劃分;divideParam表示訓練集、驗證集與測試集所佔比例,那麼在這裡,因為是直接用了先前隨機森林方法(可以看這篇部落格)中的資料劃分方式,那麼為了保證訓練集、測試集的固定,我們就將divideParam.testRatio設定為0.0,然後將訓練集與驗證集比例劃分為0.60.4

1.4 模型訓練引數設定

  接下來對模型執行過程中的主要引數加以設定。

ANNnet.performFcn = 'mse';
ANNnet.trainParam.epochs=5000;
ANNnet.trainParam.goal=0.01;

  其中,performFcn為模型誤差衡量函數,'mse'表示均方誤差;trainParam.epochs表示訓練時Epoch次數,trainParam.goal表示模型所要達到的精度要求(即模型執行到trainParam.epochs次時或誤差小於trainParam.goal時將會停止執行)。

1.5 神經網路實現

  這一部分程式碼大多數與繪圖、程式碼與GUI生成等相關,因此就不再一一解釋了,大家可以直接執行。需要注意的是,train是模型訓練函數。

% For a list of all plot functions type: help nnplot
ANNnet.plotFcns = {'plotperform','plottrainstate','ploterrhist','plotregression','plotfit'};
[ANNnet,tr] = train(ANNnet,x,t);
y = ANNnet(x);
e = gsubtract(t,y);
performance = perform(ANNnet,t,y);
% Recalculate Training, Validation and Test Performance
trainTargets = t .* tr.trainMask{1};
valTargets = t .* tr.valMask{1};
testTargets = t .* tr.testMask{1};
trainPerformance = perform(ANNnet,trainTargets,y);
valPerformance = perform(ANNnet,valTargets,y);
testPerformance = perform(ANNnet,testTargets,y);
% view(net)
% Plots
%figure, plotperform(tr)
%figure, plottrainstate(tr)
%figure, ploterrhist(e)
%figure, plotregression(t,y)
%figure, plotfit(net,x,t)
% Deployment
% See the help for each generation function for more information.
if (false)
    % Generate MATLAB function for neural network for application
    % deployment in MATLAB scripts or with MATLAB Compiler and Builder
    % tools, or simply to examine the calculations your trained neural
    % network performs.
    genFunction(ANNnet,'myNeuralNetworkFunction');
    y = myNeuralNetworkFunction(x);
end
if (false)
    % Generate a matrix-only MATLAB function for neural network code
    % generation with MATLAB Coder tools.
    genFunction(ANNnet,'myNeuralNetworkFunction','MatrixOnly','yes');
    y = myNeuralNetworkFunction(x);
end
if (false)
    % Generate a Simulink diagram for simulation or deployment with.
    % Simulink Coder tools.
    gensim(ANNnet);
end

1.6 精度衡量

%% Accuracy of ANN

ANNPredictYield=sim(ANNnet,TestVARI')';
ANNRMSE=sqrt(sum(sum((ANNPredictYield-TestYield).^2))/size(TestYield,1));
ANNrMatrix=corrcoef(ANNPredictYield,TestYield);
ANNr=ANNrMatrix(1,2);
ANNRunNum=ANNRunNum+1;
ANNRMSEMatrix=[ANNRMSEMatrix,ANNRMSE];
ANNrAllMatrix=[ANNrAllMatrix,ANNr];
disp(ANNRunNum);
end
disp(ANNRMSE);

  其中,ANNPredictYield為預測結果;ANNRMSEANNrMatrix分別為模型精度衡量指標RMSE與皮爾遜相關係數。結合本文1.1部分可知,我這裡設定為當所得神經網路模型RMSE400以內時,將會停止迴圈;否則繼續開始執行本文1.2部分至1.6部分的程式碼。

1.7 儲存模型

  這一部分就不再贅述了,大家可以參考文章MATLAB實現隨機森林(RF)迴歸與自變數影響程度分析

%% ANN Model Storage

ANNModelSavePath='G:\CropYield\02_CodeAndMap\00_SavedModel\';
save(sprintf('%sRF0417ANN0399.mat',ANNModelSavePath),'TestVARI','TestYield','TrainVARI','TrainYield','ANNnet','ANNPredictYield','ANNr','ANNRMSE',...
    'hiddenLayerSize');

2 完整程式碼

  完整程式碼如下:

%% ANN Cycle Preparation
ANNRMSE=9999;
ANNRunNum=0;
ANNRMSEMatrix=[];
ANNrAllMatrix=[];
while ANNRMSE>1000

%% ANN
x=TrainVARI';
t=TrainYield';
trainFcn = 'trainlm';
hiddenLayerSize = [10 10 10];
ANNnet = fitnet(hiddenLayerSize,trainFcn);
ANNnet.input.processFcns = {'removeconstantrows','mapminmax'};
ANNnet.output.processFcns = {'removeconstantrows','mapminmax'};
ANNnet.divideFcn = 'dividerand';
ANNnet.divideMode = 'sample';
ANNnet.divideParam.trainRatio = 0.6;
ANNnet.divideParam.valRatio = 0.4;
ANNnet.divideParam.testRatio = 0.0;
ANNnet.performFcn = 'mse';
ANNnet.trainParam.epochs=5000;
ANNnet.trainParam.goal=0.01;
% For a list of all plot functions type: help nnplot
ANNnet.plotFcns = {'plotperform','plottrainstate','ploterrhist','plotregression','plotfit'};
[ANNnet,tr] = train(ANNnet,x,t);
y = ANNnet(x);
e = gsubtract(t,y);
performance = perform(ANNnet,t,y);
% Recalculate Training, Validation and Test Performance
trainTargets = t .* tr.trainMask{1};
valTargets = t .* tr.valMask{1};
testTargets = t .* tr.testMask{1};
trainPerformance = perform(ANNnet,trainTargets,y);
valPerformance = perform(ANNnet,valTargets,y);
testPerformance = perform(ANNnet,testTargets,y);
% view(net)
% Plots
%figure, plotperform(tr)
%figure, plottrainstate(tr)
%figure, ploterrhist(e)
%figure, plotregression(t,y)
%figure, plotfit(net,x,t)
% Deployment
% See the help for each generation function for more information.
if (false)
    % Generate MATLAB function for neural network for application
    % deployment in MATLAB scripts or with MATLAB Compiler and Builder
    % tools, or simply to examine the calculations your trained neural
    % network performs.
    genFunction(ANNnet,'myNeuralNetworkFunction');
    y = myNeuralNetworkFunction(x);
end
if (false)
    % Generate a matrix-only MATLAB function for neural network code
    % generation with MATLAB Coder tools.
    genFunction(ANNnet,'myNeuralNetworkFunction','MatrixOnly','yes');
    y = myNeuralNetworkFunction(x);
end
if (false)
    % Generate a Simulink diagram for simulation or deployment with.
    % Simulink Coder tools.
    gensim(ANNnet);
end

%% Accuracy of ANN
ANNPredictYield=sim(ANNnet,TestVARI')';
ANNRMSE=sqrt(sum(sum((ANNPredictYield-TestYield).^2))/size(TestYield,1));
ANNrMatrix=corrcoef(ANNPredictYield,TestYield);
ANNr=ANNrMatrix(1,2);
ANNRunNum=ANNRunNum+1;
ANNRMSEMatrix=[ANNRMSEMatrix,ANNRMSE];
ANNrAllMatrix=[ANNrAllMatrix,ANNr];
disp(ANNRunNum);
end
disp(ANNRMSE);

%% ANN Model Storage
ANNModelSavePath='G:\CropYield\02_CodeAndMap\00_SavedModel\';
save(sprintf('%sRF0417ANN0399.mat',ANNModelSavePath),'AreaPercent','InputOutput','nLeaf','nTree',...
    'RandomNumber','RFModel','RFPredictConfidenceInterval','RFPredictYield','RFr','RFRMSE',...
    'TestVARI','TestYield','TrainVARI','TrainYield','ANNnet','ANNPredictYield','ANNr','ANNRMSE',...
    'hiddenLayerSize');

  至此,大功告成。