深度可分离卷积(Xception 与 MobileNet)
前言
從卷積神經(jīng)網(wǎng)絡(luò)登上歷史舞臺開始,經(jīng)過不斷的改進(jìn)和優(yōu)化,卷積早已不是當(dāng)年的卷積,誕生了分組卷積(Group convolution)、空洞卷積(Dilated convolution 或 à trous)等各式各樣的卷積。今天主要講一下深度可分離卷積(depthwise separable convolutions),這是 Xception 以及 MobileNet 系列的精華所在。而它最早是由Google Brain 的一名實習(xí)生 Laurent Sifre 于2013年提出,Sifre在其博士論文中對此進(jìn)行了詳細(xì)的分析和實驗,有興趣的可以去翻閱。
從 Inception module 到 depthwise separable convolutions
Xception 的論文中提到,對于卷積來說,卷積核可以看做一個三維的濾波器:通道維+空間維(Feature Map 的寬和高),常規(guī)的卷積操作其實就是實現(xiàn)通道相關(guān)性和空間相關(guān)性的聯(lián)合映射。Inception 模塊的背后存在這樣的一種假設(shè):卷積層通道間的相關(guān)性和空間相關(guān)性是可以退耦合的,將它們分開映射,能達(dá)到更好的效果(the fundamental hypothesis behind Inception is that cross-channel correlations and spatial correlations are sufficiently decoupled that it is preferable not to map them jointly.)。
以上的圖中,Figure 1 是一個典型的 Inception 模塊,它先在通道相關(guān)性上利用 1×1 卷積將輸入的 Feature Map 映射到幾個維度比原來更小的空間上,相當(dāng)于每個通道圖乘上不同的因子做線性組合,再用 3×3 卷積這些小空間,對它的空間和通道相關(guān)性同時做映射。以第二個分支為例,假設(shè) Input 是 28×28×192 的 Feature Maps,在通道相關(guān)性上利用 32 個 1×1×192 的卷積核做線性組合,得到 28×28×32 大小的 Feature Maps,再對這些 Feature Maps 做 256 個 3×3×32 的卷積,即聯(lián)合映射所有維度的相關(guān)性,就得到 28×28×256 的 Feature Maps 結(jié)果。可以發(fā)現(xiàn),這個結(jié)果其實跟直接卷積 256 個3×3×192 大小的卷積核是一樣。也就是說,Inception 的假設(shè)認(rèn)為用 32 個 1×1×192 和 256 個 3×3×32 的卷積核退耦級聯(lián)的效果,與直接用 256個 3×3×192 卷積核等效。而兩種方式的參數(shù)量則分別為32×1×1×192 + 256×3×3×32 = 79872 和 256×3×3×192 = 442368。
Figure 2 是簡化后的 Inception 模塊(僅使用3×3卷積并去除 Avg pooling),基于 Figure 2 的簡化模塊可以將所有的 1×1 卷積核整合成一個大的 1×1 卷積,如將 3 組 32 個 1×1×192 的卷積核重組為 96個 1×1×192 的卷積核,后續(xù)再接3組 3×3卷積,3×3卷積的輸入為前序輸出的1/3(Figure 3)。Xception 論文進(jìn)而提出在 Figure 3 的基礎(chǔ)上,是否可以做出進(jìn)一步的假設(shè):通道相關(guān)性和空間相關(guān)性是完全可分的,由此得到 Figure 4 中的 “extreme” Inception。如 Figure 4 所示,先進(jìn)行 1×1 的通道相關(guān)性卷積,后續(xù)接的 3×3 卷積的個數(shù)與 1×1 卷積的輸出通道數(shù)相同。
Figure 4 中的 Inception 模塊與本文的主角-深度可分離卷積就近乎相似了,但仍然存在兩點區(qū)別:
1、深度可分離卷積先進(jìn)行 channel-wise 的空間卷積,再進(jìn)行1×1 的通道卷積,Inception則相反;
2、Inception中,每個操作后會有一個ReLU的非線性激活,而深度可分離卷積則沒有。
回過頭來看一下從常規(guī)卷積 -> 典型的Inception -> 簡化的Inception -> “極限”Inception,實際上是輸入通道分組的一個變化過程。常規(guī)卷積可看做將輸入通道當(dāng)做整體,不做任何分割;Inception則將通道分割成3至4份,進(jìn)行1×1的卷積操作;“極限”Inception則每一個通道都對應(yīng)一個1×1的卷積。
引入深度可分離卷積的 Inception,稱之為 Xception(Extreme Inception),其結(jié)構(gòu)圖如下,圖中的SeparableConv即是深度可分離卷積,另外可以看出每個模塊均采用殘差連接(開頭和結(jié)尾的幾個除外):
Xception architecture
Xception 作為 Inception v3 的改進(jìn)版,在 ImageNet 和 JFT 數(shù)據(jù)集上有一定的性能提升,但是參數(shù)量和速度并沒有太大的變化,因為Xception 的目的不在于模型的壓縮。下圖是 ImageNet 上 1000 類分類網(wǎng)絡(luò)的訓(xùn)練參數(shù)和訓(xùn)練速度對比:
MobileNet 中的 depthwise separable convolutions
MobileNet 是Google推出的一款高效的移動端輕量化網(wǎng)絡(luò),其核心即是深度可分離卷積。
按照前文所述,深度可分離卷積將傳統(tǒng)的卷積分解為一個深度卷積(depthwise convolution)+ 一個 1×1的卷積(pointwise convolution)。如下圖所示,(a)是傳統(tǒng)卷積,(b)、?分別對應(yīng)深度可分離卷積的深度卷積和 1×1的卷積:
假設(shè)輸入特征圖大小為 DF×DF×MD_F×D_F×MDF?×DF?×M,輸出特征圖大小為 DF×DF×ND_F×D_F×NDF?×DF?×N,卷積核大小為 D_K×D_K,則傳統(tǒng)卷積的計算量為:
DK×DK×M×N×DF×DFD_K×D_K×M×N×D_F×D_FDK?×DK?×M×N×DF?×DF?
深度可分離卷積的計算量為深度卷積和 1×1 卷積的計算量之和:
DK×DK×M×DF×DF+M×N×DF×DFD_K×D_K×M×D_F×D_F+M×N×D_F×D_FDK?×DK?×M×DF?×DF?+M×N×DF?×DF?
深度可分離卷積與傳統(tǒng)卷積的計算量之比為:
DK×DK×M×DF×DF+M×N×DF×DFDK×DK×M×N×DF×DF=1N+1DK2\frac{D_K×D_K×M×D_F×D_F+M×N×D_F×D_F}{D_K×D_K×M×N×D_F×D_F} = \frac{1}{N} + \frac{1}{D_K^2}DK?×DK?×M×N×DF?×DF?DK?×DK?×M×DF?×DF?+M×N×DF?×DF??=N1?+DK2?1?
以上文中 28×28×192 的輸入,28×28×256 的輸出為例,卷積核大小為 3×3,兩者的計算量之比為:
39889920346816512=0.1150\frac{39889920}{346816512} = 0.115034681651239889920?=0.1150
深度可分離卷積的計算量縮減為傳統(tǒng)卷積的 1/9 左右。
下圖是傳統(tǒng)卷積(左)與MobileNet中深度可分離卷積(右)的結(jié)構(gòu)對比。Depth-wise卷積和1×1卷積后都增加了BN層和ReLU的激活層。
Deep-wise結(jié)合1×1的卷積方式代替?zhèn)鹘y(tǒng)卷積不僅在理論上會更高效,而且由于大量使用1×1的卷積,可以直接使用高度優(yōu)化的矩陣相乘(如GEMM)來完成,并且1×1的卷積不需要im2col的預(yù)處理操作,大大提升運算效率。MobileNet 中有約95%的乘加運算來自1×1卷積(同時也占總參數(shù)量的75%):
MobileNet的整體結(jié)構(gòu)如下圖所示,共含有28個網(wǎng)絡(luò)層:
為了滿足模型更小、速度更快的應(yīng)用需求,MobileNet 提出了寬度因子 \alpha 和分辨率因子 \rho兩個超參數(shù)。前者用于控制輸入輸出的通道數(shù),后者則用于控制輸入輸出的分辨率。加入超參數(shù)后的深度可分離卷積的計算量為:
DK×DK×αM×ρDF×ρDF+αM×αN×ρDF×ρDFD_K×D_K× {\alpha}M× {\rho}D_F× {\rho}D_F+ {\alpha}M× {\alpha}N× {\rho}D_F× {\rho}D_FDK?×DK?×αM×ρDF?×ρDF?+αM×αN×ρDF?×ρDF?
理論上,加入超參數(shù)后的計算量約為加入前的 1α2?ρ2\frac{1}{{\alpha}^2*{\rho}^2}α2?ρ21?:
Tensorflow 中 depthwise separable convolutions 接口
Tensorflow 里深度可分離卷積的實現(xiàn)代碼位于python/ops/nn_impl.py文件中,函數(shù)接口為:
除去與實現(xiàn)無關(guān)的name和data_format兩個參數(shù)外,其他6個參數(shù):
input:4-D的 Tensor 輸入,形如[batch, height, width, in_channels]
depthwise_filter:4-D的 Tensor,形如[filter_height, filter_width, >in_channels, channel_multiplier]。是深度卷積的卷積核。
pointwise_filter:4-D的Tensor,形如[1, 1, channel_multiplier * in_channels, out_channels]。是1×1卷積的卷積核。
strides:1-D Tensor,大小是4。深度卷積的滑動步長。
padding:邊緣填充方式,string類型,值為VALID或SAME。
rate:1-D Tensor,大小是2。與實現(xiàn)空洞卷積相關(guān)的參數(shù)。
函數(shù)實現(xiàn)上,先通過with_space_to_batch接口進(jìn)行depth-wise卷積,再調(diào)用conv2d進(jìn)行1×1的卷積,最后返回4-D的輸出Tensor。
MACE 中 depthwise separable convolutions 的實現(xiàn)
小米的MACE框架中,并沒有depthwise separable convolutions的直接接口,但是有深度卷積(depthwise convolutions)的接口,在mace\kernel\depthwise_conv2d.h 中。
CPU版本的代碼對于卷積和為(3,3),stride大小為(1,1)或(2,2)會進(jìn)行NEON指令集加速,其他情況則通過DepthwiseConv2dGeneral接口實現(xiàn)。
參考:https://www.jianshu.com/p/38dc74d12fcf
總結(jié)
以上是生活随笔為你收集整理的深度可分离卷积(Xception 与 MobileNet)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 金庸小说人物关系表年表
- 下一篇: DNS服务搭建和正反区域解析