用MATLAB实现神经网络
- 一 BP神經網絡實現不使用MATLAB神經網絡工具箱
- 問題
- 分析
- MATLAB實現代碼
- 運行結果
- 繪制的圖像
- 二 使用MATLAB的神經網絡工具箱簡易實現BP網絡
- 問題
- 分析
- 工具箱中的相關函數一些參考了MATLAB自帶的英文手冊
- mapminmax函數
- newff函數新版本
- 關于nettrainParam的常用屬性
- train函數
- sim函數
- MATLAB實現代碼
- 運行結果
- 繪制的圖像
-
一. BP神經網絡實現(不使用MATLAB神經網絡工具箱)
1. 問題
公路運量主要包括公路客運量和公路貨運量兩方面。某個地區的公路運量主要與該地區的人數、機動車數量和公路面積有關,已知該地區20年(1990-2009)的公路運量相關數據如下:
人數/萬人
20.55 22.44 25.37 27.13 29.45 30.10 30.96 34.06 36.42 38.09 39.13 39.99 41.93 44.59 47.30 52.89 55.73 56.76 59.17 60.63
機動車數量/萬輛
0.6 0.75 0.85 0.9 1.05 1.35 1.45 1.6 1.7 1.85 2.15 2.2 2.25 2.35 2.5 2.6 2.7 2.85 2.95 3.1
公路面積/單位:萬平方公里
0.09 0.11 0.11 0.14 0.20 0.23 0.23 0.32 0.32 0.34 0.36 0.36 0.38 0.49 0.56 0.59 0.59 0.67 0.69 0.79
公路客運量/萬人
5126 6217 7730 9145 10460 11387 12353 15750 18304 19836 21024 19490 20433 22598 25107 33442 36836 40548 42927 43462
公路貨運量/萬噸
1237 1379 1385 1399 1663 1714 1834 4322 8132 8936 11099 11203 10524 11115 13320 16762 18673 20724 20803 21804
2. 分析
樣本數據較多,且已知影響數據的因素(三大因素:該地區的人數、機動車數量和公路面積),可考慮將其作為BP神經網絡的訓練集,對該神經網絡進行訓練,然后對訓練好的神經網絡進行測試,最后使用測試合格的神經網絡進行預測工作。
3. MATLAB實現代碼
BP_road.m
numberOfSample = 20; %輸入樣本數量 %取測試樣本數量等于輸入(訓練集)樣本數量,因為輸入樣本(訓練集)容量較少,否則一般必須用新鮮數據進行測試 numberOfTestSample = 20; numberOfForcastSample = 2; numberOfHiddenNeure = 8; inputDimension = 3; outputDimension = 2;%準備好訓練集%人數(單位:萬人) numberOfPeople=[20.55 22.44 25.37 27.13 29.45 30.10 30.96 34.06 36.42 38.09 39.13 39.99 41.93 44.59 47.30 52.89 55.73 56.76 59.17 60.63]; %機動車數(單位:萬輛) numberOfAutomobile=[0.6 0.75 0.85 0.9 1.05 1.35 1.45 1.6 1.7 1.85 2.15 2.2 2.25 2.35 2.5 2.6 2.7 2.85 2.95 3.1]; %公路面積(單位:萬平方公里) roadArea=[0.09 0.11 0.11 0.14 0.20 0.23 0.23 0.32 0.32 0.34 0.36 0.36 0.38 0.49 0.56 0.59 0.59 0.67 0.69 0.79]; %公路客運量(單位:萬人) passengerVolume = [5126 6217 7730 9145 10460 11387 12353 15750 18304 19836 21024 19490 20433 22598 25107 33442 36836 40548 42927 43462]; %公路貨運量(單位:萬噸) freightVolume = [1237 1379 1385 1399 1663 1714 1834 4322 8132 8936 11099 11203 10524 11115 13320 16762 18673 20724 20803 21804];%由系統時鐘種子產生隨機數 rand('state', sum(100*clock));%輸入數據矩陣 input = [numberOfPeople; numberOfAutomobile; roadArea]; %目標(輸出)數據矩陣 output = [passengerVolume; freightVolume];%對訓練集中的輸入數據矩陣和目標數據矩陣進行歸一化處理 [sampleInput, minp, maxp, tmp, mint, maxt] = premnmx(input, output);%噪聲強度 noiseIntensity = 0.01; %利用正態分布產生噪聲 noise = noiseIntensity * randn(outputDimension, numberOfSample); %給樣本輸出矩陣tmp添加噪聲,防止網絡過度擬合 sampleOutput = tmp + noise;%取測試樣本輸入(輸出)與輸入樣本相同,因為輸入樣本(訓練集)容量較少,否則一般必須用新鮮數據進行測試 testSampleInput = sampleInput; testSampleOutput = sampleOutput;%最大訓練次數 maxEpochs = 50000;%網絡的學習速率 learningRate = 0.035;%訓練網絡所要達到的目標誤差 error0 = 0.65*10^(-3);%初始化輸入層與隱含層之間的權值 W1 = 0.5 * rand(numberOfHiddenNeure, inputDimension) - 0.1; %初始化輸入層與隱含層之間的閾值 B1 = 0.5 * rand(numberOfHiddenNeure, 1) - 0.1; %初始化輸出層與隱含層之間的權值 W2 = 0.5 * rand(outputDimension, numberOfHiddenNeure) - 0.1; %初始化輸出層與隱含層之間的閾值 B2 = 0.5 * rand(outputDimension, 1) - 0.1;%保存能量函數(誤差平方和)的歷史記錄 errorHistory = [];for i = 1:maxEpochs%隱含層輸出hiddenOutput = logsig(W1 * sampleInput + repmat(B1, 1, numberOfSample));%輸出層輸出networkOutput = W2 * hiddenOutput + repmat(B2, 1, numberOfSample);%實際輸出與網絡輸出之差error = sampleOutput - networkOutput;%計算能量函數(誤差平方和)E = sumsqr(error);errorHistory = [errorHistory E];if E < error0break;end%以下依據能量函數的負梯度下降原理對權值和閾值進行調整delta2 = error;delta1 = W2' * delta2.*hiddenOutput.*(1 - hiddenOutput);dW2 = delta2 * hiddenOutput';dB2 = delta2 * ones(numberOfSample, 1);dW1 = delta1 * sampleInput';dB1 = delta1 * ones(numberOfSample, 1);W2 = W2 + learningRate * dW2;B2 = B2 + learningRate * dB2;W1 = W1 + learningRate * dW1;B1 = B1 + learningRate * dB1; end%下面對已經訓練好的網絡進行(仿真)測試%對測試樣本進行處理 testHiddenOutput = logsig(W1 * testSampleInput + repmat(B1, 1, numberOfTestSample)); testNetworkOutput = W2 * testHiddenOutput + repmat(B2, 1, numberOfTestSample); %還原網絡輸出層的結果(反歸一化) a = postmnmx(testNetworkOutput, mint, maxt);%繪制測試樣本神經網絡輸出和實際樣本輸出的對比圖(figure(1))-------------------------------------- t = 1990:2009;%測試樣本網絡輸出客運量 a1 = a(1,:); %測試樣本網絡輸出貨運量 a2 = a(2,:);figure(1); subplot(2, 1, 1); plot(t, a1, 'ro', t, passengerVolume, 'b+'); legend('網絡輸出客運量', '實際客運量'); xlabel('年份'); ylabel('客運量/萬人'); title('神經網絡客運量學習與測試對比圖'); grid on;subplot(2, 1, 2); plot(t, a2, 'ro', t, freightVolume, 'b+'); legend('網絡輸出貨運量', '實際貨運量'); xlabel('年份'); ylabel('貨運量/萬噸'); title('神經網絡貨運量學習與測試對比圖'); grid on;%使用訓練好的神經網絡對新輸入數據進行預測%新輸入數據(2010年和2011年的相關數據) newInput = [73.39 75.55; 3.9635 4.0975; 0.9880 1.0268]; %利用原始輸入數據(訓練集的輸入數據)的歸一化參數對新輸入數據進行歸一化 newInput = tramnmx(newInput, minp, maxp);newHiddenOutput = logsig(W1 * newInput + repmat(B1, 1, numberOfForcastSample)); newOutput = W2 * newHiddenOutput + repmat(B2, 1, numberOfForcastSample); newOutput = postmnmx(newOutput, mint, maxt);disp('預測2010和2011年的公路客運量分別為(單位:萬人):'); newOutput(1,:) disp('預測2010和2011年的公路貨運量分別為(單位:萬噸):'); newOutput(2,:)%在figure(1)的基礎上繪制2010和2011年的預測情況------------------------------------------------- figure(2); t1 = 1990:2011;subplot(2, 1, 1); plot(t1, [a1 newOutput(1,:)], 'ro', t, passengerVolume, 'b+'); legend('網絡輸出客運量', '實際客運量'); xlabel('年份'); ylabel('客運量/萬人'); title('神經網絡客運量學習與測試對比圖(添加了預測數據)'); grid on;subplot(2, 1, 2); plot(t1, [a2 newOutput(2,:)], 'ro', t, freightVolume, 'b+'); legend('網絡輸出貨運量', '實際貨運量'); xlabel('年份'); ylabel('貨運量/萬噸'); title('神經網絡貨運量學習與測試對比圖(添加了預測數據)'); grid on;%觀察能量函數(誤差平方和)在訓練神經網絡過程中的變化情況------------------------------------------ figure(3);n = length(errorHistory); t3 = 1:n; plot(t3, errorHistory, 'r-');%為了更加清楚地觀察出能量函數值的變化情況,這里我只繪制前100次的訓練情況 xlim([1 100]); xlabel('訓練過程'); ylabel('能量函數值'); title('能量函數(誤差平方和)在訓練神經網絡過程中的變化圖'); grid on;- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
4. 運行結果
預測2010和2011年的公路客運量分別為(單位:萬人):
ans =
1.0e+04 *
4.6188 4.6601
預測2010和2011年的公路貨運量分別為(單位:萬噸):
ans =
1.0e+04 *
2.1521 2.1519
5. 繪制的圖像
- figure(1)
- 功能:通過將原矩陣每行的最小值和最大值映射到[YMIN,YMAX]來得到規范化的矩陣。
- 算法:y = ( ymax - ymin ) * ( x - xmin ) / ( xmax - xmin ) + ymin
- 默認算法:
[Y,PS] = mapminmax(X)
- X:原矩陣
- Y:對矩陣X進行規范化得到的矩陣
- PS:存放關于原矩陣規范化過程中的相關映射數據的結構體
[Y,PS] = mapminmax(X,FP)
X:原矩陣
FP:含有字段FP.ymin和FP.ymax的結構體
Y:對矩陣X進行規范化得到的矩陣(使用在FP的ymin和ymax規定下的算法)
PS:存放關于原矩陣規范化過程中的相關映射數據的結構體
Y = mapminmax(‘apply’,X,PS)
- ’apply’:必寫
- X:原矩陣
- PS:存放關于某個矩陣規范化過程中的相關映射數據的結構體
- Y:對矩陣X進行規范化得到的矩陣(使用PS中的規范化方式)
X = mapminmax(‘reverse’,Y,PS)
- ’reverse’:必寫
- Y:某個矩陣
- PS:存放關于某個矩陣規范化過程中的相關映射數據的結構體
- X:將矩陣Y反規范化得到的矩陣(使用PS中的規范化方式,這里指將矩陣X轉換為矩陣Y的規范化方式)
newff函數(新版本)
a. 功能:建立一個前饋反向傳播(BP)網絡。
b. net=newff(P,T,S)
- P: 輸入數據矩陣。(RxQ1),其中Q1代表R元的輸入向量。其數據意義是矩陣P有Q1列,每一列都是一個樣本,而每個樣本有R個屬性(特征)。一般矩陣P需要事先歸一化好,即P的每一行都歸一化到[0 1]或者[-1 1]。
- T:目標數據矩陣。(SNxQ2),其中Q2代表SN元的目標向量。數據意義參考上面,矩陣T也是事先歸一化好的。
- S:第i層的神經元個數。(新版本中可以省略輸出層的神經元個數不寫,因為輸出層的神經元個數已經取決于T)
?c. net = newff(P,T,S,TF,BTF,BLF,PF,IPF,OPF,DDF)(提供了可選擇的參數)
- TF:相關層的傳遞函數,默認隱含層使用tansig函數,輸出層使用purelin函數。
- BTF:BP神經網絡學習訓練函數,默認值為trainlm函數。
- BLF:權重學習函數,默認值為learngdm。
- PF:性能函數,默認值為mse。
- PF,OPF,DDF均為默認值即可。
d. 常用的傳遞函數:
- purelin:線性傳遞函數
- tansig:正切 S 型傳遞函數
- logsig: 對數 S 型傳遞函數
(注意:隱含層和輸出層函數的選擇對BP神經網絡預測精度有較大影響,一般隱含層節點傳遞函數選用tansig函數或logsig函數,輸出層節點轉移函數選用tansig函數或purelin函數。)
關于net.trainParam的常用屬性
(假定已經定義了一個BP網絡net)
* net.trainParam.show: 兩次顯示之間的訓練次數
* net.trainParam.epochs: 最大訓練次數
* net.trainParam.lr: 網絡的學習速率
* net.trainParam.goal: 訓練網絡所要達到的目標誤差
* net.trainParam.time: 最長訓練時間(秒)train函數
功能:訓練一個神經網絡
[NET2,TR] = train(NET1,X,T)(也可[NET2] = train(NET1,X,T) )
- NET1:待訓練的網絡
- X: 輸入數據矩陣(已歸一化)
- T:目標數據矩陣(已歸一化)
- NET2:訓練得到的網絡TR:存放有關訓練過程的數據的結構體
sim函數
功能:模擬Simulink模型
SimOut = sim(‘MODEL’, PARAMETERS)
- (見名知意,不必再解釋)
4. MATLAB實現代碼
BP_toolbox_road.m
%準備好訓練集%人數(單位:萬人) numberOfPeople=[20.55 22.44 25.37 27.13 29.45 30.10 30.96 34.06 36.42 38.09 39.13 39.99 41.93 44.59 47.30 52.89 55.73 56.76 59.17 60.63]; %機動車數(單位:萬輛) numberOfAutomobile=[0.6 0.75 0.85 0.9 1.05 1.35 1.45 1.6 1.7 1.85 2.15 2.2 2.25 2.35 2.5 2.6 2.7 2.85 2.95 3.1]; %公路面積(單位:萬平方公里) roadArea=[0.09 0.11 0.11 0.14 0.20 0.23 0.23 0.32 0.32 0.34 0.36 0.36 0.38 0.49 0.56 0.59 0.59 0.67 0.69 0.79]; %公路客運量(單位:萬人) passengerVolume = [5126 6217 7730 9145 10460 11387 12353 15750 18304 19836 21024 19490 20433 22598 25107 33442 36836 40548 42927 43462]; %公路貨運量(單位:萬噸) freightVolume = [1237 1379 1385 1399 1663 1714 1834 4322 8132 8936 11099 11203 10524 11115 13320 16762 18673 20724 20803 21804];%輸入數據矩陣 p = [numberOfPeople; numberOfAutomobile; roadArea]; %目標(輸出)數據矩陣 t = [passengerVolume; freightVolume];%對訓練集中的輸入數據矩陣和目標數據矩陣進行歸一化處理 [pn, inputStr] = mapminmax(p); [tn, outputStr] = mapminmax(t);%建立BP神經網絡 net = newff(pn, tn, [3 7 2], {'purelin', 'logsig', 'purelin'});%每10輪回顯示一次結果 net.trainParam.show = 10;%最大訓練次數 net.trainParam.epochs = 5000;%網絡的學習速率 net.trainParam.lr = 0.05;%訓練網絡所要達到的目標誤差 net.trainParam.goal = 0.65 * 10^(-3);%網絡誤差如果連續6次迭代都沒變化,則matlab會默認終止訓練。為了讓程序繼續運行,用以下命令取消這條設置 net.divideFcn = '';%開始訓練網絡 net = train(net, pn, tn);%使用訓練好的網絡,基于訓練集的數據對BP網絡進行仿真得到網絡輸出結果 %(因為輸入樣本(訓練集)容量較少,否則一般必須用新鮮數據進行仿真測試) answer = sim(net, pn);%反歸一化 answer1 = mapminmax('reverse', answer, outputStr);%繪制測試樣本神經網絡輸出和實際樣本輸出的對比圖(figure(1))------------------------------------------- t = 1990:2009;%測試樣本網絡輸出客運量 a1 = answer1(1,:); %測試樣本網絡輸出貨運量 a2 = answer1(2,:);figure(1); subplot(2, 1, 1); plot(t, a1, 'ro', t, passengerVolume, 'b+'); legend('網絡輸出客運量', '實際客運量'); xlabel('年份'); ylabel('客運量/萬人'); title('神經網絡客運量學習與測試對比圖'); grid on;subplot(2, 1, 2); plot(t, a2, 'ro', t, freightVolume, 'b+'); legend('網絡輸出貨運量', '實際貨運量'); xlabel('年份'); ylabel('貨運量/萬噸'); title('神經網絡貨運量學習與測試對比圖'); grid on;%使用訓練好的神經網絡對新輸入數據進行預測%新輸入數據(2010年和2011年的相關數據) newInput = [73.39 75.55; 3.9635 4.0975; 0.9880 1.0268]; %利用原始輸入數據(訓練集的輸入數據)的歸一化參數對新輸入數據進行歸一化 newInput = mapminmax('apply', newInput, inputStr);%進行仿真 newOutput = sim(net, newInput);%反歸一化 newOutput = mapminmax('reverse',newOutput, outputStr);disp('預測2010和2011年的公路客運量分別為(單位:萬人):'); newOutput(1,:) disp('預測2010和2011年的公路貨運量分別為(單位:萬噸):'); newOutput(2,:)%在figure(1)的基礎上繪制2010和2011年的預測情況------------------------------------------------------- figure(2); t1 = 1990:2011;subplot(2, 1, 1); plot(t1, [a1 newOutput(1,:)], 'ro', t, passengerVolume, 'b+'); legend('網絡輸出客運量', '實際客運量'); xlabel('年份'); ylabel('客運量/萬人'); title('神經網絡客運量學習與測試對比圖(添加了預測數據)'); grid on;subplot(2, 1, 2); plot(t1, [a2 newOutput(2,:)], 'ro', t, freightVolume, 'b+'); legend('網絡輸出貨運量', '實際貨運量'); xlabel('年份'); ylabel('貨運量/萬噸'); title('神經網絡貨運量學習與測試對比圖(添加了預測數據)'); grid on;- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
5. 運行結果
預測2010和2011年的公路客運量分別為(單位:萬人):
ans =
1.0e+04 *
4.4384 4.4656
預測2010和2011年的公路貨運量分別為(單位:萬噸):
ans =
1.0e+04 *
2.1042 2.1139
6. 繪制的圖像
- figure(1)
- figure(2)
2. figure(2)
3. figure(3)
可以看出,使用BP網絡中的負梯度下降原理之后,效果顯著。
二. 使用MATLAB的神經網絡工具箱簡易實現BP網絡
1. 問題
同<一>
2. 分析
同<一>
3. 工具箱中的相關函數(一些參考了MATLAB自帶的英文手冊)
mapminmax函數
(注:當xmax與xmin相等時,則對原矩陣使用mapminmax函數仍得到原矩陣)
(默認情況下,mapminmax函數的YMIN和YMAX分別是-1和1)
y = 2 * ( x - xmin ) / ( xmax - xmin ) - 1
總結
以上是生活随笔為你收集整理的用MATLAB实现神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用JQuery插件CleverTabs
- 下一篇: 用FileZilla Server搭建f