估算卷積層與反卷積層運算量
- 2020 年 4 月 1 日
- 筆記
本文首發於知乎 https://zhuanlan.zhihu.com/p/65248401
對於煉丹師來說,針對任務調整網路結構或者在做模型精簡的時候,都會去考慮模型的運算量的大概值,雖然這個只是一個間接參考值,網路真正的運行速度還要考慮其他的因素(具體解釋可以參考shufflenet v2這篇文章的解讀)。
那麼對於給定一個卷積神經網路的模型定義,該如何估算其浮點數運算量。對卷積神經網路來說,卷積層的運算量是占網路總運算量的大頭,而對於一些像素級別任務,反卷積層也要算上。
網上有很多介紹如何計算卷積網路運算量的文章,基本都是介紹卷積還有全連接等一些常用的層是如何計算的,但很少有介紹反卷積層的運算量如何計算。
本文主要內容是介紹卷積、反卷積、分組卷積和分組反卷積的運算量分別是如何估算出來的。
本文相關程式碼,計算MXNet網路運算量的小工具:
Python版本:https://github.com/Ldpe2G/DeepLearningForFun/tree/master/MXNet-Python/CalculateFlopsTool
Scala版本:https://github.com/Ldpe2G/DeepLearningForFun/tree/master/Mxnet-Scala/UsefulTools
普通卷積
普通卷積層的運算量很多文章都已經講過如何計算了,這裡也重複講下,為後面介紹反卷積的運算量做鋪墊。卷積的運算一般的實現就是轉化為矩陣乘法運算,首先來看一下卷積運算的簡單的示意圖:

首先左上角定義了輸入和輸出的feature map的形狀,假設卷積核大小是,所以權值的形狀就是 。
然後一般來說實現卷積的前向是通過首先對輸入的feature map應用im2col操作,從 形狀的矩陣,轉換成形狀是 的矩陣,接著與權值相乘,就得到右邊的輸出。所以卷積前向的運算量是:

當然卷積運算的時候除了乘法還有加法,而我這了只算了乘法的次數。
如果加上加偏置的計算,運算量就是:

下面這個倉庫的程式碼在計算運算量的時候也是只算了乘法: https://github.com/albanie/convnet-burden
卷積的反向和接下來要介紹和反卷積的前向是對應的,這裡簡單提一下卷積的反向過程,求輸入的梯度的時候是把權值轉置,然後與輸出的梯度相乘就得到中間結果,然後再做一個col2im操作把中間結果回填到輸入梯度矩陣的對應位置上。
普通反卷積
接著我們來看下普通反卷積的運算量的計算方法,首先看一下反卷積前向和後向運算過程的示意圖:

左上角也是定義了反卷積的輸入與輸出的feature map大小,這裡反卷積的權值的形狀與卷積有點不同,是 ,這是因為反卷積的前向和後向操作分別是對應卷積的後向和前向,也就是剛好反過來的。
然後我們直接看反卷積的前向操作,和卷積的後向操作對應,權值做轉置與輸入feature map做一個乘法,這裡可以看成是一個的卷積,輸出通道數是 ,然後的到中間結果,然後再做一個col2im的操作回填到輸出feature map對應的位置上。所以反卷積的運算量如下:

同樣 部分也是只考慮了乘法次數,還有後面的col2im回填累加其實也會佔據運行時間的,但是這裡沒有加上這個加法次數的時間。
加上偏置的話則是:

所以計算反卷積的運算量是需要知道輸入與輸出feature map大小的。
分組卷積
分組卷積的運算量其實就是直接把卷積的運算量除以組數,比如分為g組,繼續沿用上面卷積的運算量公式的話,那麼分組卷積的運算量為:

加上偏置的話就是:

具體是怎麼算出來的呢,直接看下面的示意圖就應該很清晰了:

左上角定義了輸入與輸出feature map的大小還有卷積的分組數,則根據分組卷積的定義,輸出feature map的通道 被分成了 組,每組裡面的 個feature map鏈接輸入的對應索引的 個通道的feature map。
所以看上圖,在把輸入作im2col操作的時候也是按組來做的,每組 feature map 都會生成一個 的矩陣,然後與對應的權值做乘法,就是圖中的相同顏色部分,每組做完乘法就得到了輸出feature map,如果還有偏置則是最後再加上,所以分組卷積的運算量就可以求到的了。
分組反卷積
來看下反卷積,有了分組卷積的鋪墊,分組反卷積也不難求,分組反卷積的FP同樣也是對應分組卷積的BP:

同樣的,左上角定義了分組反卷積的輸入和輸出feature map大小,分組數為 。同樣的輸出feature map的通道 被分成了 組,每組裡面的 個feature map鏈接輸入的對應索引的 個通道的feature map。
然後在前向過程中,對於每組的計算,權值首先需要轉置一下,得到 的權值矩陣然後和輸入對應的組數做乘法,然後得到輸出對應的組的中間結果,然後每一組的中間結果再通過 col2im 回填到輸出 feature map 對應的組的位置。
所以分組反卷積的運算量如下:

如果有偏置的話就是:

如果想更加詳細的了解程式碼上的實現,讀者可以參考MXNet中反卷積權值shape的推斷部分,還有反卷積前向部分程式碼,或者一些推理框架,比如NCNN和MNN的實現。
相關資料
- [1] https://www.zhihu.com/question/328891283/answer/717113611
- [2] https://www.zhihu.com/question/48279880/answer/838063090