误差逆传播算法(error back propagation)简称BP网络算法。而一般在说BP网络算法时,默认BP神经网络是一种多层前馈神经网络,该网络的主要特点是信号向前传递,误差反向传播。在向前传递中,输入信号是从输入层经隐含逐层处理,直至输出层。每一层的神经状态只影响下一层神经元状态。如果输出层不到期望输出,则转入反向传播,根据预测误差调整网络权值和阈值,从而使BP神经网络预测输出不断逼近期望输出。
由于神经网络的训练需要将数据集分为训练集,验证集和测试集,因此如果某变量严重程度的样本数过少,神经网络将无法学习其中的特征。
在构建神经网络的过程中,隐层节点数目的确定非常重要。虽然目前没有一个确切的公式来确定具体的隐层数目,但是为确保模型的有效性,有以下两条经验原则需要遵守.
1. 输入节点个数小于样本数
2. 样本数不大于连接权数
当输入节点数由主成分分析决定后,隐层节点的个数也大致确定。
在神经网络中,神经元接收到来自来自其他神经元的输入信号,这些信号乘以权重累加到神经元接收的总输入值上,随后与当前神经元的阈值进行比较,然后通过激活函数处理,产生神经元的输出。
神经网络模型建立
我们输入:
输出:
并对神经网络进行监督正向传播得到输出层误差,并判断是否反向传播,之后进行误差的反向传播;设网络结构是一个含有N个神经元的输入层,含有P个神经元的隐层,含有Q个神经元的输出层,用(-1,1)内的随机数初始化误差函数,并设定精度,最多迭代次数M,随机选取第k个输入样本及对应的期望输出。
误差函数:
计算隐含层个神经元的输入和输出至误差达到要求:
误差函数e对输出层各神经元的偏导数为:
误差函数对隐藏层各神经元的偏导数为:
利用偏导数来修正输出层连接权值
隐藏层连接权值修正为:
全局误差为(m个样本,q个类别)
BP神经网络模型求解
我的数据以输入层神经元数为4,隐层神经元数为60为优,自己调,输出层神经元数为2,迭代次数为1000,梯度为1.00e-05,训练精度目标显示迭代2000次后有效性检验为6,即进行6次迭代便可达到有效结果。
梯度接近目标精度1e-5;Validation Checks在训练时,用training训练,每训练一次,系统自动会将validation set中的样本数据输入神经网络进行验证在validation set输入后会得出一个均方误差,系统判断这个误差是否在连续9次检验后没有下降或者上升,说明training set训练的误差已经不再减小,停止训练。对预测结果与当前实际数据的误差分析,在一定方面检验了预测结果的误差大小,误差绝大多数分布在[-1,1]之间,只有极少数数据误差大于5,故预报结果具有一定的准确性,可以认为神经网络训练比较成功。
易看出模型拟合良好并且训练精度结果为99.166%,可以认为模型建立优秀。
%准备好训练集 clear all;clc; %天气状况 weather=xlsread('C:\Users\lenovo\Desktop\变量转换.xls','D2:D299'); %风 wind=xlsread('C:\Users\lenovo\Desktop\变量转换.xls','E2:E299'); %低温 lowTemp=xlsread('C:\Users\lenovo\Desktop\变量转换.xls','C2:C299'); %高温 highTemp=xlsread('C:\Users\lenovo\Desktop\变量转换.xls','B2:B299'); %总人数 passengerVolume =xlsread('C:\Users\lenovo\Desktop\影响因素.xlsx','F2:F299'); %公务舱 freightVolume=xlsread('C:\Users\lenovo\Desktop\影响因素.xlsx','C2:C299'); %输入数据矩阵 p = [weather wind lowTemp highTemp]'; %目标(输出)数据矩阵 t = [passengerVolume freightVolume]'; %对训练集中的输入数据矩阵和目标数据矩阵进行归一化处理 [pn, inputStr] = mapminmax(p); [tn, outputStr] = mapminmax(t); %建立BP神经网络 net = newff(pn, tn, [4 20 2], {'purelin', 'logsig', 'purelin'}); %每10轮回显示一次结果 net.trainParam.show = 10; %最大训练次数 net.trainParam.epochs = 1000; %网络的学习速率 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 = 1:298; %测试样本网络输出总人数 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; %使用训练好的神经网络对新输入数据进行预测 %新输入数据(11月1至7号的相关数据) newInput = [-1.61 -0.36 -0.11 0.11 -0.36 0.06 -0.36; 0.65 -0.65 -0.65 -0.65 -0.65 -0.65 -0.23; -0.7 -0.7 -0.7 -0.3 1.79 -0.06 -0.06; 0.09 0.75 0.75 -0.58 0.09 -1.57 0.73; ]; %利用原始输入数据(训练集的输入数据)的归一化参数对新输入数据进行归一化 newInput = mapminmax('apply', newInput, inputStr); %进行仿真 newOutput = sim(net, newInput); %反归一化 newOutput = mapminmax('reverse',newOutput, outputStr); disp('预测11月1至7号总人数分别为(单位:人):'); newOutput(1,:) disp('预测11月1至7号公务舱分别为(单位:人):'); newOutput(2,:) %在figure(1)的基础上绘制2010和2011年的预测情况------------------------------------------------------- figure(2); t1 = 1:305; 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;