一 BP神经网络实现不使用MATLAB神经网络工具箱
二 使用MATLAB的神经网络工具箱简易实现BP网络
一. 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);
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 < error0
break;
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);
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;
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(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-');
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)
2. figure(2)
3. figure(3)
可以看出,使用BP网络中的负梯度下降原理之后,效果显著。
二. 使用MATLAB的神经网络工具箱简易实现BP网络
1. 问题
同<一>
2. 分析
同<一>
3. 工具箱中的相关函数(一些参考了MATLAB自带的英文手册)
mapminmax函数
- 功能:通过将原矩阵每行的最小值和最大值映射到[YMIN,YMAX]来得到规范化的矩阵。
- 算法:y = ( ymax - ymin ) * ( x - xmin ) / ( xmax - xmin ) + ymin
(注:当xmax与xmin相等时,则对原矩阵使用mapminmax函数仍得到原矩阵)
(默认情况下,mapminmax函数的YMIN和YMAX分别是-1和1)
y = 2 * ( x - xmin ) / ( xmax - xmin ) - 1
- 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函数
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);
net = newff(pn, tn, [3 7 2], {'purelin', 'logsig', 'purelin'});
net.trainParam.show = 10;
net.trainParam.epochs = 5000;
net.trainParam.lr = 0.05;
net.trainParam.goal = 0.65 * 10^(-3);
net.divideFcn = '';
net = train(net, pn, tn);
answer = sim(net, pn);
answer1 = mapminmax('reverse', answer, outputStr);
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;
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(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)
|
请发表评论