MENU

CNN 中的反向传播

February 14, 2020 • Read: 4538 • Deep Learning阅读设置

Pooling 层的反向传播

我们知道 Pooling 操作会使得 feature map 的尺寸发生变化,假如做 $2\times 2$ 的池化,假设 $l+1$ 层的 feature map 有 16 个梯度,那么第 $l$ 层应该需要 64 个梯度,做法很简单,只需要把 1 个像素的梯度反向传给 4 个像素即可,但是要保证传递的梯度总和不变。由于有这条原则,因此 avg pooling 和 max pooling 的反向传播并不相同

1. avg pooling

avg pooling 的前向传播就是把一个 patch(窗口)内的值求和取平均。那么反向传播的过程就是把某个元素的梯度等分成 n 份,分配给前一层,这样就保证了池化前后的梯度之和保持不变,还是比较好理解的,图示如下

avg pooling 比较容易让人理解错的地方就是以为梯度直接复制 N 遍,但是这样会造成 loss 之和变为原来的 N 倍,网络会发生梯度爆炸

2. max pooling

max pooling 也要满足梯度之和不变的原则,max pooling 的前向传播是把 patch 中最大的值传给后一层,而其他像素的值直接被舍弃掉。那么反向传播也就是把这个梯度直接传给前一层某一像素,儿其它像素不接受梯度,也就是 0。max pooling 和 avg pooling 操作的不同点在于需要记录池化时,到底哪个像素的值是最大的,也就是 max_id,这个可以看 caffe 的源码的 pooling_layer.cpp,下面是 caffe 框架 max pooling 部分的源码

  • // If max pooling, we will initialize the vector index part
  • if (this->layer_param_.pooling_param().pool() == PoolingParameter_PoolMethod_MAX
  • && top.size() == 1) {
  • max_idx_.Reshape(bottom[0]->num, channels_, pooled_height_, pooled_width_);
  • }

源码中有一个名为 max_idx_的变量,这个变量记录的就是最大值所在的位置,因为在反向传播中要用到。前向传播和反向传播的过程如下图所示

Archives Tip
QR Code for this page
Tipping QR Code
Leave a Comment