python实现反向传播的神经网络算法

时间:2024-03-31 11:26:42

吴恩达机器学习在讲神经网络的时候讲的不是很清楚,而且视频中的公式有很多错误,结合课后的材料和参考别人的实现之后才终于理清了反向传播算法的脉络,下面简单的说一下反向传播算法的原理和相关公式。

第一步:前向传播

最简单的神经网络结构就是如下的三层结构,i为输入层,h为隐藏层,o为输出层。每一层包含两个神经元,其中输入层和隐藏层额外包括一个偏置单元b,偏置单元恒等于1,类似于一个常数项。
python实现反向传播的神经网络算法
其中,每个神经元的结构如下,每个神经元主要包含两个元素,一个是输入值input(图上的net),一个是输出值output(图上的out),output是通过input带入**函数算出来的,神经网络常见的**函数是sigmoid函数,即output=sigmoid(input),通过sigmoid可以把output的值限定在(0,1)之间,以便于分类。
python实现反向传播的神经网络算法
通过上一层神经元的output值以及相应的权重weight,可以算出下一层神经元的input值。假设l-1层有m个神经元,l层有n个神经元,那么l层的input向量可由下面的公式算得,其中l-1层因为有一个偏置单元,因此实际参与计算的神经元是m+1个。
python实现反向传播的神经网络算法
其中
(1) python实现反向传播的神经网络算法
代表l层的第i个神经元到l+1层第j个神经元的权重,值得一提的是,因为l层的偏置单元和l+1层的偏置单元之间并没有权重,因此i=0的时候代表l层的偏置单元,但是j=0的时候代表的是l+1层的第一个神经元而非偏置单元
(2)python实现反向传播的神经网络算法
output为一个行向量,output(0,i)代表l层第i个神经元的输出值,i=0时为偏置单元,也就是output(0,0)=1。
(3)python实现反向传播的神经网络算法
input为一个行向量,input(0,j)代表l层第j个神经元的输入值,j=0时为第一个神经元而不是偏置单元

得到input值之后,再根据sigmoid函数计算output值,之后,还需要向output向量的头部添加一个值为1的偏置单元才可以用于下一层的计算。
python实现反向传播的神经网络算法
输入层的output向量就是训练样本的输入值加上偏置单元1组成,通过上述公式一层一层的往后递推,最后便可以算出输出层的output值,由sigmoid函数的特性可知,输出层的output值是介于(0,1)之间的,这边是01分类的最后结果。

第二步:反向传播

前向传播的时候,我们通过输入层的值最后推出了输出层神经元的值,反向传播算的不是神经元的值,而是神经元的误差。很容易算出输出层的误差,再通过类似的算法将输出层的误差反向传递到第一层隐藏层(输入层没有误差),再根据误差调节权重。本文只放公式,不再推导公式,文末再贴上公式推导的博客。

  • cost function
    python实现反向传播的神经网络算法
    其中,k是训练样本数量,o是输出向量的维度,sl是l层神经元的数量,target是训练样本中已标注好的分类结果,值得注意的是,这里的正则项并没有包含偏置单元的权重。
  • 输出层神经元误差
    python实现反向传播的神经网络算法
    其中,点乘代表向量对应位置相乘,而不是矩阵乘法
  • 隐藏层神经元误差
    python实现反向传播的神经网络算法
    这里的误差其实是指神经元input的偏导值,其中,隐藏层l的偏置单元的误差项也被算了出来,但偏置单元的误差并不会参与反向传播的计算,因此,如果在实现算法的时候用的是矩阵的计算法则,还需要将偏置单元的误差从误差向量中删掉,让其变成一个1*m的行向量,不然和权重矩阵的维度对不上。

  • 权重的误差
    python实现反向传播的神经网络算法
    反向传播的目的实际上就是为了算出权重的偏导值,之前已经算出了神经元的偏导,权重的偏导实际就等于权重箭头尾部神经元的output值乘上权重箭头头部神经元的偏导值。当然,这只是一个样本的偏导值,吴恩达公开课中采用的是批量梯度下降,因此还需要将所有样本的偏导累加取平均值,累加项如下所示。
    python实现反向传播的神经网络算法
    但上面的还不是最终调整的值,因为cost function里面还含有为了防止过拟合的正则项,不过正则项的偏导很容易算,因此最终调整的delta值用D表示,如下
    python实现反向传播的神经网络算法
    python实现反向传播的神经网络算法
    其中,k是训练样本的数量,这里之所以会判断i=0的真假,是因为cost function里面正则项是没有包含偏置单元的权重的,因此偏置单元权重的偏导是不包含对正则项求导的项的。
    最后只要按照如下公式调整权重即可
    python实现反向传播的神经网络算法
    其中,alpha是学习速率。通过多次迭代梯度下降,当满足某个条件时停止迭代,即是最终模型,相关python实现代码我已经放在我的github上。
    python代码实现
    吴恩达机器学习神经网络代码
    参考博客:
    反向传播公式推导及举例
    吴恩达机器学习随堂材料