Python实现BP神经网络算法

2017年8月11日22:01:37 5 16,523

Python实现BP神经网络算法

前言

在上一篇文章中我们介绍了BP神经网络算法的理论知识,这篇文章我们就来用Python实现BP神经网络算法,在看这篇文章之前,建议先看一下前面的《Python机器学习神经网络算法理论(BP)》文章,里面有详细的前馈神经网络算法的理论实现,可以帮助这篇文章的代码理解,因为这篇文章中的代码流程就是根据上篇理论知识来编写的,所使用的公式也是上篇文章中介绍的公式。

这篇文章只是简单的使用Python实现BP神经网络算法,并没有进行代码的优化,代码写的也是一般,但大体的流程还是有些参考价值的。

在写这篇文章的代码的时候参考了很多网上的代码程序,说实话,网上的代码很多都如出一折,很多(简单的)都是同版本copy过来的,能拿来学习的真的寥寥无几。

废话不多说,下面我们就开始看代码吧。

Python实现BP神经网络算法

定义Sigmoid函数

上篇文章中说过了激活函数使用的是Sigmoid函数,我们编程是常用的两种是tanh函数和logistic函数,这两个函数的图像都跟上一篇文章中的图像很相似,都处在(0,1)之间,下面分别看一下这两个函数图像:

Python实现BP神经网络算法

tanh图像

Python实现BP神经网络算法

logistic图像

除了他们本身之外,我们在神经网络往回反馈的时候计算误差率需要用到他们的导函数,其导函数如下

Python实现BP神经网络算法

lPython实现BP神经网络算法

在Python的numpy库中已经为我们写好了tanh函数,我们只要根据公式去实现以下它的导函数就可以了,logistic函数比较简单,我们可以直接使用代码实现。

下面是用代码来定义这两个函数和他们的导函数:

BP神经网络算法

上面的激活函数只是我们定义的几个函数,是下面我们在构建算法的时候要用到的。下面直接看代码,重要的解释都在代码注释中了。

代码各模块的解释都在注释中了,就不多说了,下面说一下算法的实现流程。

1、首先的我们是定义了一个NeuralNetwork类,并且在其构造函数中传入了几个构建模型需要用到的参数。分别定义了权重(weights)和偏向(biases),在定义的时候我们使用了正太分布的随机函数生成的随机数在(-1,1)之间,到此为止我们就定义好了网络的结构,具体结构可以在测试中print一下看看。

2、下一步便是重要的一般,我们要在fit中传入训练集进行训练,构建数学模型,所使用的算法便是BackPropagation(BP)算法。该算法分为两个过程,一个是正向的前进过程,一个是反向的反馈更新过程,每一次的迭代过程都使用训练集中的一个实例。

3、向前传输,计算每层神经单元的输出,并保存。

4、根据最后一层也就是输出层的输出和真实值比较得到误差,并使用计算公式得到输出层的误差率。

5、根据输出层的误差率我们可以依次向前根据公式推导出每一次的误差率。

6、根据每一次层的误差率,我们可以使用权重的更新公式和偏向的更新公式更新权重和偏向。

7、BP算法到此结束,我们要做的就是将大量的训练集进行迭代的训练,每次迭代都要使用全部的训练集,知道满足我们的迭代次数为止。

8、实现预测函数(predict)。

上面的算法流程可以参考开头提到的前一篇理论文章。

简单的预测

算法实现完了,我们下面就进行一次简单的训练和预测,就是用最简单的异或。

输出如下:

Python实现BP神经网络算法

本次预测我们训练的次数是1000次,构造的神经网络结构模式一个2、4、3、1的网络结构。从预测的结果中我们可以看出来,其预测结果已经非常的精确了,实践发现,通过调整隐藏层的结构和增加训练的次数都可以提升预测的准确率,但我们我要在准确率和预测时间之间取一个最优解,既要准确率也要训练和预测效率。

结束语

本篇文章算法中有大量的print输出测试注释,可供学习者在研究代码流程时使用,另外提醒一下,Python版本是2.7哟!

Python实现BP神经网络算法

PS:本篇文章主要是算法的实现,在下一篇文章中我们将使用该神经网络算法进行手写数字的识别实战

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

目前评论:5   其中:访客  3   博主  2

    • MSC 0

      我选A

      • 李明 1

        你好 ,你的初始layers数组输入定义和你最后使用代入并不一致啊

          • 马瑞强 Admin

            @李明 哪里不一致? Input层2神经元,4×3的Hidden, 1 Output = 2:4:3:1, 训练集是 [[0, 0], [0, 1], [1, 0],[1, 1]] ,4批,每批2输入。

          • 李明 1

            您能具体说明4*3hidden是分别代表隐藏层数还是神经元个数吗 在定义里是这样的:param layers: list类型,比如[2,2.1]代表输入层有两个神经元,隐藏层有两个,输出层有一个

              • 马瑞强 Admin

                @李明 都是表示神经元个数,第二层4神经元,第三层3神经元,理论文章:https://www.k2zone.cn/?p=992