前言
吴恩达的机器学习网课里面,介绍了BP算法,但是并没有BP算法的推导过程。
很多人第一次接触神经网络,第一次接触BP算法的时候,都会被吓到,都会说,“哇,这个算法真复杂”。神经网络复杂的原因在于参数繁多:
自变量需要乘一个参数矩阵,再用一次sigmoid函数
再乘以一个参数矩阵,再用一次sigmoid函数
再乘以一个参数矩阵,再用一次sigmoid函数
……
经过多层套娃,才能得到最终的拟合值。以如此多的参数作为自变量,求解代价函数的最小值点,因此以梯度下降为基本思想的BP算法显得非常复杂。以下是我对BP神经网络的详细推导,以后哪天忘了,回来翻一翻这篇文章就够了。
示意图和主要符号
本文的主要符号基本与吴恩达机器学习课堂上的主要符号一致。
:神经网络层数,
:第层的神经元数量(不包括偏置元)
:第层神经网络的输入值,维向量
:第层神经网络的输出值,维向量
:到的线性变换,属于待估参数,阶矩阵
:输出神经元的数量,,
:估计值,,表示向量的第个元素
是样本,是维向量,是维向量,加上偏置元便得到
我们的目标
我们的目标是要求解使得代价函数最小的参数,即。代价函数是:
我们可以基于梯度下降的思想,来逼近最小值。设是任意一个参数,根据梯度下降的思想,通过不断更新参数值:,便可以逼近最小值。那么问题来了,怎么求得这个偏导数呢?
最后一层的delta值
在求偏导数之前,我们必须悉知,BP算法求偏导数中,对求偏导非常重要,它是对偏导的值。至于为什么这么重要,推导完就会知道了。现在我们必须寻找到一个合理的递推式,使得我们能够在程序中快速求出每一层的。
在求之前,我们先简化一下代价函数,假设只有一个样本,而且没有正则化项:
稍微运用一下大一学过的微积分求导法则,就能得到
此外,必须注意到,sigmoid函数的导数:
因此利用链式法则,我们可以求得第层的第个delta值:
也就是:。写成向量化的形式才是我们想要的最终结果:
到此为止,我们得到了最后一层的delta值。接下来我们要寻找一个递推公式,通过反向递推每一层的值。这边是反向传播算法中反向的意思。
delta值的递推公式
根据微积分的链式法则,直接计算:
上面是的第i个元素。写成向量化的形式是:
其中.*是点乘运算,代表向量或者矩阵中相应位置的元素相乘。必须维度相同的向量或者矩阵才能点乘。上式就是我们想要的delta值递推公式。
对参数的偏导数
好了,现在知道了,并且知道了,我们需要求偏导数::
大功告成了!现在得到了想要的结果:在一个样本的情况下,第层的参数矩阵的偏导数是:。
那么,如果把情况扩展到m个样本,该怎么处理呢?非常非常简单,每一个样本的偏导数加总,便得到m个样本的偏导数。在实际的BP算法中,每一次反向传播,都会循环m次,求m个偏导,再把他们加总。
那么,如果把情况扩展到有正则项的情况呢?非常非常简单,在原来已经加总的偏导数情况下,再加上正则化项相应的偏导数即可!
Loop{
初始化参数theta
偏导 = 0
for i from 1 to m, do{
通过xi和theta,求yi的拟合值
对于第i个样本,利用反向传播,求每一层的参数的偏导
偏导 = 偏导 + 第i个样本的偏导
}
偏导 = 偏导 + 正则化项的偏导
theta = theta - alpha * 偏导
}