天天看點

深度學習 | (1) 卷積神經網絡Pooling操作的反向傳播

傳統的神經網絡無論是隐層還是激活函數的導數都是可導,可以直接計算出導數函數,然而在CNN網絡中存在一些不可導的特殊環節,比如Relu等不可導的激活函數、造成維數變化的池化采樣、已經參數共享的卷積環節。NN網絡的反向傳播本質就是梯度(可能學術中會用殘差這個詞,本文的梯度可以認為就是殘差)傳遞,是以隻要我們搞懂了這些特殊環節的導數計算,那麼我們也就了解CNN的反向傳播。

Pooling池化操作的反向梯度傳播

CNN網絡中另外一個不可導的環節就是Pooling池化操作,因為Pooling操作使得feature map的尺寸變化,假如做2×22×2層就會有64個梯度,這使得梯度無法對位的進行傳播下去。其實解決這個問題的思想也很簡單,就是把1個像素的梯度傳遞給4個像素,但是需要保證傳遞的loss(或者梯度)總和不變。根據這條原則,mean pooling和max pooling的反向傳播也是不同的。

1、mean pooling

mean pooling的前向傳播就是把一個patch中的值求取平均來做pooling,那麼反向傳播的過程也就是把某個元素的梯度等分為n份配置設定給前一層,這樣就保證池化前後的梯度(殘差)之和保持不變,還是比較了解的,圖示如下

深度學習 | (1) 卷積神經網絡Pooling操作的反向傳播

mean pooling比較容易讓人了解錯的地方就是會簡單的認為直接把梯度複制N遍之後直接反向傳播回去,但是這樣會造成loss之和變為原來的N倍,網絡是會産生梯度爆炸的。

2、max pooling

max pooling也要滿足梯度之和不變的原則,max pooling的前向傳播是把patch中最大的值傳遞給後一層,而其他像素的值直接被舍棄掉。那麼反向傳播也就是把梯度直接傳給前一層某一個像素,而其他像素不接受梯度,也就是為0。是以max pooling操作和mean 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() == )
{
    max_idx_.Reshape(bottom[]->num(), channels_, pooled_height_,pooled_width_);
  }           
  • 1
  • 2
  • 3
  • 4
  • 5

源碼中有一個max_idx_的變量,這個變量就是記錄最大值所在位置的,因為在反向傳播中要用到,那麼假設前向傳播和反向傳播的過程就如下圖所示

深度學習 | (1) 卷積神經網絡Pooling操作的反向傳播

繼續閱讀