%% 该代码为bp网络
%% 清空环境变量
clc
clear
%% 训练数据预测数据提取及归一化
%数据由各文件下im_****.m生成,先将图片转换为大小为100*100的灰度图,再将100*1000排列成1*10000的特征数据集
load trousers
load skirt
load shortsleeve
load short
load longuette
load longsleeve
%%
%6个矩阵合成一个矩阵
data=[trousers;skirt;shortsleeve;short;longuette;longsleeve];%图片数据
input1=double(data)/255;%转为double类型文件,并且归一化
output1=[ones(1,size(trousers,1)) 2*ones(1,size(skirt,1)) 3*ones(1,size(shortsleeve,1)) 4*ones(1,size(short,1)) 5*ones(1,size(longuette,1)) 6*ones(1,size(longsleeve,1))];%6类标签
%%
%由于原始图片转换为100*100,因此每个图片是10000个特征,维度太高这不能直接用于训练bp网络,因此首先利用pca降维方法把10000降至D,这里D取10,
[PCALoadings,PCAScores,PCAVar] = pca(input1);%利用PCA进行降维
% percent_explained = 100 * PCAVar / sum(PCAVar);
% pareto(percent_explained) %pareto图,只显示前95%的累积分布
% xlabel('主成分')
% ylabel('贡献率(%)')
% title('主成分贡献率')
input=PCAScores(:,1:10);%利用pca进行降维至10维
%把输出从1维变成6维
output=zeros(size(output1,2),6);
for i=1:size(output1,2)
output(i,output1(i))=1;
end
%随机提取150个样本为训练样本,48个样本为预测样本
[m n]=sort(rand(1,198));
input_train=input(n(1:150),:)';
output_train=output(n(1:150),:)';
input_test=input(n(151:198),:)';
output_test=output(n(151:198),:)';
%% 网络结构初始化
innum=10;%输入层节点数
midnum=25;%隐含层节点
outnum=6;%输出层节点
%权值初始化
w1=rands(midnum,innum);
b1=rands(midnum,1);
w2=rands(midnum,outnum);
b2=rands(outnum,1);
w2_1=w2;w2_2=w2_1;
w1_1=w1;w1_2=w1_1;
b1_1=b1;b1_2=b1_1;
b2_1=b2;b2_2=b2_1;
xite=0.1;%学习率
alfa=0.01;%动量项
loopNumber=10;%训练次数
I=zeros(1,midnum);
Iout=zeros(1,midnum);
FI=zeros(1,midnum);
dw1=zeros(innum,midnum);
db1=zeros(1,midnum);
%% 网络训练
inputn=input_train;
E=zeros(1,loopNumber);
for ii=1:loopNumber
E(ii)=0;
for i=1:1:150%ce
%%
x=inputn(:,i);
% 隐含层输出
for j=1:1:midnum
I(j)=inputn(:,i)'*w1(j,:)'+b1(j);
Iout(j)=1/(1+exp(-I(j)));
end
% 输出层输出
yn=w2'*Iout'+b2;
%% 权值阀值修正
%计算误差
e=output_train(:,i)-yn;
E(ii)=E(ii)+sum(abs(e));
%计算权值变化率
dw2=e*Iout;
db2=e';
for j=1:1:midnum
S=1/(1+exp(-I(j)));
FI(j)=S*(1-S);
end
for k=1:1:innum
for j=1:1:midnum
dw1(k,j)=FI(j)*x(k)*(e(1)*w2(j,1)+e(2)*w2(j,2)+e(3)*w2(j,3)+e(4)*w2(j,4));
db1(j)=FI(j)*(e(1)*w2(j,1)+e(2)*w2(j,2)+e(3)*w2(j,3)+e(4)*w2(j,4));
end
end
w1=w1_1+xite*dw1'+alfa*(w1_1-w1_2);
b1=b1_1+xite*db1'+alfa*(b1_1-b1_2);
w2=w2_1+xite*dw2'+alfa*(w2_1-w2_2);
b2=b2_1+xite*db2'+alfa*(b2_1-b2_2);
w1_2=w1_1;w1_1=w1;
w2_2=w2_1;w2_1=w2;
b1_2=b1_1;b1_1=b1;
b2_2=b2_1;b2_1=b2;
end
end
%% 测试阶段
inputn_test=input_test;
fore=zeros(6,48);
for ii=1:1
for i=1:48%48个样本
%隐含层输出
for j=1:1:midnum
I(j)=inputn_test(:,i)'*w1(j,:)'+b1(j);
Iout(j)=1/(1+exp(-I(j)));
end
fore(:,i)=w2'*Iout'+b2;
end
end
%% 结果分析
%根据网络输出找出数据属于哪类
output_fore=zeros(1,48);
for n=1:48
[max_Y,index]=max(fore(:,n));
Y1(n)=index;
end
for n=1:48
[max_Y,index]=max(output_test(:,n));
Y2(n)=index;
end
test_accuracy=sum(Y1==Y2)/length(Y2)