楼主也是最近才刚刚接触神经网络的菜鸟,但是往往初学者才懂得初学者的痛点。在学习过程中,很多东西楼主也是不求甚解,以“会用”为主,相信在使用的过程中,很多不明白的东西,也会渐渐了解了。跌跌撞撞,花了一个星期的时间,楼主把目前用的非常多的 BP 神经网络用C++封装成了几个类,测试效果还可以,发出来分享下,可能有些地方说的不准确,但是可以给以后的自己做个备忘,也可以给其他刚接触神经网络的同学一点参考。
先贴个简单的调用案例,让大家有个比较直观的印象。
LCCBPNET net; // 结构体,神经网络的一些参数net.nIn = 2;net.nHidden = 3;net.nOut = 1;net.loopTimes = 2000;net.eta = 0.6;net.mc = 0.8;net.tolerance = 0.01;CLccBPNetWork lccBP(net); // 关键就是这两句了,这一句将 net 结构体传递给对象 lccBPlccBP.batchTrain(&trainMx, &eptMx); // 这一句是训练, trainMx 和 eptMx 是用来训练的矩阵,输入 trainMx,期望输出是 eptMxlccBP.wIH->printLccMatrix();lccBP.wHO->printLccMatrix(); // 这两句是打印出训练好的权值矩阵lccBP.testNet(&testMx, &epttestMx); // 训练好以后,就可以测试了,testMx是测试矩阵, epttestMx 是神经网络输出的结果
更多细节,楼主会慢慢说清楚。
人工神经网络是一种类似于人类神经系统的信息处理技术。事实上,神经网络包含很多种, BP 神经网络使用较多,它是一种以误差反向传播为基础的前向网络,具有非常强的非线性映射能力。神经网络的用处非常多,比较常见的用途有:识别,逼近,回归,压缩等。
通常,人类自身就是一个极好的模式识别系统,当视野中出现一张熟悉的人脸时,只需数百毫秒的时间即可正确识别。就连并不发达的昆虫神经系统,也表现出极强的识别能力。一般认为,生物神经并不是一开始就具备这样的识别能力的,而是在其成长过程中通过学习逐步获得的。随着生物的成长,大脑接收了大量的环境信息,神经元之间的相互联系不断变化,从而完成智能、思维、情绪等精神活动。下图是神经元的结构,A是轴突,D为树突,P为细胞体。不同的神经元的连接是靠突触实现的,信号从一个神经元的轴突到另一个神经元的轴突有向的传播。
在人工神经网络中,最重要的概念莫过于神经元节点与权值,节点对应细胞体,权值表示节点间相互连接的强度。
权值是可以调整的,当权值调整至恰当值时,就能输出正确的结果。网络将知识存储在调整后的各个权值中,这一点是神经网络的精髓。
下图的是 BP 神经网络的一种简单示意图,分为输入层、隐藏层和输出层,各层的连接可以通过权值调整。
能够看出,这种结构跟神经细胞连接很像,可以用这种结构来模拟生物的神经系统,实现一定的功能。
当神经网络的类型和层数确定以后,就可以输入样本进行训练了。网络可以根据环境变化不断学习,改变自身的权值。一般而言,训练指的是外界将样本输入到神经网络中,使其权值发生调整的过程,是外界的行为;而学习指的是神经网络进行自适应调整的行为,是网络自身的行为。纠结具体概念没有什么意义,学习和训练的本质都是调整网络的连接权值,我决定不对这两个词做区分,混用之。
所以我认为 BP 神经网络的使用主要只有两步:
第一步, 确定神经网络的结构,其实也就是确定网络的层数,以及各层的神经元个数。
第二步就是训练调整网络权值了。
最核心的是网络权值的调整方法。
神经网络的简要介绍就介绍到这里,接下来,我将偏实用轻理论地,用C++语言写一个BP神经网络实施例,应用于解决一个具体问题。