clc
clear
load traffic_flux input output input_test output_test
M=size(input,2); %输入节点个数 size(A,2)意思是加载A矩阵的列数,如果是1的话就是加载行数。M为输入变量个数
N=size(output,2); %输出节点个数,同上,此代码是输出表格的列数,即输出变量的个数
n=6; %隐含层神经元个数
%上面部分为网络结构输入层,隐含层,输出层结构。
%权值和学习率,权值进行第二次迭代变换时,lr1和lr2作为偏导的系数决定权值改变的大小快慢,或者可以解释为步长。
lr1=0.01;
lr2=0.001;
maxgen=500; %系统迭代次数最高为100次
%网络权值初始化
%Wij是输入层和隐含层之间的权重,Wij是隐含层和输出层的权重,从矩阵行列个数就能看出来。而a、b是小波函数上下伸缩和左右拉长的系数。
Wjk=randn(n,M);Wjk_1=Wjk;Wjk_2=Wjk_1;
Wij=randn(N,n);Wij_1=Wij;Wij_2=Wij_1;
a=randn(1,n);a_1=a;a_2=a_1;
b=randn(1,n);b_1=b;b_2=b_1;
%节点初始化
y=zeros(1,N);
net=zeros(1,n);
net_ab=zeros(1,n);
%权值学习增量初始化,用于后面计算:Wij=Wij-lr1*d_Wij;,相当于是原文推导中的偏导
d_Wjk=zeros(n,M);
d_Wij=zeros(N,n);
d_a=zeros(1,n);
d_b=zeros(1,n);
%训练数据归一化:为什么进行归一化?因为不进行归一化的话容易引起数值问题,即数据本身很大,而神经元有效的范围大概是1.7左右,
%那么就需要乘以一个很小的数,很大的数乘以很小的数,在数值分析的误差分析中就会导致结果的误差变大,从而使得数学失效。
%而进行归一化后,所有的数据值保持适中,在(-1,1)范围内,从而数据能够发挥最大作用,将误差降到最低。
[inputn,inputps]=mapminmax(input'); %进行归一化后,归一化后的数据放在inputn中,inputps中存放的是最大值最小值等特殊信息,是一个结构体。
[outputn,outputps]=mapminmax(output');%由于input(output)中的数据同一列为相同类型数据,而归一化函数是对矩阵的行向量进行归一化,因此必须要先
%将列矩阵向量转化为行矩阵向量,也就是要将input(output)进行转置。
inputn=inputn';%为了和原数据格式一样,将转置后的矩阵再次转置回来。
outputn=outputn';
%小波神经网络训练
for i=1:maxgen %全部数据重复迭代100次
error(i)=0;%记录每一次误差,虽然代码有误差,但是我看了一边代码,误差值好像只用于了误差迭代,本质上并没有使用误差进行修正。
for kk=1:size(input,1) %k从1到276;每一行的数据都要计算一次
x=inputn(kk,:); %提取input的行数据
yqw=outputn(kk,:); %提取output的行数据,也是神经网络训练的期望输出,用以不断修正权值
%网络预测输出
for j=1:n %隐含层的个数,
for k=1:M %M=4,
net(j)=net(j)+Wjk(j,k)*x(k); %Wjk是输入层和隐含层的权值,此处是算出隐含层的某个神经元与每一个输入点的节点值
net_ab(j)=(net(j)-b(j))/a(j); %此项作为小波函数的输入自变量,a(j)和b(j)分别是小波函数参量的平移量和伸缩量,net是输入层和隐含层的连接权。
end
temp=mymorlet(net_ab(j)); %小波基函数,计算神经元通过小波函数的节点输出
for k=1:N
y=y+Wij(k,j)*temp; %小波函数节点输出值通过权值后转化为系统的输出。
end
end
%误差累积,
error(i)=error(i)+sum(abs(yqw-y));
%权值修正
for j=1:n
temp=mymorlet(net_ab(j)); %小波基函数
%计算d_W_ij的修正值
for k=1:N
d_Wij(k,j)=d_Wij(k,j)-(yqw(k)-y(k))*temp; %
end
%计算d_Wjk
temp=d_mymorlet(net_ab(j));
for k=1:M
for l=1:N
d_Wjk(j,k)=d_Wjk(j,k)+(yqw(l)-y(l))*Wij(l,j);
end
d_Wjk(j,k)=-d_Wjk(j,k)*temp*x(k)/a(j);
end
%计算d_b(b的修正值)
for k=1:N
d_b(j)=d_b(j)+(yqw(k)-y(k))*Wij(k,j);
end
d_b(j)=d_b(j)*temp/a(j);
%计算d_a(a的修正值)
for k=1:N
d_a(j)=d_a(j)+(yqw(k)-y(k))*Wij(k,j);
end
d_a(j)=d_a(j)*temp*((net(j)-b(j))/b(j))/a(j);
end
%权值参数更新
Wij=Wij-lr1*d_Wij;
Wjk=Wjk-lr1*d_Wjk;
b=b-lr2*d_b;
a=a-lr2*d_a;
d_Wjk=zeros(n,M);
d_Wij=zeros(N,n);
d_a=zeros(1,n);
d_b=zeros(1,n);
y=zeros(1,N);
net=zeros(1,n);
net_ab=zeros(1,n);
Wjk_1=Wjk;Wjk_2=Wjk_1;
Wij_1=Wij;Wij_2=Wij_1;
a_1=a;a_2=a_1;
b_1=b;b_2=b_1;
end
end
%网络预测
x=mapminmax('apply',input_test',inputps);
x=x';
%yuce=zeros(1,100);
for i=1:92
x_test=x(i,:);
for j=1:1:n
for k=1:1:M
net(j)=net(j)+Wjk(j,k)*x_test(k);
net_ab(j)=(net(j)-b(j))/a(j);
end
temp=mymorlet(net_ab(j));
for k=1:N
y(k)=y(k)+Wij(k,j)*temp;
end
end
yuce(i)=y(k); %预测结果记录
y=zeros(1,N);
net=zeros(1,n);
net_ab=zeros(1,n);
end
%网络预测反归一化
ynn=mapminmax('reverse',yuce,outputps);
%画图
figure(1);
plot(ynn,'r*:');
hold on
plot(output_test,'bo--');
hold on
predict_error=output_test-ynn';
plot(predict_error,'g')
hold on
m=0:1:100;
n=0*m;
plot(m,n)
title('预测交通流量','fontsize',12);
legend('预测交通流量','实际交通流量');
xlabel('时间点');
ylabel('交通流量');
需要数据可以或源文件可以私下联系