一个BP的完整代码实现(供参考与收藏)

2023-10-21 10:40

本文主要是介绍一个BP的完整代码实现(供参考与收藏),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文来自 老饼玩转-BP神经网络http://bp.bbbdata.com/teach#100


目录

一、代码思路简介

二、主体代码

三、附加代码:表达式打印


本文展示一个完整的BP神经网络训练例子,包含归一化、训练与测试数据分割、BP网络训练、训练结果与测试结果展示,和最后提取模型的数学表达式共6个完整步骤(使用matlab2014b)。
作为一个完整的base Demo供参考和学习。


一、代码思路简介

本例从 \text{y} = 10*\sin(x_1)+0.2*x_2^2  中采取100个样本建立BP神经网络,然后与原函数进行比较。

步骤包括

(1)数据生成
(2)数据归一化
(3)训练测试数据分割
(4)网络训练
(5)展示训练结果
(6)泛化检验-测试数据的测试结果
(7)模型的使用
(8)提取模型的表达式
(9)模型表达式的反归一化
附加:模型表达式的打印。


运行结果如下

训练得到的模型表达式

13.8247*tansig(-0.94451*x1+0.33945*x2+2.1889)+18.6309*tansig(0.38004*x1+0.38706*x2+0.095989)-15.5021*tansig(0.7589*x1-0.06713*x2+2.0389)+1.6125

二、主体代码

clear all;close all ;
%------------------原始数据-----------------------------------
x1 = linspace(-3,3,100);     % 在[-3,3]之间线性生成100个数据
x2 = linspace(-2,1.5,100);   % 在[-2,1.5]之间线性生成100个数据
y = 10*sin(x1)+0.2*x2.*x2;   % 生成yinputData  = [x1;x2];        % 将x1,x2作为输入数据
outputData = y;              % 将y作为输出数据%--------------数据预处理:归一化-------------------------------
%由于有归一化,必须先将归一化信息抓取出来
iMax = max(inputData,[],2);
iMin = min(inputData,[],2);
oMax = max(outputData,[],2);
oMin = min(outputData,[],2);normInputData=2*(inputData -repmat(iMin,1,size(inputData,2)))./repmat(iMax-iMin,1,size(inputData,2)) -1;
normOutPutData=2*(outputData -repmat(oMin,1,size(outputData,2)))./repmat(oMax-oMin,1,size(outputData,2)) -1;%---------------数据预处理:预留检验数据----------------------------------
randIndex  = randperm(100);
trainIndex = sort(randIndex(1:80));                 % 随机选出80个数据作为训练数据(这里先选出数据的序号)
testIndex  = sort(randIndex(81:100));               % 将剩下的20个数据作为检验数据(这里先选出数据的序号)inputData_train  = normInputData(:,trainIndex);     % 根据序号选出80个用于训练的输入
inputData_test   = normInputData(:,testIndex);      % 根据序号选出20个用于检验的输入
outputData_train = normOutPutData(:,trainIndex);    % 根据序号选出80个用于训练的输出
outputData_test  = normOutPutData(:,testIndex);     % 根据序号选出20个用于检验的输出%----------------网络训练 -----------------------------------------------
%使用用输入输出数据(inputData_train、outputData_train)建立网络,隐节点个数设为3.其中输入层到隐层、隐层到输出层的节点分别为tansig和purelin,使用trainlm方法训练。
net = newff(inputData_train,outputData_train,3,{'tansig','purelin'},'trainlm');%设置一些常用参数
net.trainparam.goal = 0.00001;    % 训练目标:均方误差低于0.0001
net.trainparam.show = 400;        % 每训练400次展示一次结果
net.trainparam.epochs = 15000;    % 最大训练次数:15000.[net,tr] = train(net,inputData_train,outputData_train);  % 调用matlab神经网络工具箱自带的train函数训练网络%----------训练数据的拟合效果-----------------------------
figure;
%训练数据的拟合效果
simout_train = sim(net,inputData_train);
subplot(2,1,1);
title('训练数据的拟合效果')
hold on
t=1:length(simout_train);
plot(t,outputData_train,t,simout_train,'r')%画图,对比原来的y和网络预测的y%检验数据的拟合效果
simout_test = sim(net,inputData_test);
subplot(2,1,2);
title('未训练数据的拟合效果')
hold ont=1:length(simout_test);
plot(t,outputData_test,t,simout_test,'r')%画图,对比原来的y和网络预测的y%-----------------------真正使用时的流程--------------------
X= [-2.9;-1.9];                             % 要预测的X
normX=2*(X -iMin)./(iMax-iMin) -1;          % 对X归一化
normSimY = sim(net,normX);                  % 用网络预测
simy = (normSimY+1).*(oMax-oMin)./2 + oMin; % 对结果反归一%----------------------提取表达式(对应归一化数据)------------------------------------
%提取权重
w12 = net.iw{1,1};                          % 第1层(输入层)到第2层(隐层)的权值
b2 = net.b{1};                              % 第2层(隐层)的神经元阈值w23 = net.lw{2,1};                          % 第2层(输入层)到第3层(输出层)的权值
b3 = net.b{2};                              % 第3层(输出层)的神经元阈值%对应的数学表达式:
sim_y_norm = w23 *tansig( w12 *inputData + repmat(b2,1,size(inputData,2))) + repmat(b3,1,size(inputData,2));%----------------------提取表达式(对应原始数据)------------------------------------
%权重反归一化
W12 = w12 * 2 ./repmat(iMax' -iMin',size(w12,1),1);
B2  = -w12* (2*iMin ./(iMax - iMin) + 1) + b2;W23 = w23 .*repmat((oMax -oMin),1,size(w23,2))/2;
B3  = (oMax -oMin) .*b3 /2 + (oMax -oMin)/2 + oMin;%最终的数学表达式:
sim_y = W23 *tansig( W12 *inputData + repmat(B2,1,size(inputData,2))) + repmat(B3,1,size(inputData,2));%数学表达式与工具箱预测结果的比较
net_sim_y = sim(net,normInputData);
net_sim_y=(net_sim_y+1).*(oMax-oMin)./2 + oMin; % 对结果反归一
formula_err=max(max(abs(net_sim_y - sim_y)));

三、附加代码:表达式打印

加入以下一段,可以打印表达式(仅为参考DEMO,非通用函数)

[hn,xn] = size(W12);%隐节点个数,输入个数
f_str = '';
for i=1:hncur_tansig = [num2str(W23(i)),'*tansig('];if(i>1 && W23(i)>0)cur_tansig =['+',cur_tansig] ;endfor j = 1: xnsign_str = '';if(j>1 && W12(i,j)>0 )sign_str='+';endcur_tansig = [cur_tansig,sign_str,num2str(W12(i,j)),'*x',num2str(j)];endsign_str = '';if( B2(i)>0 )sign_str='+';endcur_tansig = [cur_tansig,sign_str,num2str(B2(i)),')'];f_str= [f_str,cur_tansig];
end
sign_str = '';
if( B3>0 )sign_str='+';
end
f_str=[f_str,sign_str,num2str(B3)]

运行结果:

13.8247*tansig(-0.94451*x1+0.33945*x2+2.1889)+18.6309*tansig(0.38004*x1+0.38706*x2+0.095989)-15.5021*tansig(0.7589*x1-0.06713*x2+2.0389)+1.6125

 相关文章

​《BP神经网络梯度推导》

​​​​​​《BP神经网络提取的数学表达式》

《一个BP的完整建模流程》

这篇关于一个BP的完整代码实现(供参考与收藏)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/253843

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter