『高性能模型』卷積複雜度以及Inception系列

轉載自知乎:卷積神經網絡的複雜度分析html

以前的Inception學習博客:python

『TensorFlow』讀書筆記_Inception_V3_上網絡

『TensorFlow』讀書筆記_Inception_V3_下ide

1、時間複雜度

即模型的運算次數,可用FLOPs衡量,也就是浮點運算次數(FLoating-point OPerations)。post

單個卷積層的時間複雜度

      Time~O(M2·K2·Cin·Cout)學習

M:輸出特徵圖邊長優化

K:卷積核尺寸spa

C:通道數目3d

輸出邊長M計算公式爲:htm

      M = (X - K + 2*Padding)//Stride + 1

  • 注1:爲了簡化表達式中的變量個數,這裏統一假設輸入和卷積核的形狀都是正方形
  • 注2:嚴格來說每層應該還包含 1 個 Bias 參數,這裏爲了簡潔就省略了
  • 注3:TensorFlow中SAME形式輸出爲(X/Stride)上取整,由於TF中默認總共填充K/2,注意不須要進行2*Padding

下圖展現了單個Cout的上單個點的計算示意,須要重複計算:Cout·每張輸出特徵圖上像素數次。

卷積神經網絡總體複雜度

      Time~O(∑l=1 M2·K2·Cl-1·Cl)

l表示層編號,實質就是對各個層求和。

卷積層實現能夠很好的看清實現機理:out層、out長寬、in層循環,循環體內k2級別運算:

def conv2d(img, kernel):
    height, width, in_channels = img.shape
    kernel_height, kernel_width, in_channels, out_channels = kernel.shape
    out_height = height - kernel_height + 1
    out_width = width - kernel_width + 1
    feature_maps = np.zeros(shape=(out_height, out_width, out_channels))
    for oc in range(out_channels):              # Iterate out_channels (# of kernels)
        for h in range(out_height):             # Iterate out_height
            for w in range(out_width):          # Iterate out_width
                for ic in range(in_channels):   # Iterate in_channels
                    patch = img[h: h + kernel_height, w: w + kernel_width, ic]
                    feature_maps[h, w, oc] += np.sum(patch * kernel[:, :, ic, oc])

    return feature_maps

2、空間複雜度

空間複雜度(訪存量),嚴格來說包括兩部分:總參數量 + 各層輸出特徵圖。

  • 參數量:模型全部帶參數的層的權重參數總量(即模型體積,下式第一個求和表達式)
  • 特徵:模型在實時運行過程當中每層所計算出的輸出特徵圖大小(下式第二個求和表達式)

      Space~O(∑K2·Cl-1·Cl + ∑M2·Cl)

M:輸出特徵圖邊長

K:卷積核尺寸

C:通道數目

3、複雜度對模型的影響

時間複雜度決定了模型的訓練/預測時間。若是複雜度太高,則會致使模型訓練和預測耗費大量時間,既沒法快速的驗證想法和改善模型,也沒法作到快速的預測。

空間複雜度決定了模型的參數數量。因爲維度詛咒的限制,模型的參數越多,訓練模型所需的數據量就越大,而現實生活中的數據集一般不會太大,這會致使模型的訓練更容易過擬合。

當咱們須要裁剪模型時,因爲卷積核的空間尺寸一般已經很小(3x3),而網絡的深度又與模型的表徵能力緊密相關,不宜過多削減,所以模型裁剪一般最早下手的地方就是通道數

4、Inception系列優化思路

一、Inception_v1:1*1卷積降維同時優化時間複雜度和空間複雜度

InceptionV1 借鑑了 Network in Network 的思想,在一個 Inception Module 中構造了四個並行的不一樣尺寸的卷積/池化模塊(上圖左),有效的提高了網絡的寬度。可是這麼作也形成了網絡的時間和空間複雜度的激增。對策就是添加 1 x 1 卷積(上圖右紅色模塊)將輸入通道數先降到一個較低的值,再進行真正的卷積。

在3*3卷積分支上加入64個1*1卷積先後的時間複雜度對好比下式:

同理,在5*5卷積分支上加入64個1*1卷積先後的時間複雜度對好比下式:

整個層的參數量變化以下:

二、Inception_v1:使用GAP(全局平局均池化)代替全鏈接

全鏈接層複雜度分析:X*X的輸入Flatten爲X2的輸入,輸出神經元個數能夠視爲1*1*Cout,則:

      Time~O(12·X2·Cin·Cout)

      Space~O(X2·Cin·Cout + X2·Cin) ~ O(X2·Cin·Cout)

空間複雜度第一部分爲權重參數,第二部分爲當前輸入大小。順便一提我以前的一個誤區:全鏈接層相對卷積層其運算瓶頸不在時間複雜度,而在空間複雜度,我以前的印象裏把二者混爲一談了。

使用GAP後,首先將Cin·X2的輸入轉化爲Cin,而後1*1卷積爲Cout

      Time~O(Cin·Cout)

      Space~O(Cin·Cout + Cin)~ O(Cin·Cout)

Space來講可能有點問題:Cin·X2的原輸入應該仍是要存儲的,不過因爲不涉及到卷積運算,姑且不細究。

可是注意:GAP會影響收斂速度,不過並不會影響最終的精度。

三、Inception_v2:兩個3*3卷積聯級替代5*5卷積

兩個3*3卷積聯級的感覺野與單個5*5卷積至關,計算公式可見『計算機視覺』感覺野和anchor,替換後時間複雜度卻可下降:

四、Inception_v3:使用N*1和1*N卷積聯級代替N*N卷積

 

InceptionV3 中提出了卷積的 Factorization,在確保感覺野不變的前提下進一步簡化,複雜度的改善同理可得,再也不贅述。

五、Xnception:使用Depth wise Separable Convolution

Xception 中每一個輸入通道只會被對應的一個卷積核掃描,下降了模型的冗餘度對於深度可分離卷積Depthwise Separable 是一個 Depthwise conv 加一個 Pointwise conv,其中 Depthwise 是M2·K2·Cin,Pointwise 是M2·Cin·Cout,即:

      Time~O(M2·K2·Cin + M2·Cin·Cout)

相關文章
相關標籤/搜索