Write BP from scratch, do not use MATLAB toolbox, purely hand-write matlab code, take BP classification as an example

This article takes BP classification as an example (it can also be used for prediction), purely handwritten BP neural network. The BP neural network with additional momentum factor and adaptive learning rate will be released in a follow-up article.

When programming, choose the Sigmoid function as the activation function, or take the classic red wine data as an example, without further ado, let’s go directly to the code!

a760e9ed9ac1433a919ef8f3aedaee04.png


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);
xite =  0.001;
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)+1/2*sum(abs(e).^2);
    %计算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+xite*dw1';
    b1=b1+xite*db1';
    w2=w2+xite*dw2';
    b2=b2+xite*db2';
   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*')
yticks(1:1:8)
% yticklabels({'正常状态','冷却水流量不足','冷冻水流量不足','制冷剂泄漏','制冷剂过量','滑油过量','冷凝器结垢','制冷剂中混入不凝性气体0'})
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('迭代次数')

 The result display:

5ad8bd7b76cc46b48d4dceb56296e724.png

 69c97605cfed42e0a4bc89fd0fb0231d.png

a3c1c477499c4e2db8a538b973474ad8.png

53a00b4d21724c41ab2df82ac0e11548.png

 e6a26749c72d42c6812d8f8d2c8da80c.png

Follow-up will continue to release the BP neural network MATLAB code with additional momentum factor and adaptive learning rate.

Guess you like

Origin blog.csdn.net/woaipythonmeme/article/details/131047905