• 从0开始编写BP,附加动量因子的BP神经网络,不使用MATLAB工具箱,纯手写matlab代码,以BP分类为例...


    本篇文章以BP分类为例(也可以做预测),纯手写BP神经网络。附加动量因子的BP神经网络。

    编程时,激活函数选择Sigmoid函数,使用者也可以根据需要自行更改!

    以经典的红酒数据分类为例,红酒数据大小为178*14,最后一列为标签列。随机算取数据的百分之70作为训练集,百分之30作为测试集。

    废话不多说,接下来直接上代码!

    首先是主程序代码:

    1. close all
    2. warning off
    3. %% 数据读取
    4. clc
    5. clear
    6. load Wine
    7. %% 数据载入
    8. data=Wine;
    9. data=data(randperm(size(data,1)),:); %此行代码用于打乱原始样本,使训练集测试集随机被抽取,有助于更新预测结果。
    10. input=data(:,1:end-1);
    11. output1 =data(:,end);
    12. %把输出从1维变成3
    13. for i=1:size(data,1)
    14. switch output1(i)
    15. case 1
    16. output(i,:)=[1 0 0];
    17. case 2
    18. output(i,:)=[0 1 0];
    19. case 3
    20. output(i,:)=[0 0 1];
    21. end
    22. end
    23. %% 选取训练数据和测试数据
    24. m=fix(size(data,1)*0.7); %训练的样本数目
    25. input_train=input(1:m,:)';
    26. output_train=output(1:m,:)';
    27. input_test=input(m+1:end,:)';
    28. output_test=output(m+1:end,:)';
    29. %% 数据归一化
    30. [inputn,inputps]=mapminmax(input_train,0,1);
    31. % [outputn,outputps]=mapminmax(output_train);
    32. inputn_test=mapminmax('apply',input_test,inputps);
    33. %网络结构
    34. innum=size(input,2);
    35. midnum=20;
    36. outnum=size(output,2);
    37. %权值阈值初始化
    38. w1=rands(midnum,innum);
    39. b1=rands(midnum,1);
    40. w2=rands(midnum,outnum);
    41. b2=rands(outnum,1);
    42. w2_1=w2;w2_2=w2_1;
    43. w1_1=w1;w1_2=w1_1;
    44. b1_1=b1;b1_2=b1_1;
    45. b2_1=b2;b2_2=b2_1;
    46. xite = 0.0009;
    47. alfa=0.001; %附加动量因子
    48. I=zeros(1,midnum);
    49. Iout=zeros(1,midnum);
    50. FI=zeros(1,midnum);
    51. dw1=zeros(innum,midnum);
    52. db1=zeros(1,midnum);
    53. I=zeros(1,midnum);
    54. Iout=zeros(1,midnum);
    55. FI=zeros(1,midnum);
    56. dw1=zeros(innum,midnum);
    57. db1=zeros(1,midnum);
    58. loopNumber = 2000;
    59. fprintf('附加动量BP,training is begining……\n');
    60. tic
    61. for ii=1:loopNumber
    62. E(ii)=0; %训练误差
    63. for i=1:1:size(inputn,2)
    64. %选择本次训练数据
    65. x=inputn(:,i);
    66. % 隐含层输出
    67. for j=1:1:midnum
    68. I(j)=inputn(:,i)'*w1(j,:)'+b1(j);
    69. Iout(j)=1/(1+exp(-I(j)));
    70. end
    71. %输出层输出
    72. yn=w2'*Iout'+b2;
    73. %预测误差
    74. e=output_train(:,i)-yn;
    75. E(ii)=E(ii)+sum(abs(e));
    76. %计算w2.b2调整量
    77. dw2=e*Iout;
    78. db2=e';
    79. %计算w1 b1调整量
    80. for j=1:1:midnum
    81. S=1/(1+exp(-I(j)));
    82. FI(j)=S*(1-S);
    83. end
    84. for k=1:1:innum
    85. for j=1:1:midnum
    86. hh = 0;
    87. for ij = 1:size(e,1)
    88. hh = hh +e(ij)*w2(j,ij);
    89. end
    90. dw1(k,j)=FI(j)*x(k)*hh;
    91. db1(j)=FI(j)*hh;
    92. end
    93. end
    94. %权值阈值更新
    95. w1=w1_1+xite*dw1'+alfa*(w1_1-w1_2);
    96. b1=b1_1+xite*db1'+alfa*(b1_1-b1_2);
    97. w2=w2_1+xite*dw2'+alfa*(w2_1-w2_2);
    98. b2=b2_1+xite*db2'+alfa*(b2_1-b2_2);
    99. w1_2=w1_1;w1_1=w1;
    100. w2_2=w2_1;w2_1=w2;
    101. b1_2=b1_1;b1_1=b1;
    102. b2_2=b2_1;b2_1=b2;
    103. end
    104. w1_1=w1;
    105. w2_1=w2;
    106. b1_1=b1;
    107. b2_1=b2;
    108. E(ii) = E(ii)/size(inputn,2);
    109. if mod(ii,500)==0
    110. disp(['训练过程:',num2str(ii), '/', num2str(loopNumber),'误差为:',num2str(E(ii))])
    111. end
    112. end
    113. disp( ['训练时间: ',num2str(toc) ] );
    114. %% 将优化的权值阈值带入,用测试集求解
    115. for i=1:1:size(inputn_test,2)
    116. for j=1:1:midnum
    117. I(j)=inputn_test(:,i)'*w1(j,:)'+b1(j);
    118. Iout(j)=1/(1+exp(-I(j)));
    119. end
    120. %输出层输出
    121. yn=w2'*Iout'+b2;
    122. an0(:,i) = yn;
    123. end
    124. predict_label=zeros(1,size(an0,2));
    125. for i=1:size(an0,2)
    126. predict_label(i)=find(an0(:,i)==max(an0(:,i)));
    127. end
    128. outputt=zeros(1,size(output_test,2));
    129. for i=1:size(output_test,2)
    130. outputt(i)=find(output_test(:,i)==max(output_test(:,i)));
    131. end
    132. fprintf('test is over and plot begining……\n');
    133. accuracy=sum(outputt==predict_label)/length(predict_label); %计算预测的确率
    134. disp(['准确率:',num2str(accuracy*100),'%'])
    1. % 作图
    2. figure
    3. stem(1:length(predict_label),predict_label,'b^')
    4. hold on
    5. stem(1:length(predict_label),outputt,'r*')
    6. legend('预测类别','真实类别','NorthWest')
    7. title({'BP神经网络的预测效果',['测试集正确率 = ',num2str(accuracy*100),' %']})
    8. xlabel('预测样本编号')
    9. ylabel('分类结果')
    10. set(gca,'fontsize',10)
    11. %输出准确率
    12. disp('---------------------------测试准确率-------------------------')
    13. disp(['准确率:',num2str(accuracy*100),'%'])
    14. % 画方框图
    15. confMat = confusionmat(outputt,predict_label); %output_test是真实值标签
    16. figure;
    17. set(gcf,'unit','centimeters','position',[15 5 20 15])
    18. yanseplot(confMat.');
    19. xlabel('Predicted label')
    20. ylabel('Real label')
    21. set(gca,'fontsize',10)
    22. hold off
    23. %% 对训练集进行测试
    24. for i=1:1:size(inputn,2)
    25. for j=1:1:midnum
    26. I(j)=inputn(:,i)'*w1_1(j,:)'+b1_1(j);
    27. Iout(j)=1/(1+exp(-I(j)));
    28. end
    29. %输出层输出
    30. yn=w2_1'*Iout'+b2_1;
    31. an1(:,i) = yn;
    32. end
    33. predict_label2=zeros(1,size(an1,2));
    34. for i=1:size(an1,2)
    35. predict_label2(i)=find(an1(:,i)==max(an1(:,i)));
    36. end
    37. outputt2=zeros(1,size(output_train,2));
    38. for i=1:size(output_train,2)
    39. outputt2(i)=find(output_train(:,i)==max(output_train(:,i)));
    40. end
    41. fprintf('test is over and plot begining……\n');
    42. accuracy=sum(outputt2==predict_label2)/length(predict_label2); %计算预测的确率
    43. % 作图
    44. figure
    45. stem(1:length(predict_label2),predict_label2,'b^')
    46. hold on
    47. stem(1:length(predict_label2),outputt2,'r*')
    48. legend('预测类别','真实类别','NorthWest')
    49. title({'BP神经网络的预测效果',['训练集正确率 = ',num2str(accuracy*100),' %']})
    50. xlabel('预测样本编号')
    51. ylabel('分类结果')
    52. set(gca,'fontsize',12)
    53. %输出准确率
    54. disp('---------------------------训练集准确率-------------------------')
    55. disp(['训练集准确率:',num2str(accuracy*100),'%'])
    56. % 画方框图
    57. confMat = confusionmat(outputt2,predict_label2); %output_test是真实值标签
    58. figure;
    59. set(gcf,'unit','centimeters','position',[15 5 13 9])
    60. yanseplot(confMat.');
    61. xlabel('Predicted label')
    62. ylabel('Real label')
    63. hold off
    64. figure
    65. plot(E)
    66. title('误差曲线')
    67. ylabel('误差')
    68. xlabel('迭代次数')

    运行之后,结果如下。

    首先是训练集的测试结果图:

    c4a12a3d867a5b2aafde1b732ba27336.png

    测试集的训练结果图:

    a96f57e80b8a802ccff5edacfae6389e.png

    训练误差图:

    61890628f94ba6a774cb7414ea1d0141.png

    附上一个热力图:(热力图的效果和第一张图是一致的,在类别情况较多时,多采用热力图)

    6f1ca65913c72e85141267cb80808a4d.png

    可以看到,手写的附加动量因子的BP神经网络matlab代码,可以实现对红酒数据的精准识别,测试集的识别率高达100%。

    UCI常用数据集链接

    https://pan.baidu.com/s/10gYszv5_BCfr43RMLOVXVQ?pwd=8888

  • 相关阅读:
    (八) ES6 新特性 —— promise
    使用字典映射关系格式化输出字符串format_map()方法
    Vue3中使用tinymce全功能演示,包括开源功能
    JavaScript高级语法——严格模式
    一文了解 Go 方法
    4.3 IAT Hook 挂钩技术
    孩子学习编程对学习有帮助吗?
    自己动手写数据库:关系代数和查询树执行效率的推导
    CSS3技巧37:JS+CSS3 制作旋转图片墙
    软件设计模式白话文系列(八)桥接模式
  • 原文地址:https://blog.csdn.net/woaipythonmeme/article/details/133875125