Matlab自带的神经网络工具包已封装好不便于调试中间参数,且Simulink的工具包也只能用于样本离线的在线训练。本次搭建了一个简单的基于Simulink的8层神经网络在线训练,可以通过示波器模块观察到ANN运行中每个参数的变化。通过改装模块也可以实现样本更新的神经网络在线训练。
仿真源文件可私信,欢迎批评指正。
BP神经网络模型结构包含Input Layer,Hidden Layer, Output layer。基本结构如图所示。构成每一个神经层的节点称为神经元,图中表示网络的 输入;、表示网络隐层的权值和偏置值;表示激活函数,表示隐层输出值;是网络输出层。将各层网络参数向量化, 用矩阵形式表示为
其中是Hidden Layer的过渡值,激活函数g通常为可微非线性函数,目的是优化拟合效果,加快收敛。
本次代码背景选取激活函数g为Sigmoid函数
此外,实际的输入,输出和网络的输入、输出之间通常还要进行归一化处理,本次归一化函数为
同理,网络输出转化程实际输出值还要进行反归一化处理。
梯度下降法求网络参数等这里不再叙述。
背景摘自某CSDN文章,是关于各因素影响下交通流量的拟合和预测。
输入量:人数(单位:万人)、机动车数(单位:万辆)、公路面积(单位:万平方公里)
输出量:公路客运量(单位:万人)、公路货运量(单位:万吨)
已知1990-2009年20个样本的值如下:
%人数(单位:万人)
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];
因为涉及各种矩阵模块的运算,demux模块使用会混乱。所以老老实实谁对应谁连接起来。
其中in、out模块为将多个输入输出向量统一处理为矩阵。premmix模块为归一化处理,将归一化后的输入、输出值接至traning模块。模块输出hidden layer的关系矩阵 W,b ,并通过延迟模块将上一时刻的迭代输出作为下一时刻的输入。
防止网络过拟合,加入了噪声模块。
function noise = fcn()
outputDimension = 2;
numberOfSample = 20; %输入样本数量
%噪声强度
noiseIntensity = 0.01;
%利用正态分布产生噪声
noise = noiseIntensity * randn(outputDimension, numberOfSample);
%给样本输出矩阵tmp添加噪声,防止网络过度拟合
end
搭建8层网络,三个输入两个输出,ANN训练模块函数如下:
function [W1d,B1d,W2d,B2d] = ANN_Training(sampleInput,tmp,W1,B1,W2,B2,noise,T)
numberOfSample = 20; %输入样本数量
numberOfHiddenNeure = 8;
inputDimension = 3;
outputDimension = 2;
%重置种子产生随机数
%添加噪声
sampleOutput = tmp + noise;
%网络的学习速率
learningRate = 0.035;
if T==0
%初始化输入层与隐含层之间的权值
W1d = 0.5 * rand(numberOfHiddenNeure, inputDimension) - 0.1;
%初始化输入层与隐含层之间的阈值
B1d = 0.5 * rand(numberOfHiddenNeure, 1) - 0.1;
%初始化输出层与隐含层之间的权值
W2d = 0.5 * rand(outputDimension, numberOfHiddenNeure) - 0.1;
%初始化输出层与隐含层之间的阈值
B2d = 0.5 * rand(outputDimension, 1) - 0.1;
else
%隐含层输出
hiddenOutput_mid=W1 * sampleInput + repmat(B1, 1, numberOfSample);
hiddenOutput = 1./(1+exp(-hiddenOutput_mid));
%输出层输出
networkOutput = W2 * hiddenOutput + repmat(B2, 1, numberOfSample);
%实际输出与网络输出之差e
error = sampleOutput - networkOutput;
%以下依据能量函数的负梯度下降原理对权值和阈值进行调整
delta2 = error;
delta1 = W2' * delta2.*hiddenOutput.*(1 - hiddenOutput);
dW2 = delta2 * hiddenOutput';
dB2 = delta2 * ones(numberOfSample, 1);
dW1 = delta1 * sampleInput';
dB1 = delta1 * ones(numberOfSample, 1);
W2d = W2 + learningRate * dW2;
B2d = B2 + learningRate * dB2;
W1d = W1 + learningRate * dW1;
B1d = B1 + learningRate * dB1;
end
end
拟合效果测试函数:
function y = test(X,y0,W1,B1,W2,B2,mint,maxt)
numberOfTestSample = 20;
h_mid=W1*X+repmat(B1, 1, numberOfTestSample);
h=1./(1+exp(-h_mid));
y=W2*h+ repmat(B2, 1, numberOfTestSample);
y1 = y(1,:);
y0=(y0-min(y0))/(max(y0)-min(y0))*2-1;
t = 1990:2009;
plot(t, y1, 'ro', t, y0, 'b+');
end
运行100s,时钟采样周期0.1s变化一次,相当于迭代1000次,用示波器观察的收敛过程,可以看到收敛明显。
观察拟合效果,横轴为时间,纵轴为公路客运量(单位:万人)