bp神经网络
BP神经网络C语言实现
山人
bp神经网络应用广泛,大概是今年的五月份左右,我需要做一个多元函数的拟合,所以写了这个BP神经网络。为什么要使用C语言来写呢?因为我的程序需要在单片机上跑,所以不得不使用C语言。
这一篇博客不会讲解BP神经网络的基本原理,反向传播公式,因为关于这些的资料网上已经很多了(虽然大多数都有着不小的BUG,但足以入门学习)。我会着重讲解我写的BP神经网络的每个函数的具体作用,以及该如何使用,争取让有需要的人能通过这篇博客学会使用我写的BP神经网络。
C语言工程链接:https://download.csdn.net/download/qq_39545674/10884423
如果想知道BP神经网络的理论推导,可以参考下面的链接,这篇博客写的很好:
BP神经网络原理推导:https://blog.csdn.net/qq_39545674/article/details/86375170
如果你想在单片机或者arm之类的硬件上(当然,电脑也可以)部署bp神经网络,做一些函数拟合或者预测之类的,我的工程可以直接帮你解决。
1 BP神经网络具体函数
1.1 main.c
这是BP神经网络训练的主函数,在这里设置网络的主要参数。
·训练的样本x、y,(x表示输入,一行表示一个输入变量,y表示输出,一行表示一个输出变量,x、y的行列数ROW_X、COL_X、ROW_Y、COL_Y定义在BPNetwork.h里面,需要根据你的训练样本自己修改)
·隐含层的层数LAYER(这是一个宏,在BPNetwork.h里面定义的)
·激励函数选择:mode为1表示选择正切双曲余弦函数作为激励函数,为0表示选择sig函数作为激励函数,一般选则前者,性能更好。
·nodes是隐含层神经元个数设置数组,第一个元素表示第一层隐含层神经元个数,依此类推。
1.2 BPNetwork.c BPNetwork.h
这是BP神经网络的主体部分,包括网络的正向过程和反向传播过程。由于这部分不会涉及到参数的设置,所以就不列举变量以及函数了,主要介绍算法过程。
1.2.1 数据预处理
首先第一步是将训练样本进行归一化的操作,这样可以增加收敛速度。执行这个功能的是minmax函数。
1.2.2 建立网络节点
第二步是建立网络节点。执行这个功能的是netSetup。
1.2.3 初始化参数
执行函数是netInit。
1.2.4 设置求解的迭代次数
Maxepoch表示训练的代数,可以自己根据需求设置。
1.2.5 开始求解
接着就是开始求解了,这是使用了传统的BP优化方法,加入了动量项以及学习速率的自适应。具体函数是netSolve。
1.2.6 恢复到原始空间
由于之前将数据归一化了,所以现在需要还原到原始空间。执行函数是recoverOutput。
1.2.6 保存结果
在求解结束后,将得到的参数以及隐含层信息保存到一个txt文件里面(便于在单片机上建立函数),执行函数是OutPut。
1.2.7 释放内存
由于在训练的时候使用了动态内存,所以必须释放,否则内存泄漏,执行函数是freeNet。
1.3 BPSim.c BPSim.h
网络训练好之后,就是该如何应用的问题了。只需要把BPSim.c 和BPSim.h拷贝到单片机工程里面,把上一步保存的txt文件里面的参数拷贝给data即可。
初始化步骤如下:
- 拷贝参数给data。注意,txt里面的参数是列向量,需要转成行向量再拷贝。
- 执行siMinit函数。注意,如果和我一样需要在单片机或其他嵌入式平台上使用,需要稍稍修改一下这个函数,去掉readData函数
- 执行sim函数。这个就是仿真函数了。
1.4 其他
rand.c rand.h 是我写的一个随机数生成函数,用于参数初始化,也可以使用自带的。
我所使用的环境是Win10,vs2017,(vs2013也跑过)
如果有什么问题,欢迎评论
或者联系我,qq:1826249828
相关阅读
有两种方法 方法一 方法二
window.location.href的用法(动态输出跳转)
javascript中的location.href有很多种用法,主要如下。self.location.href="/url" 当前页面打开URL页面location.href="/url" 当前
在Android源码的中,很多UI布局采用了Preference的布局方式。Preference的布局与view的布局基本相似,其布局文件位于res/xml中。在Pr
一、Scrum的初识软件市场发展越来越迅速和成熟,传统瀑布式开发模式存在一定的限制,敏捷从而有了更广阔的的平台与机遇。Scrum作为在
Linux字符设备驱动之register_chrdev_region()系列
Linux字符设备驱动之 register_chrdev_region()函数系列1.内核中所有已分配的字符设备编号都记录在一个名为 chrdevs 散列表里。