从0开始编写BP,自适应学习率的BP神经网络,不使用MATLAB工具箱,纯手写matlab代码,以BP分类为例...

与上篇文章不同,仔细读了上篇文章的小伙伴应该知道,BP神经网络是有一个学习率的,而这个学习率很大程度上决定着神经网络的效果。这里采用自适应学习率,实现纯手写BP神经网络。

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

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

红酒数据的获取可以参考常用UCI数据集,链接放在文末,其中的Wine.mat即为红酒数据。

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

首先是主程序代码:

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 1output(i,:)=[1 0 0];case 2output(i,:)=[0 1 0];case 3output(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=rand(midnum,innum);
b1=rand(midnum,1);
w2=rand(midnum,outnum);
b2=rand(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.0002;
xite2 =  0.001;I=zeros(1,midnum);
Iout=zeros(1,midnum);
FI=zeros(1,midnum);
dw1=zeros(innum,midnum);
db1=zeros(1,midnum);
loopNumber = 2000;
fprintf('自适应学习率,training is begining……\n');
tic
for ii=1:loopNumberSSE(ii)=0; %训练误差for i=1:1:size(inputn,2)%选择本次训练数据x=inputn(:,i);
%      隐含层输出for j=1:1:midnumI(j)=inputn(:,i)'*w1(j,:)'+b1(j);Iout(j)=1/(1+exp(-I(j)));end%输出层输出yn=w2'*Iout'+b2;%预测误差e=output_train(:,i)-yn;SSE(ii)=SSE(ii)+1/2*sum(e.^2);%计算w2.b2调整量dw2=e*Iout;db2=e';%计算w1 b1调整量for j=1:1:midnumS=1/(1+exp(-I(j)));FI(j)=S*(1-S);endfor k=1:1:innumfor j=1:1:midnumhh = 0;for ij = 1:size(e,1)hh = hh +e(ij)*w2(j,ij);enddw1(k,j)=FI(j)*x(k)*hh;db1(j)=FI(j)*hh;endend%权值阈值更新ff(ii) = xite2-ii*(xite2-xite)/loopNumber; %自适应学习率核心公式w1=w1_1+ff(ii)*dw1';b1=b1_1+ff(ii)*db1';w2=w2_1+ff(ii)*dw2';b2=b2_1+ff(ii)*db2';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;  endSSE(ii) = SSE(ii)/size(inputn,2);if mod(ii,500)== 0disp(['训练过程:',num2str(ii), '/', num2str(loopNumber),'误差为:',num2str(SSE(ii))])end
end
disp( ['训练时间: ',num2str(toc) ] );%% 将优化的权值阈值带入,用测试集求解
for i=1:1:size(inputn_test,2)for j=1:1:midnumI(j)=inputn_test(:,i)'*w1(j,:)'+b1(j);Iout(j)=1/(1+exp(-I(j)));end%输出层输出yn=w2'*Iout'+b2;an0(:,i) = yn;
endpredict_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:midnumI(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;
endpredict_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 offfigure
plot(SSE)
title('误差曲线')
ylabel('误差')
xlabel('迭代次数')figure
plot(ff)
title('自适应学习率变化曲线')
ylabel('学习速度')
xlabel('迭代次数')

下面直接上结果图。

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

b09520da17a8763cc1f5c64abb419b6e.png

测试集的训练结果图:

8b330984365ccfaeecaa48eb8cef24b9.png

同样,再附一张训练集的热力图。(热力图的效果和第一张图是一致的,在类别情况较多时,多采用热力图)

dc5c6ad0b396d4ffff4a11120d0408fc.png

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

由于BP神经网络的偶然性,建议大家多运行几次,除此之外,隐含层节点个数,自适应学习率的上下限值,都是可以自行调整的。大家根据自己的项目随意调整即可。

UCI常用数据集链接

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/108908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MFC-列表控件

目录 1、更改列表控件的属性: 2、代码设置表头: 3、设置正文内容: 4、设置属性,显示成表格形式 : 5、代码实现: 1、更改列表控件的属性: VIEW设置为Report模式会出现表格形状 2、代码设置…

二维码智慧门牌管理系统:高效标准化处理地址数据

文章目录 前言一、标准化数据的重要性二、标准检查与自动化处理三、人工修复与高效性四、数据应用与效益 前言 随着科技的快速发展,数据管理在现代社会中扮演着越来越重要的角色。为了提升数据质量,标准化检查成为必不可少的环节。今天,我们…

软考系统架构设计师考试冲刺攻略

系统架构冲刺攻略 上篇为综合知识,介绍了系统架构设计师应熟练掌握的基本知识,主要包括绪论、计算机系统、信息系统、信息安全技术、软件工程、数据库设计、系统架构设计、系统质量属性与架构评估、软件可靠性、软件架构的演化和维护、未来信息综合技术等…

【面试经典150 | 区间】插入区间

文章目录 Tag题目解读题目来源解题思路方法一:合并区间方法二:模拟 其他语言python3 写在最后 Tag 【模拟】【数组】 题目解读 给定一个含有多个无重叠区间的数组,并且数组已经按照区间开始值升序排序。在列表中插入一个新的区间&#xff0…

小程序原生代码转uniapp

写了一份小程序原生代码,想转为uniapp 再转为其他平台发布 1、在命令行里,运行【 npm install miniprogram-to-uniapp -g 】进行安装,因为这个包是工具,要求全局都能使用&#x…

JS加密/解密之webpack打包代码逆向

Webpack 是一个强大的打包工具,能够将多个文件打包成一个或多个最终的文件。然而,将已经经过打包的代码还原回原始源代码并不是一件直接的事情,因为 webpack 打包的过程通常会对代码进行压缩、混淆和优化,丢失了部分变量名和代码结…

【C++11新特性】右值引用和移动语义(移动构造,移动赋值)

文章目录 前言一、列表初始化(不同于初始化列表)二、initializer_list三、decltype关键字四、nullptr五、右值引用移动拷贝和移动赋值被编译器识别成将亡值的原因 左值引用和右值引用的场景和价值右值引用的场景move函数 六、关于右值引用的功能和属性问…

pinctrl子系统 - 架构和结构体关系(四)

一,pinctrl的引入 由于SoC系统越来越复杂、集成度越来越高,SoC中pin的数量也越来越多、功能也越来越复杂,这就对如何管理、使用这些pins提出了挑战。因此,用于管理这些pins的硬件模块(pin controller)就出…

c# xml 参数配置表的使用

使用简介 实际使用界面 配置表管理界面 进入 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;…

用GDB调试程序的栈帧

2023年10月17日&#xff0c;周二晚上 目录 练习GDB栈帧调试功能的程序 GDB栈帧方面的指令 调试效果 练习GDB栈帧调试功能的程序 斐波那契数列 #include <iostream>int factorial(int n) {if (n < 1) {return 1;} else {return n * factorial(n - 1);} }int main(…

Redis数据结构之listpack

前言 当数据量较小时&#xff0c;Redis 会优先考虑用 ziplist 来存储 hash、list、zset&#xff0c;这么做可以有效的节省内存空间&#xff0c;因为 ziplist 是一块连续的内存空间&#xff0c;它采用一种紧凑的方式来存储元素。但是它也有缺点&#xff0c;比如查找的时间复杂度…

nginx基础概念

1.正向代理&#xff1a;代理的是客户端&#xff0c;一般有明确的访问对象 比如&#xff1a;我现在通过v-p-n去访问YouTube&#xff0c;那么就是正向代理。 2.反向代理&#xff1a;代理的是服务器 最常见的就是web中&#xff0c;nginx去代理一群后端的服务器。 3.负载均衡&…

Flume 整合 Kafka

1.背景 先说一下,为什么要使用 Flume + Kafka? 以实时流处理项目为例,由于采集的数据量可能存在峰值和峰谷,假设是一个电商项目,那么峰值通常出现在秒杀时,这时如果直接将 Flume 聚合后的数据输入到 Storm 等分布式计算框架中,可能就会超过集群的处理能力,这时采用 Kaf…

制造企业如何做好MES管理系统需求分析

随着制造业的不断发展&#xff0c;制造企业对于生产过程的管理需求日益增长。为了提高生产效率和质量&#xff0c;越来越多的制造企业开始关注MES生产管理系统的需求分析。本文将从以下几个方面探讨制造企业如何做好MES管理系统需求分析。 一、明确需求 在进行MES管理系统需求…

Vue 网络处理 - axios 异步请求的使用,请求响应拦截器

目录 一、axiox 1.1、axios 简介 1.2、axios 基本使用 1.2.1、下载核心 js 文件. 1.2.2、发送 GET 异步请求 1.2.3、发送 POST 异步请求 1.2.4、发送 GET、POST 请求最佳实践 1.3、请求响应拦截器 1.3.1、拦截器解释 1.3.2、请求拦截器的使用 1.3.3、响应拦截器的使用…

基于SSM框架的安全教育平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

微信小程序仿苹果负一屏由弱到强的高斯模糊

进入下面小程序可以体验效果&#xff0c;然后进入更多。查看模糊效果 一、创建小程序组件 二、代码 wxml: <view class"topBar-15"></view> <view class"topBar-14"></view> <view class"topBar-13"></view&…

Kotlin中布尔类型、字符类型、字符串类型和数组类型

在Kotlin中&#xff0c;布尔类型、字符类型、字符串类型和数组类型是常用的数据类型之一。下面我将对它们进行详细描述并提供示例代码。 布尔类型&#xff08;Boolean&#xff09;&#xff1a; 布尔类型表示逻辑值&#xff0c;只有两个可能的取值&#xff1a;true和false。在K…

node多版本管理器nvm

node多版本管理器nvm 1、为何要使用node版本管理器2、nvm安装步骤2-1、卸载系统中的node2-2、下载nvm2-3、安装 3、维护node版本3-1、安装指定版本node3-2、查看本机已安装的所有node版本3-3、切换本机node版本 1、为何要使用node版本管理器 在日常开发中&#xff0c;难免会遇…