步长stride>2的二维卷积方法的反向传播算法(主要讨论误差矩阵)

前言

存在步长stride为1的卷积方式的反向传播,但是很多时候,使用的卷积步长会大于1,这个情况下的卷积方式的反向传播和步长为1的情况稍稍有些区别,不过区别并没有想象中那么大,因此下面就对步长stride大于1的情况进行简单的阐述。请注意:这里的所有推导过程都只是针对当前设置的参数信息,并不具有一般性,但是所有的推导过程可以推导到一般的运算,因此以下给出的并不是反向传播算法的严格证明,不涉及十分复杂的公式推导,争取可以以一种简单的方式来理解卷积的反向传播。希望可以很好的帮助理解反向传播算法。

需要注意的是,在本文中,所有的正向传播过程中,卷积的步长stride均固定为2。

一,参数设置

这里我们设置我们的数据矩阵(记作xxx)大小为5x5,卷积核(记作kkk)大小为3x3,由于步长是2,因此,卷积之后获得的结果是一个2x2大小的数据矩阵(不妨我们记作uuu)。偏置项我们记为bbb,将和卷积之后的矩阵进行相加。

我们的参数汇总如下:
图 1
和前面一样,我们定义卷积操作的符号为convconvconv,我们可以将卷积表示为(需要注意的是这里步长选取为2):
  x   c o n v   k + b = u \ x~ conv~k+b=u  x conv k+b=u
  展开之后,我们可以得到:
展开之后,我们可以得到:
图 32
将矩阵   u \ u  u 进一步展开,我们有:
在这里插入图片描述

二、误差传递

步长为2的二维卷积已经在上面的式子中被完整的表示出来了,因此,下一步就是需要对误差进行传递,和前面步长为1的情况一样,我们可以将上面的结果保存在一张表格中,每一列表示的是一个特定的输出   ∂ u i , j \ \partial u_{i, j}  ui,j,每一行表示的是一个特定的输入值   ∂ x p , k \ \partial x_{p, k}  xp,k,行与列相交的地方表示的就是二者相除的结果,表示的是输出对于输入的偏导数,即   ∂ u i , j ∂ x p , k \ \frac{\partial u_{i, j}}{\partial x_{p, k}}  xp,kui,j 。于是,表格如下:
  在这里插入图片描述在这里插入图片描述在这里插入图片描述
  可以看出,数据依然都是很规律的进行着重复。

我们假设后面传递过来的误差是   δ \ δ  δ,即:
  图 12
  类似地,我们可以计算出所有的输入矩阵中的元素所对应的偏导数信息,所有的偏导数计算结果均在上表中列出。

和前面步长stride为1的卷积方式的误差传递类似,我们需要对传递来的误差矩阵和卷积核进行一定的处理,然后再进行卷积,得到应该传递到下一层的网络结构中,所以我们需要的解决问题的问题有三个,即:1.误差矩阵如何处理,2.卷积核如何处理,3.如何进行卷积。
  同样,我们将   ∂ L ∂ x 3 , 3 \ \frac{\partial L_{}}{\partial x_{3, 3}}  x3,3L
单独拿出来进行考察,如果需要用到全部的卷积核的元素的话,并不能和传递来的误差矩阵相匹配,为了使得两者可以再维度上相匹配,我们再误差矩阵中添加若干0,和步长stride为1的卷积反向传播一样,我们也将卷积核进行180°翻转,于是,我们可以得到:
在这里插入图片描述
在这里插入图片描述
误差矩阵插入0的方式
  很明显,我们唯一需要解决的问题就是如何在误差矩阵中插入0。在这里直接给出结论,那就是每个相邻的元素之间应该插入(步长stride - 1)个0,或者说每个元素之间的距离是卷积的步长。因为在这个模型中,唯一和前面的卷积方式不同的变量就是步长stride,那么需要满足的条件也必然和步长有关。

当我们在元素之间插入合适数目的0之后,接下来就是在误差矩阵周围填补上合适数目的0层,然后将卷积核旋转180°,最后按照步长为1的方式进行卷积,最后得到应该向前传递的误差矩阵。 这两步和步长stride为1的反向传播算法相同

三、误差矩阵参数更新(一次卷积后进入下一次)

当我们解决了误差的向前传递之后,下一步就是解决参数的更新的问题。和前面的定义一样,假设我们在这一阶段接收到的后方传递过来的误差为   δ \ δ  δ,即:
3 6
37
38
据此,我们可以发现,在卷积核参数更新的过程中,我们也需要对误差矩阵进行插入0的操作。而且插入0的方式和误差传递过程中的方式完全相同。所以,我们可以总结出步长为s的时候卷积反向传播的卷积核参数更新的方法,即:1.首先在接收到的误差矩阵中插入合适数目的0,2.在输入矩阵xxx上应用误差矩阵进行步长为1的卷积,从而得到卷积核的更新梯度。

同样,我们由上面的推导可以发现,无论是何种方式的卷积操作,偏置项bbb的更新梯度都是接收到的误差矩阵中的元素之和。

四、总结

我们将上面的求解过程总结如下有:
  在这里插入图片描述
正向传播:

conv(x, kernel, bias, "VALID")

反向传播代码:

conv_backward(error, x, kernel, bias):
	# 计算传递给下一层的误差
	1.在接收到的error矩阵的矩阵中插入合适数目的0,使得每个元素之间的0的数目为(stride - 1)
	2.在error周围填补上合适数目的0
	3.将kernel旋转180°
	4.将填补上0的误差和旋转之后的kernel进行步长为1的卷积,从而得到传递给下一层的误差new_error。
	
	# 更新参数
	1.在接收到的error矩阵的矩阵中插入合适数目的0,使得每个元素之间的0的数目为(stride - 1)
	2.将输入矩阵x和插入0之后的误差矩阵error进行步长为1的卷积,得到kernel的更新梯度
	3.将上一层传递来的误差矩阵error所有元素求和,得到bias的更新梯度
	4.kernel := kernel - 学习率 * kernel的更新梯度
	5.bias := bias - 学习率 * bias的更新梯度
	
	# 返回误差,用以传递到下一层
	return new_error

五、卷积基础操作: Kernel, Padding, Stride & Column

一般在模型表述中,卷积操作的简写类似 k(3,3)-c512-s1-p1, 其中 k 代表 kernel(大小), c 代表 column(层数),s 代表 stride(步长), p 代表 padding(填充数量)。这四个是卷积操作的基本属性。

Kernel 卷积核
一般为奇数正方形,如 3x3, 7x7

Column
Kernel 的深度或者说层数

Stride
Kernel 移动的步长,Stride 其实就是一个 down-sampling 的过程。

Padding
为保留图像边缘信息而在四周进行padding(一般为0)。

卷积前后特征图的大小关系为:
在这里插入图片描述
助记: 本来的尺寸是   n i n \ n_{in}  nin, 两边加 padding 就要   + 2 p \ +2p  +2p , kernel 放进去就占一片位置,所以   − k \ -k  k, 按照 stride 跳着走,所以就要   s \ \over s s  , 剩下的不够一个k就不走了,所以要向下取整。前面减得太多,最后整体   + 1 \ +1  +1。就得到了   n o u t \ n_{out}  nout

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值