`
lwh394dw
  • 浏览: 17405 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

bp神经网络进行交通预测的Matlab源代码

 
阅读更多

bp神经网络进行交通预测的Matlab源代码
2012年01月17日
  %bp神经网络进行交通预测的Matlab源代码
   % BP 神经网络用于预测
   % 使用平台 - Matlab7.0
   % 数据为1986年到2000年的交通量 ,网络为3输入,1输出
   % 15组数据,其中9组为正常训练数据,3组为变量数据,3组为测试数据
   %by akjuan
   %all rights preserved by www.4math.cn
   08.11
   clc
   clear
   All_error=[];%所有误差存储
   %------------------------------------------------- --
   %原始数据
   %------------------------------------------------- --
   year=1986:2000;%数据是从1986到2000年的
   p=[493 372 445;372 445 176;445 176 235;176 235 378;235 378 429;...
      378 429 561;429 561 651;561 651 467;651 467 527;467 527 668;...
      527 668 841; 668 841 526;841 526 480;526 480 567;480 567 685]';%输入数据,共15组,每组3个输入
   t=[176 235 378 429 561 651 467 527 668 841 526 480 567 685 507];%输出数据,共15组,每组1个输出
   %------------------------------------------------- --
   %数据归一化处理,归一化数据到[-1,1],mapminmax函数调用形式
   %[y,ps] =%mapminmax(x,ymin,ymax),x需归化的数据输入,
   %ymin,ymax为需归化到的范围,不填默认为归化到[-1,1]
   %返回归化后的值y,以及参数ps,ps在结果反归一化中,需要调用
   %------------------------------------------------- --
   [normInput,ps] = mapminmax(p);
   [normTarget,ts] = mapminmax(t);
   %------------------------------------------------- --
   %数据乱序,及分类处理,将输入的15组数据,0.2%既3组,用来作为测试数据,
   % 0.2%既3组,用来作为变化数据,另外9组用来正常输入,用来训练
   %DIVIDEVEC用来重新随机抽取上述三种分类的数据,原来的顺序被打乱
   %函数调用的语法[trainV,valV,testV] = dividevec(p,t,valPercent,testPercent)
   %输入p为输入数据,t为输出数据,valPercent为训练用的变化数据在总输入中的百分比
   %testPercent为训练用的测试数据在总输入中的百分比
   %输出trainV,valV,testV分别为按乱序及相应百分比,得到的数据
   %另外,打乱后的数据,p和t都是对应的,请放心使用
   %------------------------------------------------- --
   testPercent = 0.20;  % Adjust as desired
   validatePercent = 0.20;  % Adust as desired
   [trainSamples,validateSamples,testSamples] = dividevec(normInput,normTarget,validatePercent,tes tPercent);
   for j=1:200
   %------------------------------------------------- --
   % 设置网络参数
   %------------------------------------------------- --   
   NodeNum1 = 20; % 隐层第一层节点数
   NodeNum2=40;   % 隐层第二层节点数
   TypeNum = 1;   % 输出维数
   TF1 = 'tansig';TF2 = 'tansig'; TF3 = 'tansig';%各层传输函数,TF3为输出层传输函数
   %如果训练结果不理想,可以尝试更改传输函数,以下这些是各类传输函数
   %TF1 = 'tansig';TF2 = 'logsig';
   %TF1 = 'logsig';TF2 = 'purelin';
   %TF1 = 'tansig';TF2 = 'tansig';
   %TF1 = 'logsig';TF2 = 'logsig';
   %TF1 = 'purelin';TF2 = 'purelin';
   net=newff(minmax(normInput),[NodeNum1,NodeNum2,Typ eNum],{TF1 TF2 TF3},'traingdx');%网络创建
   %------------------------------------------------- --
   % 设置训练参数
   %------------------------------------------------- --   
   net.trainParam.epochs=10000;%训练次数设置
   net.trainParam.goal=1e-6;%训练目标设置
   PL.lr=0.01;%学习率设置,应设置为较少值,太大虽然会在开始加快收敛速度,但临近最佳点时,会产生动荡,而致使无法收敛
   %------------------------------------------------- --
   % 指定训练参数
   % net.trainFcn = 'traingd'; % 梯度下降算法
   % net.trainFcn = 'traingdm'; % 动量梯度下降算法
   %
   % net.trainFcn = 'traingda'; % 变学习率梯度下降算法
   % net.trainFcn = 'traingdx'; % 变学习率动量梯度下降算法
   %
   % (大型网络的首选算法)
   % net.trainFcn = 'trainrp'; % RPROP(弹性BP)算法,内存需求最小
   %
   % 共轭梯度算法
   % net.trainFcn = 'traincgf'; % Fletcher-Reeves修正算法
   % net.trainFcn = 'traincgp'; % Polak-Ribiere修正算法,内存需求比Fletcher-Reeves修正算法略大
   % net.trainFcn = 'traincgb'; % Powell-Beal复位算法,内存需求比Polak-Ribiere修正算法略大
   % (大型网络的首选算法)
   %net.trainFcn = 'trainscg'; % Scaled Conjugate Gradient算法,内存需求与Fletcher-Reeves修正算法相同,计算量比上面三种算法都小很多
   %
   % net.trainFcn = 'trainbfg'; % Quasi-Newton Algorithms - BFGS Algorithm,计算量和内存需求均比共轭梯度算法大,但收敛比较快
   % net.trainFcn = 'trainoss'; % One Step Secant Algorithm,计算量和内存需求均比BFGS算法小,比共轭梯度算法略大
   %
   % (中型网络的首选算法)
   %net.trainFcn = 'trainlm'; % Levenberg-Marquardt算法,内存需求最大,收敛速度最快
   %
   % net.trainFcn = 'trainbr'; % 贝叶斯正则化算法
   %
   % 有代表性的五种算法为:'traingdx','trainrp','trainscg','trainoss', 'trainlm'
   net.trainfcn='traingdm';
   [net,tr] = train(net,trainSamples.P,trainSamples.T,[],[],vali dateSamples,testSamples);
   %------------------------------------------------- --
   % 训练完成后,就可以调用sim()函数,进行仿真了
   %------------------------------------------------- --   
   [normTrainOutput,Pf,Af,E,trainPerf] = sim(net,trainSamples.P,[],[],trainSamples.T);%正常输入的9组p数据,BP得到的结果t
   [normValidateOutput,Pf,Af,E,validatePerf] = sim(net,validateSamples.P,[],[],validateSamples.T) ;%用作变量3的数据p,BP得到的结果t
   [normTestOutput,Pf,Af,E,testPerf] = sim(net,testSamples.P,[],[],testSamples.T);%用作测试的3组数据p,BP得到的结果t
   %------------------------------------------------- --
   % 仿真后结果数据反归一化,如果需要预测,只需将预测的数据P填入
   % 将获得预测结果t
   %------------------------------------------------- --  
   trainOutput = mapminmax('reverse',normTrainOutput,ts);%正常输入的9组p数据,BP得到的归一化后的结果t
   trainInsect = mapminmax('reverse',trainSamples.T,ts);%正常输入的9组数据t
   validateOutput = mapminmax('reverse',normValidateOutput,ts);%用作变量3的数据p,BP得到的归一化的结果t
   validateInsect = mapminmax('reverse',validateSamples.T,ts);%用作变量3的数据t
   testOutput = mapminmax('reverse',normTestOutput,ts);%用作变量3组数据p,BP得到的归一化的结果t
   testInsect = mapminmax('reverse',testSamples.T,ts);%用作变量3组数据t
   %绝对误差计算
   absTrainError = trainOutput-trainInsect;
   absTestError = testOutput-testInsect;
   error_sum=sqrt(absTestError(1).^2+absTestError(2). ^2+absTestError(3).^2);
   All_error=[All_error error_sum];
   eps=90;%其为3组测试数据的标准差,或者每个数据偏差在一定范围内而判别
   if ((abs(absTestError(1))<=30 )&(abs(absTestError(2))<=30)&(abs(absTestError(3))<= 30)|(error_sum<=eps))
   save mynetdata net
        break
   end
   j
   end
   j
   Min_error_sqrt=min(All_error)
   testOutput
   testInsect
   %------------------------------------------------- --
   % 数据分析和绘图
   %------------------------------------------------- --  
   figure
   plot(1:12,[trainOutput validateOutput],'b-',1:12,[trainInsect validateInsect],'g--',13:15,testOutput,'m*',13:15, testInsect,'ro');
   title('o为真实值,*为预测值')
   xlabel('年份');
   ylabel('交通量(辆次/昼夜)');
   figure
   xx=1:length(All_error);
   plot(xx,All_error)
   title('误差变化图')
  [b][/b] 训练样本的目的是 数学模型的参数,经过训练之后,可以认为你的模型系统确立了下来。
  建立的模型有多好,和真实事件的差距大不大,既可以认为是测试样本的目的。
  一般训练样本和测试样本相互独立,使用不同的数据。 网上有人说测试样本集和验证样本集不一样,测试样本集数据主要用于模型可靠程度的检验,验证样本集的样本数据要在同样条件下,再另外采集一些数据用来对模型的准确性进行验证。(?)
  有人采用交叉验证,交叉验证指的的训练样本集、测试样本集、验证样本集、三中数据集都组合在一起,数据的划分采用交叉取样的方法。 二,如何选择训练集和测试集
  未完待续
  网上有人说 经常采用的是m-folder cross validation的方法,把样本分成m份,轮流把其中一份作为测试集。至于m取多少看样本数量而定,样本充足的话m=10,另外m=3也是经常被使用的 至于验证集,通常并不需要。
  三,Clementine中如何选择节点将数据分为训练集和测试集前期整理好数据后,选择partition节点 连接入数据流,在里面可以设置训练集、测试集及验证集,若要平分在测试集及训练集栏位内填上50%。 
  另外可以设置标签及数值;下面的设置是对数据表中增加标志字段(区分测试集和训练集)的数值进行选择,第一个表示使用1、2、3这样的数值来表示,第二个是 使用“1_training“等来表示,第三个是使用”training“等来表示,可以通过第二个图中的value来观察。此外下面还有设置随机种子的 选项。
  ps:在分割完不同集合后,可以右击partition节点,选择cache中enable,这样随机分割完的数据就可以暂时存在缓存中,这样不同时候进行不同建模的时候就不会因为样本不同而使结构受影响!(第一次执行后会在节点的右上方出现绿色的文件件的标签) 四,如何建立测试模型
  如果训练好模型后,把所得的模型节点从右上方拖到数据流的测试集后,建立连接后,再加个分析节点或一些结果的节点就可以了。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics