反向传播算法推导-卷积神经网络

SIGAI-AI学习交流群的目标是为学习者提供一个AI技术交流与分享的平台。

导言

SIGAI之前的公众号文章“反向传播算法推导-全连接神经网络”中,我们推导了全连接神经网络的反向传播算法。其核心是定义误差项,以及确定误差项的递推公式,再根据误差项得到对权重矩阵、偏置向量的梯度。最后用梯度下降法更新。卷积神经网络由于引入了卷积层和池化层,因此情况有所不同。在今天这篇文章中,我们将详细为大家推导卷积神经网络的反向传播算法。对于卷积层,我们将按两条路线进行推导,分别是标准的卷积运算实现,以及将卷积转化成矩阵乘法的实现。在文章的最后一节,我们将介绍具体的工程实现,即卷积神经网络的卷积层,池化层,激活函数层,损失层怎样完成反向传播功能。

回顾

首先回顾一下全连接神经网络反向传播算法的误差项递推计算公式。根据第l层的误差项计算第l-1层的误差项的递推公式为:

其中W为权重矩阵,u为临时变量,f为激活函数。根据误差项计算权重梯度的公式为:

其中x为本层的输入向量。这几组公式具有普遍意义,对于卷积神经网络的全连接层依然适用。如果你对这些公式的推导还不清楚,请先去阅读我们之前的文章“反向传播算法推导-全连接神经网络”。

卷积层

首先推导卷积层的反向传播计算公式。正向传播时,卷积层实现的映射为:

卷积输出图像的任意一个元素都与卷积核矩阵的任意一个元素都有关,因为输出图像的每一个像素值都共用了一个卷积核模板。反向传播时需要计算损失函数对卷积核以及偏置项的偏导数,和全连接网络不同的是,卷积核要作用于同一个图像的多个不同位置。

上面的描述有些抽象,下面我们用一个具体的例子来说明。假设卷积核矩阵为:

输入图像是:

卷积之后产生的输出图像是U,注意这里只进行了卷积、加偏置项操作,没有使用激活函数:

正向传播时的卷积操作为:

反向传播时需要计算损失函数对卷积核以及偏置项的偏导数,和全连接网络不同的是,卷积核要反复作用于同一个图像的多个不同位置。根据链式法则,损失函数对第l层的卷积核的偏导数为:

在这里i j是卷积输出图像的行和列下标,这是因为输出图像的每一个元素都与卷积核的元素kpq相关。首先我们看上式最右边求和项的第二个乘积项:

这是激活函数对输入值的导数,激活函数作用于每一个元素,产生同尺寸的输出图像,和全连接网络相同。第三个乘积项为:

假设

已经求出,我们根据它就可以算出

的值:

偏置项的偏导数更简单:

这和全连接层的计算方式类似。同样的定义误差项为:

这是损失函数对临时变量的偏导数。和全连接型不同的是这是一个矩阵:

尺寸和卷积输出图像相同,而全连接层的误差向量和该层的神经元个数相等。这样有:

这也是一个卷积操作,

充当卷积核,

则充当输入图像。

我们用前面这个例子来进行计算:

卷积输出图像对应的误差项矩阵

为:

下面计算损失函数对卷积核各个元素的偏导数,根据链式法则有:

这是因为产生输出u11时卷积核元素k11在输入图像中对应的元素是x11。产生输出u12时卷积核元素k11在输入图像中对应的元素是x12。其他的依次类推。同样的有:

其它的以此类推。从上面几个偏导数的值我们可以总结出这个规律:损失函数对卷积核的偏导数实际上就是输入图像矩阵与误差矩阵的卷积:

其中*为卷积运算。写成矩阵形式为:

在这里conv为卷积运算,卷积输出图像的尺寸刚好和卷积核矩阵的尺寸相同。现在的问题是

怎么得到。如果卷积层后面是全连接层,按照全连接层的方式可以从后面的层的误差得到

。如果后面跟的是池化层,处理的方法在下一节中介绍。

接下来要解决的问题是怎样将误差项传播到前一层。卷积层从后一层接收到的误差为

,尺寸和卷积输出图像相同,传播到前一层的误差为

,尺寸和卷积输入图像相同。同样的,我们用上面的例子。假设已经得到了

,现在要做的是根据这个值计算出

。根据定义:

正向传播时的卷积操作为:

根据定义:

由于:

因此有:

类似的可以得到:

从而有:

类似的有:

剩下的以此类推。从上面的过程我们可以看到,实际上是将

进行扩充(上下左右各扩充2个0)之后的矩阵和卷积核矩阵进行顺时针180度旋转的矩阵的卷积,即:

将上面的结论推广到一般情况,我们得到误差项的递推公式为:

