深度學習-MobileNet (Depthwise separable convolution)
今天要介紹的depthwise separable convolution是Google在2017年提出的MobileNet模型(https://arxiv.org/pdf/1704.04861.pdf),主要是因為隨著深度學習的快速發展,模型不但深又巨大,使得整體參數很可觀(比較流行的模型幾乎都以千萬個參數為單位),而加乘法運算(multiplications and accumulations)更達到數十億為單位的計算量,這麼大的模型不太能在Mobile/Portable device(手機或是即時翻譯機在沒有大量GPU幫助下)做到real time implement,因此Google提出MobileNet來解決這個問題。
在這些巨大的網路模型中,大部分的計算量都發生在卷積(convolution)計算中,因此Depthwise separable convolution就是提出來在不減低太多performance狀態下,盡量去減少原始convolution的計算量。
Note:
1. 減少計算複雜度或是計算時間方式除了這篇介紹的方法外,還有定點運算的方式,關鍵字是Quantization(google Song Han這個大神可以得到很多訊息)和Binary neural network(極端的神經網路)。
2. 如果有用到全連接層(fully connection),全連接層參數量和計算量更巨大更可觀,有人用SVD(singular value decomposition)對全連結層的權重做拆解減少運算量,比如4096–4096(參數量: 4096*4096=16777216)拆成4096–512–4096(4096*512+512*4096=4194304),拆解的參數原始的1/4。
這邊先介紹什麼是Depthwise separable convolution,然後我再比較Depthwise separable convolution和一般的convolution計算量差了多少。
在開始Depthwise separable convolution前,我們先假設一般卷積運算(參考:之前的文章)
輸入資料: W_in * H_in * Nch (輸入圖的寬*高*輸入channel數)
Kernel Map: k * k * Nk (Kernel map寬*高*kernel數,kernel寬高假設一樣)
輸出資料: W_out * H_out * Nk (輸出圖的寬*高*輸出channel數)
後面我們開始介紹Depthwise separable convolution,跟Depthwise separable convolution怎麼達到一樣的輸出結果量。
Depthwise separable convolution
Depthwise separable convolution的計算是希望在不影響輸出結構的狀況下減少運算量,基本上可以拆成兩部分Depthwise convolution和pointwise convolution。
Depthwise convolution
針對輸入資料的每一個Channel都建立一個k*k的Kernel,然後每一個Channel針對對應的Kernel都各自(分開)做convolution。
這步驟和一般卷積不太一樣,一般的卷積計算是每個Kernel Map都要和所有channel都去做convolution,這邊是分開獨立去做。
Pointwise convolution
在輸入資料的每個channel做完depthwise convolution後,針對每個點的所有channel做pointwise convolution。
實際做法是說建立Nk個1*1*Nch的kernel Map,將depthwise convolution的輸出做一般1*1的卷積計算
所以計算方式
- Depthwise convolution:
輸入資料: W_in * H_in * Nch
做每個輸入Channel相對應的Kernel Map (k*k)的convolution
輸出大小為W_out * H_out * Nch
2. Pointwise convolution
輸入資料: W_out * H_out * Nch
做一般Nk個Kernel Map (1*1)的convolution
輸出大小: W_out * H_out * Nk
所以Depthwise separable convolution(下圖)的輸入和輸出結果量是可以跟一般卷積計算一樣的。
計算量
輸入資料: W_in * H_in * Nch,Kernel Map: k * k * Nk,輸出資料: W_out * H_out * Nk
一般卷積 計算量為 W_in * H_in * Nch* k * k * Nk
Depthwise separable convolution計算量為
(Depthwise convolution計算量+Pointwise convolution計算量)
Depthwise convolution計算量為 W_in * H_in * Nch* k * k
Pointwise convolution計算量為 Nch*Nk * W_in * H_in
所以當Kernel Map越大和Kernel Map數量越多,Depthwise separable convolution可以節省越多計算量。
假設input為416*416*50, filter為10個大小為3*3的kernel map,Depthwise separable convolution只有一般捲積的1/10+1/9=0.211計算量。