Convolutional Neural Networks(CNN) #6 Pooling in Backward pass
本文將介紹Pooling layer在反向傳遞(Backward propagation / Backward pass)的運作過程,雖然Pooling層的參數不需要被訓練,但是在大多數情況下,Pooling layer通常是承接著啟動函數的輸出。因此,本文將會詳細介紹反向傳遞時Kernel、Bias、Feature map的細節。
如果你對於Pooling layer的運作方式不太了解,可以先來讀這一篇:CNN #2 Pooling layer。若想要了解更多關於卷積神經網路於反向傳遞時的計算過程與其推導,強烈建議閱讀發布的這幾篇教學:CNN #4 Kernels in Backward、CNN #5 Feature maps & Biases in Backward。
此外,本篇內容中卷積神經網路的功能,同步存放於Github:https://github.com/PoLun-Wang/DL_practice_convolutional_neural_networks
表(1):符號說明
符號 | 說明 |
$x$ | 前一層神經網路的輸出 |
$z$ | 現在這一層Pooling運算的結果 |
$L(\cdot)$ | Loss function |
圖(1):池化層簡易架構
因為Pooling layer的Back propagation運作比較易懂,所以$\frac{\partial L}{\partial z}$我就直接以矩陣表達:
$\frac{\partial L}{\partial z}=\begin{bmatrix}
\frac{\partial L}{\partial z_{11}} & \frac{\partial L}{\partial z_{12}} & \frac{\partial L}{\partial z_{13}} & \frac{\partial L}{\partial z_{14}}\\
\frac{\partial L}{\partial z_{21}} & \frac{\partial L}{\partial z_{22}} & \frac{\partial L}{\partial z_{23}} & \frac{\partial L}{\partial z_{24}}\\
\frac{\partial L}{\partial z_{31}} & \frac{\partial L}{\partial z_{32}} & \frac{\partial L}{\partial z_{33}} & \frac{\partial L}{\partial z_{34}}\\
\frac{\partial L}{\partial z_{41}} & \frac{\partial L}{\partial z_{42}} & \frac{\partial L}{\partial z_{43}} & \frac{\partial L}{\partial z_{44}}
\end{bmatrix}$
對於Max Pooling來說原先在Forward pass的運算規則是挑出Sliding window之中的最大值填入$z$,而在Backward pass則是把$\frac{\partial L}{\partial z}$的數值直接回傳至原本上一層Feature map$x$對應到最大值的位置。
p.s. 出現不止一個最大值的話,就一樣最大的位置同時填入數值。
Step1:以$\frac{\partial L}{\partial z_{11}}$作為例子來說,Sliding window以Pooling kernel size在上層Feature map上會框選到$\begin{bmatrix} 1 & 2 & 3\\ 2 & 2 & 5\\ 0 & 6 & 9 \end{bmatrix}$,由此確定最大值的位置是在右下角。
Step2:知道最大值的位置之後,就可以在暫存結果的矩陣中的相對位置填上$\frac{\partial L}{\partial z_{11}}$。此時,暫存結果的矩陣狀態如下:
$\begin{bmatrix}
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 &\frac{\partial L}{\partial z_{11}} & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0
\end{bmatrix}$
Step3:接著依照Stride$=1$的規則,將Sliding window向右移動$1$像素,將會從$z$上面框選到$\begin{bmatrix}2&3&1\\2&5&4\\6&9&6\end{bmatrix}$,由此得知最大值在正下方的位置。此外,在$z$這邊也要跟著向右移動$1$像素,也就會對應到$\frac{\partial L}{\partial z_{12}}$。最後,依照上述Step2的作法,將$\frac{\partial L}{\partial z_{12}}$累加到正確的位置後,暫存結果的矩陣狀態如下:
$\begin{bmatrix}
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 &\frac{\partial L}{\partial z_{11}}+\frac{\partial L}{\partial z_{12}} & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0
\end{bmatrix}$
重複上述步驟就可以完成Pooling layer在BP裡面的計算。
原本Mean Pooling的作法是將Sliding window內的數值計算平均,並將結果填入在輸出Feature map上對應之位置。在Backward pass中的邏輯也很相似,差別在於方向相反,實際作法如下步驟所示。
Step1:以$\frac{\partial L}{\partial z_{11}}$來說,對應至$x$的位置是$\begin{bmatrix} 1 & 2 & 3\\ 2 & 2 & 5\\ 0 & 6 & 9 \end{bmatrix}$。
Step2:接著只需要將$\frac{\partial L}{\partial z_{11}}$除以像素數($3\times3=9$),並將結果分散填入暫存矩陣中。
$\begin{bmatrix}
(\frac{\partial L}{\partial z_{11}})/9 &(\frac{\partial L}{\partial z_{11}})/9 &(\frac{\partial L}{\partial z_{11}})/9 & 0 & 0 & 0 \\
(\frac{\partial L}{\partial z_{11}})/9 &(\frac{\partial L}{\partial z_{11}})/9 &(\frac{\partial L}{\partial z_{11}})/9 & 0 & 0 & 0 \\
(\frac{\partial L}{\partial z_{11}})/9 &(\frac{\partial L}{\partial z_{11}})/9 &(\frac{\partial L}{\partial z_{11}})/9 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0
\end{bmatrix}$
重複上述步驟就可以完成Pooling layer在BP裡面的計算。
- Andrew Ng – Convolution Neural Networks in Coursera
- (paper) A guide to convolution arithmetic for deep learning
- Back Propagation in Convolutional Neural Networks — Intuition and Code
- A Comprehensive Introduction to Different Types of Convolutions in Deep Learning