%------------初始化---------------------%
clear all;close all;
innode=1;hiddennode=15;outnode=1; %输入层4个节点,隐含层7个,输出层1个
W_F=0.1*rand(hiddennode,innode); %初始化输入层到隐层的权值
W_B=4*rand(hiddennode,1); %初始化混沌反馈层权值
W_O=0.1*rand(1,hiddennode); %设置隐层和输出层间权值(隐层有7个节点,输出层有1个节点,故需1*7矩阵)
W_T=0.1*rand(hiddennode,1); %初始化隐层阈值
H_B=rand(hiddennode,1); %初始化混沌反馈层输出
H_F=zeros(hiddennode,1);
H=zeros(hiddennode,1);
Delta_W_F=zeros(hiddennode,innode);
Delta_W_O=zeros(1,hiddennode);
Delta_W_T=zeros(hiddennode,1);
Delta_W_B=zeros(hiddennode,1);
u0=0.000075; %学习率
a=0.000065;
Epx=0;
P=zeros(hiddennode,1);
out3=zeros(outnode,1);
output=zeros(outnode,80);%存储实际输出数据
%----------------读取训练样本---------------------%
format long
fi=fopen('C:\Users\Administrator\Documents\MATLAB\BP\MDT.txt');
[te,count]=fscanf(fi,'%f',inf); %从文件中读数据到te中,读到的数据的个数放到count中
fclose(fi); %关闭文件
iteration=count/(innode+outnode); %得到读入数据的组数
f=fopen('C:\Users\Administrator\Documents\MATLAB\BP\MDT.txt'); %再次打开文件
[temp,count1]=fscanf(f,'%f ',[(innode+outnode),iteration]); %按组读入数据
data=temp'; %data等于temp的转置data为iteration*(innode+outnode)矩阵
%------------输入输出数据归一化-----------------------%
for i=1:(outnode+innode)
maxi=data(1,i);mini=data(1,i);
for j=2:iteration
if maxi>data(j,i)
ma(i)=maxi;
else
ma(i)=data(j,i);
end
maxi=ma(i);
if mini<data(j,i)
mi(i)=mini;
else
mi(i)=data(j,i);
end
mini=mi(i);
end
end %找到所有数据中的最大值和最小值
for i=1:(outnode+innode)
for j=1:iteration
da(j,i)=(data(j,i)-mi(i))/(ma(i)-mi(i));
end
end %所有数据都归一化
for i=1:innode
x(i,:)=da(:,i)';
end
%x1=da(:,1)';
%x2=da(:,2)';
%x3=da(:,3)';
%x=[x1;x2;x3]; x为输入,按列进行排列(归一化之后的输入)
y=da(:,innode+1)'; %y为网络的输出
%-------------------------主程序开始---------------------%
for s=1:1000
Epx=0; %累积误差初始化
for i=1:iteration
%反馈输出
for j=1:hiddennode
H_B(j,1)=W_B(j,1)*H_B(j,1)*(1-H_B(j,1));
end
%前向输出
H_F=W_F*x(:,i)+W_T;
H_I=H_F+H_B; %输出层的输入信号
for j=1:hiddennode
H(j,1)=1/(1+exp(-1*H_I(j,1)));
end
in3=W_O*H;
for j=1:outnode
out3(j,1)=in3(j,1); %输出层的输出
end
output(:,i)=out3; %output储存第i组输出结果
epoc(i)=i; %?????
error=0.5*abs((y(:,i)-out3)')*abs((y(:,i)-out3));%计算第i组的E
Epx=Epx+error; %误差输出
e=y(:,i)-out3; %绝对误差
epoch(s)=s; %?????
%---------------修正隐含层到输出层的权值
for m=1:outnode
for n=1:hiddennode
Delta_W_O(m,n)=Delta_W_O(m,n)+e*H(n,1);
end
end
for m=1:outnode
for n=1:hiddennode
W_O(m,n)=W_O(m,n)+u0*Delta_W_O(m,n)+a*e*H(n,1);
end
end
%_____________修正反馈权值
for j=1:hiddennode
P(j,1)=H_B(j,1)*(1-H_B(j,1))+W_B(j,1)*P(j,1)*(1-2*H_B(j,1));
end
for j=hiddennode
Delta_W_B(j,1)=Delta_W_B(j,1)+e*W_O(1,j)*H(j,1)*(1-H(j,1))*P(j,1);
end
for j=1:hiddennode
W_B(j,1)=W_B(j,1)+u0*Delta_W_B(j,1)+a*e*W_O(1,j)*H(j,1)*(1-H(j,1))*P(j,1);
end
%-------------修正阈值
for j=1:hiddennode
Delta_W_T(j,1)=Delta_W_T(j,1)+e*W_O(1,j)*H(j,1)*(1-H(j,1));
end
for j=1:hiddennode
W_T(j,1)=W_T(j,1)+u0*Delta_W_T(j,1)+a*e*W_O(1,j)*H(j,1)*(1-H(j,1));
end
for p=1:hiddennode
for q=1:innode
Delta_W_F(p,q)=Delta_W_F(p,q)+e*W_O(1,p)*H(p,1)*(1-H(p,1))*x(q,i);
end
end
for p=1:hiddennode
for q=1:innode
W_F(p,q)=W_F(p,q)+u0*Delta_W_F(p,q)+a*e*W_O(1,p)*H(p,1)*(1-H(p,1))*x(q,i);
end
end
end
er=Epx/iteration %均方差
Error(s)=er;
if er<0.000000001 %终止条件
break;
end
end
%------------------输出反归一化-----------------%
for i=1:iteration
real(i)=output(1,i)*(ma(innode+1)-mi(innode+1))+mi(innode+1);
end
%--------------显示曲线---------------------%
%subplot(2,2,1);
figure(1);
plot(epoc,real,'r',epoc,temp((innode+1),:),'b');title('训练完后的实际输出与期望输出');xlabel('epoch');ylabel('输出');grid on;
%subplot(2,2,2);
figure(2);
plot(epoch,Error);title('训练误差输出');xlabel('epoch');ylabel('误差E');grid on;
for i=1:iteration
r_error(i)=100*abs((data(i,innode+1)-real(i)))/data(i,innode+1);
end
rev_error=0;
for i=1:iteration
rev_error=rev_error+r_error(i);
end
rev_error=rev_error/iteration;
figure(3);
plot(epoc,r_error,'-');title('相对误差');ylabel('%');grid on;
%subplot(2,2,3);
%----------测试训练权值----------------------------------------------------------
%----------------读取训练样本---------------------%
ti=fopen('C:\Users\Administrator\Documents\MATLAB\BP\MD.txt');
[ti,count1]=fscanf(ti,'%f',inf);
%fclose(ti);
iteration=count1/(innode+outnode);
fo=fopen('C:\Users\Administrator\Documents\MATLAB\BP\MD.txt');
[train_data,count1]=fscanf(fo,'%f ',[(innode+outnode),iteration]);%train_data为3*81矩阵
t_data=train_data'; %t_data为81*3矩阵
%------------训练数据归一化-----------------------%
for i=1:(outnode+innode)
maxi=t_data(1,i);mini=t_data(1,i);
for j=2:iteration
if maxi>t_data(j,i)
ma(i)=maxi;
else
ma(i)=t_data(j,i);
end
maxi=ma(i);
if mini<t_data(j,i)
mi(i)=mini;
else
mi(i)=t_data(j,i);
end
mini=mi(i);
end
end %找到t_train中的最大值和最小值
for i=1:(outnode+innode)
for j=1:iteration
t_d(j,i)=(t_data(j,i)-mi(i))/(ma(i)-mi(i));
end
end %将t_d中的数据归一化后放入t_d(200*5)矩阵
%z1=t_d(:,1)';
%z2=t_d(:,2)';
%z3=t_d(:,3)';
%z=[z1;z2;z3];
for i=1:innode
z(i,:)=t_d(:,i)'; %将t_d矩阵转置为z矩阵(2*80),t-d矩阵的第i列等于z矩阵的第i行
end
%----------计算输出------------------
for i=1:iteration
%反馈输出
for j=1:hiddennode
H_B(j,1)=W_B(j,1)*H_B(j,1)*(1-H_B(j,1)); %隐含层输出
end
%前向输出
H_F= W_F*z(:,i)+W_T; %计算隐藏层的输入
H_I=H_B+H_F; %输出层的输入
for j=1:hiddennode
H(j,1)=1/(1+exp(-1*H_I(j,1)));
end
in3=W_O*H;
for j=1:outnode
out3(j,1)=in3(j,1); %输出层的输出
end
test_out(:,i)=out3;
epo(i)=i;
end
%-----------------测试输出数据反归一化-----------------%
for j=1:outnode
for i=1:iteration
t_real(j,i)=test_out(j,i)*(ma(innode+j)-mi(innode+j))+mi(innode+j);
end
end
figure(4);
plot(epo,t_real(1,:),'r',epo,train_data(innode+1,:),'b'); legend('测试输出','实际输出');title('测试数据与实际输出');grid on;
for i=1:iteration
r_error1(i)=100*abs((t_data(i,innode+1)-t_real(i)))/t_data(i,innode+1);
end
re_error=0;
for i=1:iteration
re_error=re_error+r_error1(i);
end
re_error=re_error/iteration;
%subplot(2,2,3);
figure(5);
plot(epo,r_error1,'-');title('相对误差');ylabel('%');grid on;