其中rot180表示矩阵顺时针旋转180度操作。至此根据误差项得到了卷积层的权重,偏置项的偏导数;并且把误差项通过卷积层传播到了前一层。推导卷积层反向传播算法计算公式的另外一种思路是把卷积运算转换成矩阵乘法,这种做法更容易理解,在后面将会介绍。

池化层

池化层没有权重和偏置项,因此无需对本层进行参数求导以及梯度下降更新,所要做的是将误差项传播到前一层。假设池化层的输入图像是X (l-1),输出图像为X (l),这种变换定义为:

其中down为下采样操作,在正向传播时,对输入数据进行了压缩。在反向传播时,接受的误差是

,尺寸和X (l)相同,传递出去的误差是

,尺寸和X (l-1)相同。和下采样相反,我们用上采样来计算误差项:

其中up为上采样操作。如果是对s

s的块进行的池化,在反向传播时要将

的一个误差项值扩展为

的对应位置的s

s个误差项值。下面分别对均值池化和max池化进行讨论。均值池化的变换函数为:

其中xi为池化的s

s子图像块的像素,y是池化输出像素值。假设损失函数对输出像素的偏导数为

,则对输入像素的偏导数为:

因此由

得到

的方法为,将

的每一个元素都扩充为s

s个元素:

再看第二种情况。如果是max池化,在进行正向传播时,需要记住最大值的位置。在反向传播时,对于扩充的s

s块,最大值位置处的元素设为,其他位置全部置为0:

同样的,我们给出推导过程。假设池化函数为:

损失函数对xi的偏导数为:

在这里分两种情况,如果 i = t,则有:

否则有:

至此我们得到了卷积层和池化层的反向传播实现。全连接层的反向传播计算方法和全连接神经网络相同,组合起来我们就得到了整个卷积网络的反向传播算法计算公式。

将卷积转化成矩阵乘法

如果用标准的形式实现卷积,则要用循环实现,依次执行乘法和加法运算。为了加速,可以将卷积操作转化成矩阵乘法实现,以充分利用GPU的并行计算能力。

整个过程分为以下3步:

1.将待卷积图像、卷积核转换成矩阵 2.调用通用矩阵乘法 GEMM 函数对两个矩阵进行乘积 3.将结果矩阵转换回图像

在反卷积的原理介绍中,我们也介绍了这种用矩阵乘法实现卷积运算的思路。在Caffe的实现中和前面的思路略有不同,不是将卷积核的元素复制多份,而是将待卷积图像的元素复制多份。

首先将输入图像每个卷积位置处的子图像按照行拼接起来转换成一个列向量。假设子图像的尺寸为s

s,和卷积核大小一样,列向量的尺寸就是s

s;如果一共有nconv个卷积子图像,列向量的个数就是nconv,接下来将这些列向量组合起来形成矩阵。假设有一个m

n的输入图像:

对于第一个卷积位置的s

s子图像,转换成列向量之后变为:

对于单通道图像,将所有位置的子矩阵都像这样转换成列向量,最后将nconv个列向量组成矩阵,矩阵的行数为s

s,列数为nconv

对于多通道图像,还要将上面的这种单通道图像转换成的矩阵在垂直方向依次拼接起来。最后形成的矩阵的行数为c

s

s,其中c是图像的通道数。

接下来,将卷积核矩阵也转换成向量。具体做法是,将卷积核矩阵的所有行拼接起来形成一个行向量。每个卷积核形成一个行向量,有个nkernel卷积核,就有个nkernel行向量。假设有一个s

s的卷积核矩阵:

转换之后变成这样的列向量:

如果卷积核有多个通道,就将这多个通道拼接起来,形成一个更大的行向量。由于卷积层有多个卷积核,因此这样的行向量有多个,将这些行向量合并在一起,形成一个矩阵:

有了上面这些矩阵,最后就将卷积操作转换成如下的矩阵乘积:

KX

乘积结果矩阵的每一行是一个卷积结果图像。下面用一个实际的例子来说明。假设输入图像为:

卷积核为:

则输入图像的第一个卷积位置的子图像为:

转化为列向量后为:

第二个卷积位置的子图像为:

转化成列向量为:

总共有4个卷积子图像,这样整个图像转换成矩阵之后为:

将卷积核转换成矩阵之后为:

读者可以验证,矩阵乘法:

KX

即为卷积的结果。

采用这种矩阵乘法之后,反向传播求导可以很方面的通过矩阵乘法实现,和全连接神经网络类似。假设卷积输出图像为Y,即:

Y = KX

则我们可以很方便的根据损失函数对的梯度计算出对卷积核的梯度,根据之前的文章“反向传播算法推导-全连接神经网络”中证明过的结论,有:

而误差项传播到前一层的计算公式为:

工程实现

