赞
踩
本篇文章以BP分类为例(也可以做预测),纯手写BP神经网络。附加动量因子的BP神经网络。
编程时,激活函数选择Sigmoid函数,使用者也可以根据需要自行更改!
以经典的红酒数据分类为例,红酒数据大小为178*14,最后一列为标签列。随机算取数据的百分之70作为训练集,百分之30作为测试集。
废话不多说,接下来直接上代码!
首先是主程序代码:
- close all
- warning off
- %% 数据读取
- clc
- clear
- load Wine
- %% 数据载入
- data=Wine;
- data=data(randperm(size(data,1)),:); %此行代码用于打乱原始样本,使训练集测试集随机被抽取,有助于更新预测结果。
- input=data(:,1:end-1);
- output1 =data(:,end);
- %把输出从1维变成3维
- for i=1:size(data,1)
- switch output1(i)
- case 1
- output(i,:)=[1 0 0];
- case 2
- output(i,:)=[0 1 0];
- case 3
- output(i,:)=[0 0 1];
- end
- end
-
- %% 选取训练数据和测试数据
- m=fix(size(data,1)*0.7); %训练的样本数目
- input_train=input(1:m,:)';
- output_train=output(1:m,:)';
- input_test=input(m+1:end,:)';
- output_test=output(m+1:end,:)';
- %% 数据归一化
- [inputn,inputps]=mapminmax(input_train,0,1);
- % [outputn,outputps]=mapminmax(output_train);
- inputn_test=mapminmax('apply',input_test,inputps);
- %网络结构
- innum=size(input,2);
- midnum=20;
- outnum=size(output,2);
-
-
- %权值阈值初始化
- 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.0009;
- alfa=0.001; %附加动量因子
- I=zeros(1,midnum);
- Iout=zeros(1,midnum);
- FI=zeros(1,midnum);
- dw1=zeros(innum,midnum);
- db1=zeros(1,midnum);
-
-
- I=zeros(1,midnum);
- Iout=zeros(1,midnum);
- FI=zeros(1,midnum);
- dw1=zeros(innum,midnum);
- db1=zeros(1,midnum);
- loopNumber = 2000;
- fprintf('附加动量BP,training is begining……\n');
- tic
- for ii=1:loopNumber
- E(ii)=0; %训练误差
- for i=1:1:size(inputn,2)
- %选择本次训练数据
- 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));
- %计算w2.b2调整量
- dw2=e*Iout;
- db2=e';
- %计算w1 b1调整量
- 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
- hh = 0;
- for ij = 1:size(e,1)
- hh = hh +e(ij)*w2(j,ij);
- end
- dw1(k,j)=FI(j)*x(k)*hh;
- db1(j)=FI(j)*hh;
- 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
- w1_1=w1;
- w2_1=w2;
- b1_1=b1;
- b2_1=b2;
- E(ii) = E(ii)/size(inputn,2);
- if mod(ii,500)==0
- disp(['训练过程:',num2str(ii), '/', num2str(loopNumber),'误差为:',num2str(E(ii))])
- end
- end
- disp( ['训练时间: ',num2str(toc) ] );
- %% 将优化的权值阈值带入,用测试集求解
- for i=1:1:size(inputn_test,2)
- for j=1:1:midnum
- I(j)=inputn_test(:,i)'*w1(j,:)'+b1(j);
- Iout(j)=1/(1+exp(-I(j)));
- end
- %输出层输出
- yn=w2'*Iout'+b2;
- an0(:,i) = yn;
- end
- predict_label=zeros(1,size(an0,2));
- for i=1:size(an0,2)
- predict_label(i)=find(an0(:,i)==max(an0(:,i)));
- end
- outputt=zeros(1,size(output_test,2));
- for i=1:size(output_test,2)
- outputt(i)=find(output_test(:,i)==max(output_test(:,i)));
- end
- fprintf('test is over and plot begining……\n');
- accuracy=sum(outputt==predict_label)/length(predict_label); %计算预测的确率
- disp(['准确率:',num2str(accuracy*100),'%'])
- % 作图
- figure
- stem(1:length(predict_label),predict_label,'b^')
- hold on
- stem(1:length(predict_label),outputt,'r*')
- legend('预测类别','真实类别','NorthWest')
- title({'BP神经网络的预测效果',['测试集正确率 = ',num2str(accuracy*100),' %']})
- xlabel('预测样本编号')
- ylabel('分类结果')
- set(gca,'fontsize',10)
- %输出准确率
- disp('---------------------------测试准确率-------------------------')
- disp(['准确率:',num2str(accuracy*100),'%'])
- % 画方框图
- confMat = confusionmat(outputt,predict_label); %output_test是真实值标签
- figure;
- set(gcf,'unit','centimeters','position',[15 5 20 15])
- yanseplot(confMat.');
- xlabel('Predicted label')
- ylabel('Real label')
- set(gca,'fontsize',10)
- hold off
-
-
- %% 对训练集进行测试
-
-
- for i=1:1:size(inputn,2)
- for j=1:1:midnum
- I(j)=inputn(:,i)'*w1_1(j,:)'+b1_1(j);
- Iout(j)=1/(1+exp(-I(j)));
- end
- %输出层输出
- yn=w2_1'*Iout'+b2_1;
- an1(:,i) = yn;
- end
-
-
- predict_label2=zeros(1,size(an1,2));
- for i=1:size(an1,2)
- predict_label2(i)=find(an1(:,i)==max(an1(:,i)));
- end
- outputt2=zeros(1,size(output_train,2));
- for i=1:size(output_train,2)
- outputt2(i)=find(output_train(:,i)==max(output_train(:,i)));
- end
- fprintf('test is over and plot begining……\n');
- accuracy=sum(outputt2==predict_label2)/length(predict_label2); %计算预测的确率
- % 作图
- figure
- stem(1:length(predict_label2),predict_label2,'b^')
- hold on
- stem(1:length(predict_label2),outputt2,'r*')
- legend('预测类别','真实类别','NorthWest')
- title({'BP神经网络的预测效果',['训练集正确率 = ',num2str(accuracy*100),' %']})
- xlabel('预测样本编号')
- ylabel('分类结果')
- set(gca,'fontsize',12)
- %输出准确率
- disp('---------------------------训练集准确率-------------------------')
- disp(['训练集准确率:',num2str(accuracy*100),'%'])
- % 画方框图
- confMat = confusionmat(outputt2,predict_label2); %output_test是真实值标签
- figure;
- set(gcf,'unit','centimeters','position',[15 5 13 9])
- yanseplot(confMat.');
- xlabel('Predicted label')
- ylabel('Real label')
-
-
- hold off
- figure
- plot(E)
- title('误差曲线')
- ylabel('误差')
- xlabel('迭代次数')
运行之后,结果如下。
首先是训练集的测试结果图:
测试集的训练结果图:
训练误差图:
附上一个热力图:(热力图的效果和第一张图是一致的,在类别情况较多时,多采用热力图)
可以看到,手写的附加动量因子的BP神经网络matlab代码,可以实现对红酒数据的精准识别,测试集的识别率高达100%。
UCI常用数据集链接
https://pan.baidu.com/s/10gYszv5_BCfr43RMLOVXVQ?pwd=8888
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。