下面我们介绍全连接层,卷积层,池化层,激活函层,损失层的工程实现细节。核心是正向传播和反向传播的实现。

在实现时,由于激活函数对全连接层,卷积层,以后要讲述的循环神经网络的循环层都是一样的,因此为了代码复用,灵活组合,一般将激活函数单独拆分成一层来实现。

下面我们将各种层抽象成统一的实现方式。在正向传播时,每一层根据输入数据x(l-1)计算输出数据x(l),本层可能还有需要训练得到的参数w(l)。正向传播时的计算为:

其中h是本层的映射函数。

无论是哪一种层,反向传播时要做的事情是:

如果本层有需要通过训练得到的参数,根据后一层传入的误差项

计算本层参数的梯度值

,而这个误差项是损失函数对本层输出值的梯度:

将误差传播到前一层,即根据

计算值

,而

是损失函数对本层输入数据的梯度:

在之前的文章“反向传播算法推导-全连接神经网络”中已经介绍过,激活函数实现的是向量到向量的逐元素映射,对输入向量的每个分量进行激活函数变换。正向传播时接受前一层的输入,通过激活函数作用于输入数据的每个元素之后产生输出。反向传播时接受后一层传入的误差项,计算本层的误差项并把误差项传播到前一层,计算公式为:

由于激活层没有需要训练得到的参数,因此无需根据误差项计算本层的梯度值,只需要将误差传播到前一层即可。

拆出激活函数之后,全连接层的输入数据是一个向量,计算该向量与权重矩阵的乘积,如果需要还要加上偏置,最后产生输出。正向传播的计算公式为:

反向传播时计算本层权重与偏置的导数:

另外还要将误差传播到前一层:

卷积层和池化层的反向传播实现已经在前面介绍了,因此在这里不再重复。

损失层实现各种类型的损失函数,它们仅在训练阶段使用,是神经网络的最后一层,也是反向传播过程的起点。损失层的功能是在正向传播时根据传入的数据以及函数的参数计算损失函数的值,送入到求解器中使用;在反向传播时计算损失函数对输入数据的导数值,传入前一层。

原文发布于微信公众号 - SigAI(SIGAICN)

原文发表时间:2018-08-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习算法与Python学习

线性分类器

线性分类 上一篇笔记介绍了图像分类问题。图像分类的任务,就是从已有的固定分类标签集合中选择一个并分配给一张图像。我们还介绍了k-Nearest Neighbor...

3799
来自专栏机器学习、深度学习

目标检测中的尺度--An Analysis of Scale Invariance in Object Detection – SNIP

An Analysis of Scale Invariance in Object Detection – SNIP Code will be made ...

6296
来自专栏机器学习、深度学习

多目标检测跟踪文献代码汇总

The Multiple Object Tracking Benchmark https://motchallenge.net/ 高速跟踪: 当检测精度较高...

5205
来自专栏深度学习与计算机视觉

Object Detection系列(三) Fast R-CNN

Object Detection系列(一) R-CNN Object Detection系列(二) SPP-Net Object Detectio...

4635
来自专栏一直在跳坑然后爬坑

向量空间相关概念总结-基

之前的向量空间一节已经说过:向量空间对向量的线性组合封闭(相加和数乘),所以,向量空间可以通过“向量+线性组合”构成。也可以说,这个向量空间由这些向量所张成,反...

3163
来自专栏机器学习算法与Python学习

卷积神经网络详解

注:看本文之前最好能构理解前馈圣经网络以及BP(后向传播)算法,可以看之前发的相关文章或者看知乎、简书、博客园等相关博客。 卷积神经网络(Convolution...

3038
来自专栏计算机视觉战队

每日一学——线性分类笔记(上)

线性分类 上一篇笔记介绍了图像分类问题。图像分类的任务,就是从已有的固定分类标签集合中选择一个并分配给一张图像。我们还介绍了k-Nearest Neighbor...

3395
来自专栏null的专栏

简单易学的机器学习算法——神经网络之BP神经网络

一、BP神经网络的概念     BP神经网络是一种多层的前馈神经网络,其主要的特点是:信号是前向传播的,而误差是反向传播的。具体来说,对于如下的只含一个隐层的神...

3564
来自专栏我的python

自然语言处理之文本卷积

自然语言处理之文本卷积 1.文本的向量表示 2.文本的1维卷积 3.池化

36216
来自专栏红色石头的机器学习之路

Coursera吴恩达《神经网络与深度学习》课程笔记(4)-- 浅层神经网络

上节课我们主要介绍了向量化、矩阵计算的方法和python编程的相关技巧。并以逻辑回归为例,将其算法流程包括梯度下降转换为向量化的形式,从而大大提高了程序运算速度...

2870

扫码关注云+社区

领取腾讯云代金券