天天看點

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結

性能提升方法

本文github連結

1. 小模型 mobilenet , 更精細模型的設計,緊緻網絡設計
   mobilenet squeezenet shufflenet 
           

MobileNet逐通道卷積 + 普通點卷積

SqueezeNet 1∗1 和3∗3 卷積較少通道數量

ShuffleNet 分組點卷積+通道重排+逐通道卷積

2. 模型壓縮:參數稀疏、剪裁、量化、分解
   本部分
           

量化

剪枝

3. 軟體優化-高性能計算 
   騰訊 ncnn 小米mace 百度MDL Google TensorFlow Lite
           

高性能計算

4. 硬體優化-AI晶片
   TPU
   FPGA上的應用
   賽靈思Xilinx
   暫時未涉及
           

利用 賽靈思Xilinx 器件的INT8優化開展深度學習

Binarized Neural Network TF training code + C matrix / eval library 量化網絡架構

Model Compression and Model Acceleration in TensorLayer

如果想把參數壓縮方案和其他一些方案結合,
比如上面提到的一些 SqueezeNet,MobileNets,ShuffleNet 結合起來,會對準确率造成比較大的影響。
原因可以歸為參數壓縮算法其實是一個找次優解的問題,當網絡備援度越小,解越不好找。
是以,目前的高精度壓縮算法隻适合于傳統的有很多備援的網絡。
           

AI晶片

Efficient Processing of Deep Neural Networks: A Tutorial and Survey

由于目前基于 PC 平台的神經網絡加速一定程度上不能滿足需要,
    開發基于硬體例如 FPGA 的硬體加速平台顯得很有必要。
    其實硬體加速神經網絡前向運算的最主要的任務就是完成卷積優化,
    減少卷積運算的資源和能源消耗非常核心。
           

卷積優化的主要思路

1. 記憶體換取時間:

如果深度學習中每一層的卷積都是針對同一張圖檔,
那麼所有的卷積核可以一起對這張圖檔進行卷積運算,
然後再分别存儲到不同的位置,這就可以增加記憶體的使用率,
一次加載圖檔,産生多次的資料,而不需要多次通路圖檔,
這就是用記憶體來換時間。
           

2. 乘法優化:

以下圖為例,上面是兩張圖檔,右邊是卷積核。
我們可以把卷積核心展開成一條行,然後多個卷積核就可以排列成多行,
再把圖像也用類似的方法展開,就可以把一個卷積問題轉換成乘法問題。
這樣就是一行乘以一列,就是一個結果了。
這樣雖然多做了一些展開的操作,
但是對于計算來講,速度會提升很多。
           

3. GPU優化:

1. 了解 IO 通路的情況以及 IO 的性能;

2. 多線程的并行計算特性;

3. IO 和并行計算間的計算時間重疊。

對于 NVIDIA 的 GPU 來講,記憶體通路是有一些特性的,
連續合并通路可以很好地利用硬體的帶寬。
你可以看到,NVIDIA 最新架構的 GPU,其核心數目可能并沒有明顯增加,
架構似乎也沒有太大變化,但在幾個計算流處理器中間增加緩存,
就提高了很大的性能,為 IO 通路這塊兒帶來了很大優化。  
           

4. 卷積計算優化

目前,卷積的計算大多采用間接計算的方式,主要有以下三種實作方式:

1、im2col + GEMM。
   caffe等很多架構中都使用了這種計算方式,
   原因是将問題轉化為矩陣乘法後可以友善的使用很多矩陣運算庫(如MKL、openblas、Eigen等)。
2、FFT變換。 
   時域卷積等于頻域相乘,是以可将問題轉化為簡單的乘法問題。
3、Winograd。 
   這種不太熟悉,據說在GPU上效率更高。 
   NNPACK就是FFT和Winograd方法的結合。
   
上面三種方法執行效率都還不錯,但對記憶體占用比較高,因為需要存儲中間結果或者臨時輔助變量。


1、Strassen 算法:
分析 CNN 的線性代數特性,增加加法減少乘法,
這樣降低了卷積運算的計算的複雜度(o(n^3) -> o(n^2.81)),
但是這種方法不适合在硬體裡面使用,這裡就不做詳細的介紹了。

2、 MEC:
一種記憶體使用率高且速度較快的卷積計算方法
           

MEC: Memory-efficient Convolution for Deep Neural Network 論文

部落格解析

5. 卷積中的資料重用

在軟體中的卷積運算,其實我們是在不斷的讀取資料,進行資料計算。
也就是說卷積操作中資料的存取其實是一個很大的浪費,
卷積操作中資料的重用如下圖所示.

那麼想辦法減少資料的重用,減少資料的存取成為解決卷積計算問題的一個很重要的方面。
目前這樣的方法有很多種,最主要的方法包括以下幾種:

    權重固定:最小化權重讀取的消耗,最大化卷積和卷積核權重的重複使用;
    輸出固定:最小化部分和 R/W 能量消耗,最大化本地積累;
    NLR (No Local Reuse):使用大型全局緩沖區共享存儲,減少 DRAM 通路能耗;
    RS:在内部的寄存器中最大化重用和累加,針對整體能源效率進行優化,而不是隻針對某種資料類型。
    下表是在 45NM CMOS 的基礎上對于不同的操作的能耗進行的統計。
    對 32 位的各種操作的能耗進行統計,可以看到從 DRAM 裡面存取資料的能量消耗是最大的。
    是 32 位整型資料進行加法的能量消耗的 6400 倍。
    那麼,從資料存取角度考慮卷積的優化就顯得尤為必要了。
           

可行性分析

在 GPU 中加速時,主要通過将資料最大程度的并行運算,
增加了 GPU 的使用率進而加快了速度。
但是這種方法在硬體實作的時候是不可行的,因為這種方法本質上沒有降低能耗,
而 DNN 模型的高能耗和大量的資料是其在可穿戴裝置上面進行部署所需要面對的困難。
下面對一個卷積部分和運算進行分析,如下圖 :
    對第一組的 PE 整列,輸入的是從 Image 的第 0 行到第 R-1 行的 S 列的資料,
    同樣的對于第二列的 PE 陣列輸入的是第 2 行到第 R 的 S 列的資料。
    每一列的 PE 計算得到一個最終的 Psum 的結果,那麼如果設定 PE 陣列的列數為 N 的話,
    每次我們就可以計算得到連續的 N 個部分和的結果。

    不斷更新 PE(process element,即處理單元)中 Image 緩沖區的資料,
    就可以模拟卷積在水準方向上面的滑動,不斷更新整個 PE 陣列的資料輸入,
    就可以模拟卷積窗在垂直方向上面的滑動,最終完成整個卷積運算的實作。

    對應的卷積運算公式的細節在圖中已經給出了,每一組 PE 産生一個部分和的結果的話,
    那麼增加 PE 陣列的組數,就可以一次性産生多個部分和計算結果,這裡的組數就是并行度。

    上面的内容簡單論證用資料重用的方式實作卷積運算的可行性,
    至于實作的具體資料流,還有相對用的系統的架構。
           

壓縮算法在實際硬體晶片的應用

其實壓縮算法應用硬體晶片非常簡單,就是簡單的将硬體晶片原來使用的乘法器進行替換,
如果是 BNN,參數隻有兩種情形,
那麼如果參數為 1 的時候,直接通過,
不計算,如果參數為 -1 的時候,翻轉最高位即可。

同理三值化中增加了一個 0 參數,這個可以直接跳過不進行計算。
至于參數為(-2,-1,0,1,2)的情形,參數為 2 時就增加了一個移位運算,
參數為 -2 的時候增加了一個最高位的翻轉。

如果是 DoReFaNet,權值和輸出都固定在一定的種類内部,那麼他們的乘積情形也隻有一定的種類,
這個時候相當于把乘法器變成了一個尋址操作,
每次乘法隻需要在 LUT(look-up table,查找表)裡面尋找到正确的結果讀出即可。
           

模型壓縮

中科院自動化研究所

DeepCompression-caffe

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結

超全總結:神經網絡加速之量化模型 | 附帶代碼

量化模型(Quantized Model)是一種模型加速(Model Acceleration)方法的總稱,
包括二值化網絡(Binary Network)、
三值化網絡(Ternary Network)、
深度壓縮(Deep Compression)、
多比例量化等
           

為什麼要壓縮網絡?

做過深度學習的應該都知道,NN大法确實效果很贊,
在各個領域輕松碾壓傳統算法,
不過真正用到實際項目中卻會有很大的問題:

計算量非常巨大;
模型特别吃記憶體;

這兩個原因,使得很難把NN大法應用到嵌入式系統中去,
因為嵌入式系統資源有限,而NN模型動不動就好幾百兆。
是以,計算量和記憶體的問題是作者的motivation;
           

如何壓縮?

論文題目已經一句話概括了:
    Prunes the network:隻保留一些重要的連接配接;
    Quantize the weights:通過權值量化來共享一些weights;
    Huffman coding:通過霍夫曼編碼進一步壓縮;
           

效果如何?

Pruning:把連接配接數減少到原來的 1/13~1/9; 
Quantization:每一個連接配接從原來的 32bits 減少到 5bits;
           

最終效果:

- 把AlextNet壓縮了35倍,從 240MB,減小到 6.9MB; 
- 把VGG-16壓縮了49北,從 552MB 減小到 11.3MB; 
- 計算速度是原來的3~4倍,能源消耗是原來的3~7倍;
           

網絡壓縮(network compression)

盡管深度神經網絡取得了優異的性能,
但巨大的計算和存儲開銷成為其部署在實際應用中的挑戰。
有研究表明,神經網絡中的參數存在大量的備援。
是以,有許多工作緻力于在保證準确率的同時降低網路複雜度。
           

0、訓練時對參數的更新進行限制,使其趨向于稀疏.

核參數稀疏: 是在訓練過程中,對參數的更新進行限制,使其趨向于稀疏.
                對于稀疏矩陣,可以使用更加緊緻的存儲方式,如CSC,
                但是使用稀疏矩陣操作在硬體平台上運算效率不高,
                容易受到帶寬的影響,是以加速并不明顯。 

    在訓練過程中,對權重的更新加以正則項進行誘導,使其更加稀疏,使大部分的權值都為0。
    http://papers.nips.cc/paper/6504-learning-structured-sparsity-in-deep-neural-networks.pdf
    
    動态的模型裁剪方法
    https://arxiv.org/pdf/1608.04493.pdf
    
    包括以下兩個過程:pruning和splicing,其中pruning就是将認為不中要的weight裁掉,
    但是往往無法直覺的判斷哪些weight是否重要,
    是以在這裡增加了一個splicing的過程,
    将哪些重要的被裁掉的weight再恢複回來,
    類似于一種外科手術的過程,将重要的結構修補回來。
    作者通過在W上增加一個T來實作,T為一個2值矩陣,起到的相當于一個mask的功能,
    當某個位置為1時,将該位置的weight保留,為0時,裁剪。
    在訓練過程中通過一個可學習mask将weight中真正不重要的值剔除,進而使得weight變稀疏。
    
    特點:
         核的稀疏化可能需要一些稀疏計算庫的支援,其加速的效果可能受到帶寬、稀疏度等很多因素的制約;
           

1、低秩近似 (低秩分解 Low Rank Expansion)

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
上圖展示了低秩分解的基本思想:
    将原來大的權重矩陣分解成多個小的矩陣,
    右邊的小矩陣的計算量都比原來大矩陣的計算量要小,
    這是低秩分解的基本出發點。

 奇異值分解SVD、CP分解、Tucker分解、Tensor Train分解和Block Term分解
 
 用低秩矩陣近似原有權重矩陣。
 例如,可以用SVD得到原矩陣的最優低秩近似,
 或用Toeplitz矩陣配合Krylov分解近似原矩陣。

    SVD分解:
    全連接配接層的權重矩陣記作 W∈Rm×n ,首先對 W 進行 SVD 分解,如下:

    W=USV轉置
    為了能夠用兩個較小的矩陣來表示 W ,我們可以取奇異值的前 K 個分量。
    于是,W可以通過下式重建:

    W^=U^S^V^T,其中U^∈Rm×kV^∈Rn×k
    我們唯一需要儲存的就是3個比較小的矩陣 U,S,V ,我們可以簡單算一下壓縮比為 mn/k(m+n+1)


矩陣的秩概念上就是線性獨立的縱列(或者橫列)的最大數目。
行秩和列秩線上性代數中可以證明是相等的,例如:
    3*3的矩陣如下,則 行秩==列秩==秩==3
    1 2 3
    4 5 6
    7 8 9

    1*3的矩陣如下,則 行秩==列址==秩==1
    [1 2 3] 
    3*1的矩陣如下,則 行秩==列址==秩==1
    [1] [2] [3] 
    
低秩分解,這個名字雖然唬人,
實際上就是把較大的卷積核分解為兩個級聯的行卷積核和列卷積核。
常見的就是一個3*3的卷積層,替換為一個3*1的卷積層加上一個1*3的卷積核。
容易計算得,
一個特征圖10*10,經過3*3卷積核後得到8*8的特征圖輸出,
而替換為低秩後,
則先得到10*8的特征圖然後再得到8*8的特征圖。    


另外現在越來越多網絡中采用1×1的卷積,
而這種小的卷積使用矩陣分解的方法很難實作網絡加速和壓縮。
           

a、奇異值分解svd

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
上圖是微軟在2016年的工作,将卷積核矩陣先做成一個二維的矩陣,再做SVD分解。
上圖右側相當于用一個R的卷積核做卷積,再對R的特征映射做深入的操作。
從上面可以看到,雖然這個R的秩非常小,但是輸入的通道S還是非常大的。
           

b、Tucker分解 解決SVD分解中輸入的通道S大的問題

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
為了解決SVD分解過程中通道S比較大的問題,
我們從另一個角度出發,沿着輸入的方向對S做降維操作,這就是上圖展示的Tucker分解的思想。
具體操作過程是:
   原來的卷積,首先在S次元上做一個低維的表達,
   再做一個正常的3×3的卷積,
   最後再做一個升維的操作。
           

c、CP分解加速神經網絡的方法

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
在SVD分解和Tucker分解之後的一些工作主要是做了更進一步的分解。
上圖展示了使用微調的CP分解加速神經網絡的方法。
在原來的四維張量上,在每個次元上都做類似1×1的卷積,轉
化為第二行的形式,在每一個次元上都用很小的卷積核去做卷積。
在空間次元上,大部分都是3×3的卷積,是以空間的次元很小,可以轉化成第三行的形式,
在輸入和輸出通道上做低維分解,但是在空間次元上不做分解,類似于MobileNet。
           

d、塊分解

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
結合了上述兩種分解方法各自的優勢。首先把輸入參數做降維,
然後在第二個卷積的時候,做分組操作,這樣可以降低第二個3×3卷積的計算量,最後再做升維操作。
另一方面由于分組是分塊卷積,它是有結構的稀疏,是以在實際中可以達到非常高的加速,
我們使用VGG網絡在手機上的實驗可以達到5-6倍的實際加速效果。
           

LBCNN 局部二值卷積 卷積稀疏濾波器

LBCNN 參考

代碼

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結

2、剪枝(pruning) 在訓練結束後,可以将一些不重要的神經元連接配接

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
非結構化剪枝Pruning,結構化剪枝Filter Pruning,梯度Pruning等方法

(可用權重數值大小衡量配合損失函數中的稀疏限制)或整個濾波器去除,
之後進行若幹輪微調。實際運作中,神經元連接配接級别的剪枝會
使結果變得稀疏,
不利于緩存優化和記憶體通路,有的需要專門設計配套的運作庫。
相比之下,濾波器級别的剪枝可直接運作在現有的運作庫下,
而濾波器級别的剪枝的關鍵是如何衡量濾波器的重要程度。
例如,可用卷積結果的稀疏程度、該濾波器對損失函數的影響、
或卷積結果對下一層結果的影響來衡量。

特别地,由于計算稀疏矩陣在CPU和GPU上都有特定的方法,是以前向計算也需要對一些部分進行代碼修改。
GPU上計算稀疏需要調用cuSPARSE庫,
而CPU上計算稀疏需要mkl_sparse之類的庫去優化稀疏矩陣的計算,
否則達不到加速效果.

剪枝方法基本流程如下:
    1. 正常流程訓練一個神經網絡。以CAFFE為例,就是普普通通地訓練出一個caffemodel。
    2. 确定一個需要剪枝的層,一般為全連接配接層,設定一個裁剪門檻值或者比例。
        實作上,通過修改代碼加入一個與參數矩陣尺寸一緻的mask矩陣。
        mask矩陣中隻有0和1,實際上是用于重新訓練的網絡。
    3. 重新訓練微調,參數在計算的時候先乘以該mask,則mask位為1的參數值将繼續訓練通過BP調整,
       而mask位為0的部分因為輸出始終為0則不對後續部分産生影響。
    4. 輸出模型參數儲存的時候,因為有大量的稀疏,是以需要重新定義儲存的資料結構,
       僅儲存非零值以及其矩陣位置。重新讀取模型參數的時候,就可以還原矩陣。
           

a、非結構化剪枝

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
上圖展示了在NIP2015上提出的非常經典的三階段剪枝的方法。

首先訓練一個全精度網絡,
随後删除一些不重要的節點,
後面再去訓練權重。

這種非結構化的剪枝的方法,雖然它的理論計算量可以壓縮到很低,
但是收益是非常低的,比如在現在的CPU或者GPU架構下很難達到非常高的加速效果。
是以下面這種結構化的剪枝技術越來越多。
           

b、結構化剪枝

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
從去年的ICCV就有大量基于channel sparsity的工作。
上面是其中的一個示意圖,相當于對每一個feature map定義其重要性,
把不重要的給删除掉,這樣産生的稀疏就是有規則的,
我們可以達到非常高的實際加速效果。
           

3、量化(quantization)。對權重數值進行聚類,

量化的思想非常簡單。
CNN參數中數值分布在參數空間,
通過一定的劃分方法,
總是可以劃分稱為k個類别。
然後通過儲存這k個類别的中心值或者映射值進而壓縮網絡的儲存。

量化可以分為
Low-Bit Quantization(低比特量化)、
Quantization for General Training Acceleration(總體訓練加速量化)和
Gradient Quantization for Distributed Training(分布式訓練梯度量化)。

由于在量化、特别是低比特量化實作過程中,
由于量化函數的不連續性,在計算梯度的時候會産生一定的困難。
對此,阿裡巴巴冷聰等人把低比特量化轉化成ADMM可優化的目标函數,進而由ADMM來優化。

從另一個角度思考這個問題,使用哈希把二值權重量化,再通過哈希求解.

用聚類中心數值代替原權重數值,配合Huffman編碼,
具體可包括标量量化或乘積量化。
但如果隻考慮權重自身,容易造成量化誤差很低,
但分類誤差很高的情況。
是以,Quantized CNN優化目标是重構誤差最小化。
此外,可以利用哈希進行編碼,
即被映射到同一個哈希桶中的權重共享同一個參數值。

聚類例子:
    例如下面這個矩陣。

    1.2  1.3  6.1
    0.9  0.7  6.9
    -1.0 -0.9 1.0
    設定類别數k=3,通過kmeans聚類。得到:
    A類中心: 1.0 , 映射下标: 1
    B類中心: 6.5 , 映射下标: 2
    C類中心: -0.95 , 映射下标: 3

    是以儲存矩陣可以變換為(距離哪個中心近,就用中心的下标替換):
    1  1  2
    1  1  2
    3  3  1
    當然,論文還提出需要對量化後的值進行重訓練,挽回一點丢失的識别率 
    基本上所有壓縮方法都有損,是以重訓練還是比較必要的。

Huffman編碼筆者已經不太記得了,好像就是高頻值用更少的字元儲存,低頻則用更多。
           

4、降低資料數值範圍。 其實也可以算作量化

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
預設情況下資料是單精度浮點數,占32位。
有研究發現,
改用半精度浮點數(16位)幾乎不會影響性能。
谷歌TPU使用8位整型來表示資料。
極端情況是數值範圍為 二值(0/1) 或 三值 (-1/0/1),
這樣僅用位運算即可快速完成所有計算,
但如何對二值或三值網絡進行訓練是一個關鍵。
通常做法是網絡前饋過程為二值 或 三值,
梯度更新過程為實數值。
           

5、遷移學習 Knowledge Distillation

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
在Knowledge Distillation中有兩個關鍵的問題,
一是如何定義知識,
二是使用什麼損失函數來度量student網絡和teacher 網絡之間的相似度。

通過訓練一個更大的神經網絡模型,再逐漸剪枝得到的小模型取得的結果要比直接訓練這樣一個小模型的結果好得多。
           

已訓練好的模型上做裁剪

這種就是在訓練好的模型上做一些修改,
然後在fine-tuning到原來的準确率,
主要有一些方法:
1、剪枝:神經網絡是由一層一層的節點通過邊連接配接,每個邊上會有權重,
        所謂剪枝,就是當我們發現某些邊上的權重很小,
        可以認為這樣的邊不重要,進而可以去掉這些邊。
        在訓練的過程中,在訓練完大模型之後,
        看看哪些邊的權值比較小,把這些邊去掉,然後繼續訓練模型;
2、權值共享:就是讓一些邊共用一個權值,達到縮減參數個數的目的。
            假設相鄰兩層之間是全連接配接,每層有1000個節點,
            那麼這兩層之間就有1000*1000=100萬個權重參數。
            可以将這一百萬個權值做聚類,利用每一類的均值代替這一類中的每個權值大小,
            這樣同屬于一類的很多邊共享相同的權值,假設把一百萬個權值聚成一千類,則可以把參數個數從一百萬降到一千個。
3、量化:一般而言,神經網絡模型的參數都是用的32bit長度的浮點型數表示,
        實際上不需要保留那麼高的精度,可以通過量化,
        比如用0~255表示原來32個bit所表示的精度,
        通過犧牲精度來降低每一個權值所需要占用的空間。
4、神經網絡二值化:比量化更為極緻的做法就是神經網絡二值化,
                 也即将所有的權值不用浮點數表示了,
                 用二進制的數表示,要麼是+1,要麼是-1,用二進制的方式表示,
                 原來一個32bit權值現在隻需要一個bit就可以表示,
                 可以大大減小模型尺寸。
           

Deep Compression 方法,包含

裁剪,
量化,
編碼 三個手段。
           

模型參數分析:

網絡中全連層參數和卷積層weight占絕大多數,
卷積層的bias隻占極小部分。
而參數分布在0附近,近似高斯分布。
參數壓縮針對卷積層的weight和全連層參數。每一層的參數單獨壓縮。
           

1. 剪枝(pruning)

Lecun老爺子的OBD可以将網絡中不重要的參數剔除

模型的裁剪方法則比較簡單明了,直接在原有的模型上剔除掉不重要的filter,
雖然這種壓縮方式比較粗糙,但是神經網絡的自适應能力很強,
加上大的模型往往備援比較多,将一些參數剔除之後,
通過一些retraining的手段可以将由剔除參數而降低的性能恢複回來,
是以隻需要挑選一種合适的裁剪手段以及retraining方式,
就能夠有效的在已有模型的基礎上對其進行很大程度的壓縮,是目前使用最普遍的方法。


基于模型裁剪的方法: 

       對以訓練好的模型進行裁剪的方法,是目前模型壓縮中使用最多的方法,
       通常是尋找一種有效的評判手段,來判斷參數的重要性,
       将不重要的connection或者filter進行裁剪來減少模型的備援。
           

a. 門檻值剪裁

基于模型裁剪的方法

pruning可以分為三步: 
step1. 正常訓練模型得到網絡權值; 
step2. 将所有低于一定門檻值的權值設為0; 
step3. 重新訓練網絡中剩下的非零權值。 

截止濾波後的稀疏矩陣:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
0很多,直接存儲矩陣太浪費,采用CSR 存儲方式
記錄非零值 以及非零值的 索引,

CSR可以将原始矩陣表達為三部分,即AA,JA,IC 
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
AA是矩陣A中所有非零元素,長度為a,即非零元素個數; 
JA是矩陣A中每行第一個非零元素在AA中的位置,最後一個元素是非零元素數加1,長度為n+1, n是矩陣A的行數;  
IC是AA中每個元素對應的列号,長度為a。 
是以将一個稀疏矩陣轉為CSR表示,需要的空間為2*a+n+1個,同理CSC也是類似。 
           

caffe-python 剪枝 執行個體

b.基于量級的裁剪方式

相關論文

基于量級的裁剪方式,用weight值的大小來評判其重要性,
對于一個filter,其中所有weight的絕對值求和,後通過排序來區分重要性。
來作為該filter的評價名額,
将一層中值低的filter裁掉,
可以有效的降低模型的複雜度并且不會給模型的性能帶來很大的損失.
https://arxiv.org/pdf/1608.08710.pdf

作者在裁剪的時候同樣會考慮每一層對裁剪的敏感程度,作者會單獨裁剪每一層來看裁剪後的準确率。
對于裁剪較敏感的層,作者使用更小的裁剪力度,或者跳過這些層不進行裁剪。
目前這種方法是實作起來較為簡單的,并且也是非常有效的,
它的思路非常簡單,就是認為參數越小則越不重要。
           

c.統計filter中激活為0的值的數量作為标準

論文參考

作者認為,在大型的深度學習網絡中,大部分的神經元的激活都是趨向于零的,
而這些激活為0的神經元是備援的,将它們剔除可以大大降低模型的大小和運算量,
而不會對模型的性能造成影響,于是作者定義了一個量APoZ(Average Percentage of Zeros)
來衡量每一個filter中激活為0的值的數量,來作為評價一個filter是否重要的标準。
           

d.基于熵值的剪裁

論文參考

作者認為通過weight值的大小很難判定filter的重要性,
通過這個來裁剪的話有可能裁掉一些有用的filter。
是以作者提出了一種基于熵值的裁剪方式,利用熵值來判定filter的重要性。 
作者将每一層的輸出通過一個Global average Pooling,
将feature map 轉換為一個長度為c(filter數量)的向量,
對于n張圖像可以得到一個n*c的矩陣,
對于每一個filter,将它分為m個bin,統計每個bin的機率pi,
然後計算它的熵值,利用熵值來判定filter的重要性,再對不重要的filter進行裁剪。
第j個feature map熵值的計算方式如下: 

Hj = -sum(pi*log(pi))

在retrain中,作者使用了這樣的政策,即每裁剪完一層,通過少數幾個疊代來恢複部分的性能,
當所有層都裁剪完之後,再通過較多的疊代來恢複整體的性能,
作者提出,在每一層裁剪過後隻使用很少的訓練步驟來恢複性能,
能夠有效的避免模型進入到局部最優。
           

e.基于能量效率的裁剪方式

論文參考

作者認為以往的裁剪方法,都沒有考慮到模型的帶寬以及能量的消耗,
是以無法從能量使用率上最大限度的裁剪模型,是以提出了一種基于能量效率的裁剪方式。
作者指出一個模型中的能量消耗包含兩個部分,一部分是計算的能耗,一部分是資料轉移的能耗,
在作者之前的一片論文中(與NVIDIA合作,Eyeriss),提出了一種估計硬體能耗的工具,
能夠對模型的每一層計算它們的能量消耗。然後将每一層的能量消耗從大到小排序,
對能耗大的層優先進行裁剪,這樣能夠最大限度的降低模型的能耗,對于需要裁剪的層,
根據weight的大小來選擇不重要的進行裁剪,同樣的作者也考慮到不正确的裁剪,
是以将裁剪後模型損失最大的weight保留下來。 

每裁剪完一層後,對于該層進行locally的fine-tune,locally的fine-tune,
是在每一層的filter上,使用最小二乘優化的方法來使裁剪後的filter
調整到使得輸出與原始輸出盡可能的接近。在所有層都裁剪完畢後,
再通過一個global的finetuning來恢複整體的性能。
           

f.遺傳算法思想,随機剪裁,選擇效果好的

論文參考

作者認為,既然我無法直覺上的判定filter的重要性,
那麼就采取一種随機裁剪的方式,然後對于每一種随機方式統計模型的性能,來确定局部最優的裁剪方式。 
這種随機裁剪方式類似于一個随機mask,假設有M個潛在的可裁剪weight,那麼一共就有2^M個随機mask。
假設裁剪比例為a,那麼每層就會随機選取ML*a個filter,一共随機選取N組組合,
然後對于這N組組合,統計裁剪掉它們之後模型的性能,
然後選取性能最高的那組作為局部最優的裁剪方式。
           

g.基于icc組内相關來衡量filter的重要性

論文參考

作者發現,在最後一個卷積層中,經過LDA分析發現對于每一個類别,
有很多filter之間的激活是高度不相關的,
是以可以利用這點來剔除大量的隻具有少量資訊的filter而不影響模型的性能。 
作者在VGG-16上進行實驗,VGG-16的conv5_3具有512個filter,
将每一個filter的輸出值中的最大值定義為該filter的fire score,
是以對應于每一張圖檔就具有一個512維的fire向量,當輸入一堆圖檔時,
就可以得到一個N*512的fire矩陣,作者用intra-class correlation來衡量filter的重要性: 

作者這樣做的目的是通過隻保留對分類任務提取特征判别性最強的filter,來降低模型的備援。
           

h.基于神經元激活相關性的重要性判别方法

論文參考

作者認為,如果一層中的某個神經元的激活與上一層的某個神經元的激活有很強的相關性,
那麼這個神經元對于後面層的激活具有很強的判别性。
也就是說,如果前後兩層中的某對神經元的激活具有較高的相關性,
那麼它們之間的連接配接weight就是非常重要的,而弱的相關性則代表低的重要性。
如果某個神經元可以視為某個特定視覺模式的探測器,那麼與它正相關的神經元也提供了這個視覺模式的資訊,
而與它負相關的神經元則幫助減少誤報。作者還認為,那些相關性很低的神經元對,
它們之間的連接配接不一定是一點用也沒有,它們可能是對于高相關性神經元對的補充。
           

i.将裁剪問題當做一個組合優化問題

論文參考

作者将裁剪問題當做一個組合優化問題:從衆多的權重參數中選擇一個最優的組合B,使得被裁剪的模型的代價函數的損失最小.
這類似于Oracle pruning的方式,即通過将每一個weight單獨的剔除後看模型損失函數的衰減,
将衰減最少的參數認為是不重要的參數,可以剔除,這也是OBD的思路,但是OBD的方法需要求二階導數,
實作起來難度較大,而本文提出的Taylor expansion的方法可以很好的解決這個問題.
           

j. 一種基于Hessian矩陣的網絡修剪算法

論文參考

參考博文

OBS算法是一種基于Hessian矩陣的網絡修剪算法,首先,構造誤差曲面的一個局部模型,分析權值的擾動所造成的影響。 
           

通過對誤差函數進行Taylor展開

可以得到 與二階導數 海塞矩陣H相關的一個式子

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
1.OBS算法的全稱為optimal brain surgeon,翻譯成中文就是最優外科手術,表面的意思就是該方法是和神經網絡過程是分開的。 
2.該方法是一種架構,隻要是模型能求出參數的梯度,那麼都可用這個方法進行稀疏化。 
           

2. 量化(Quantization)

對象:對權重量化,對特征圖量化(神經元輸出),對梯度量化(訓練過程中)
過程:在inference網絡前傳,在訓練過程(反傳)
一步量化(僅對權重量化),
兩步量化(對神經元與特征圖量化,第一步先對feature map進行量化,第二步再對權重量化)

32位浮點和16位浮點存儲的時候,
第一位是符号位,中間是指數位,後面是尾數。
英特爾在NIPS2017上提出了把前面的指數項共享的方法,
這樣可以把浮點運算轉化為尾數的整數定點運算,進而加速網絡訓練。
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
分布式訓練梯度量化:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
在很多深度學習訓練過程中,為了讓訓練更快往往會用到分布式計算。
在分布式計算過程中有一個很大問題,
每一個分布式伺服器都和中心伺服器節點有大量的梯度資訊傳輸過程,進而造成帶寬限制。
這篇文章采取把要傳輸的梯度資訊量化為三值的方法來有效加速分布式計算。
           

聚類量化,降低記憶體消耗,但不能降低計算消耗

代碼參考

為了進一步壓縮網絡,考慮讓若幹個權值共享同一個權值,
這一需要存儲的資料量也大大減少。
在論文中,采用kmeans算法來将權值進行聚類,
在每一個類中,所有的權值共享該類的聚類質心,
是以最終存儲的結果就是一個碼書和索引表。

1.對權值聚類 
    論文中采用kmeans聚類算法,
    通過優化所有類内元素到聚類中心的差距(within-cluster sum of squares )來确定最終的聚類結果.
    
2. 聚類中心初始化 

    常用的初始化方式包括3種: 
    a) 随機初始化。
       即從原始資料種随機産生k個觀察值作為聚類中心。 

    b) 密度分布初始化。
       現将累計機率密度CDF的y值分布線性劃分,
       然後根據每個劃分點的y值找到與CDF曲線的交點,再找到該交點對應的x軸坐标,将其作為初始聚類中心。 

    c) 線性初始化。
        将原始資料的最小值到最大值之間的線性劃分作為初始聚類中心。 

    三種初始化方式的示意圖如下所示: 
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
由于大權值比小權值更重要(參加HanSong15年論文),
而線性初始化方式則能更好地保留大權值中心,
是以文中采用這一方式,
後面的實驗結果也驗證了這個結論。 

3. 前向回報和後項傳播 
    前向時需要将每個權值用其對應的聚類中心代替,
    後向計算每個類内的權值梯度,
    然後将其梯度和反傳,
    用來更新聚類中心,
    如圖: 
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
共享權值後,就可以用一個碼書和對應的index來表征。
    假設原始權值用32bit浮點型表示,量化區間為256,
    即8bit,共有n個權值,量化後需要存儲n個8bit索引和256個聚類中心值,
    則可以計算出壓縮率compression ratio: 
        r = 32*n / (8*n + 256*32 )≈4 
        可以看出,如果采用8bit編碼,則至少能達到4倍壓縮率。
           

通過減少精度的方法來優化網絡的方法總結

2. 二值量化網絡

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
上圖是在定點表示裡面最基本的方法:BNN和BWN。
在網絡進行計算的過程中,可以使用定點的資料進行計算,
由于是定點計算,實際上是不可導的,
于是提出使用straight-through方法将輸出的估計值直接傳給輸入層做梯度估計。
在網絡訓練過程中會儲存兩份權值,用定點的權值做網絡前向後向的計算,
整個梯度累積到浮點的權值上,整個網絡就可以很好地訓練,
後面幾乎所有的量化方法都會沿用這種訓練的政策。
前面包括BNN這種網絡在小資料集上可以達到跟全精度網絡持平的精度,
但是在ImageNet這種大資料集上還是表現比較差。
           

1. BCN & BNN 全二值網絡

Binarized Neural Networks BNN

BNN的激活量和參數都被二值化了, 反向傳播時使用全精度梯度。 
有确定性(sign()函數)和随機(基于機率)兩種二值化方式。
使用sign函數時,sign函數不可導,使用直通估計(straight-through estimator)(即将誤差直接傳遞到下一層): …. 
gr=gq1|r|≤1

BNN中同時介紹了基于移位(而非乘法)的BatchNormailze和AdaMax算法。 
實驗結果: 
在MNIST,SVHN和CIFAR-10小資料集上幾乎達到了頂尖的水準。 
在ImageNet在使用AlexNet架構時有較大差距(在XNOR-Net中的實驗Δ=29.8%) 
在GPU上有7倍加速
           

2. BWN(Binary-Weights-Networks) 僅有參數二值化了,激活量和梯度任然使用全精度

BWN(Binary-Weights-Networks)

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
上圖展示了ECCV2016上一篇名為XNOR-Net的工作,
其思想相當于在做量化的基礎上,乘了一個尺度因子,這樣大大降低了量化誤差。
他們提出的BWN,在ImageNet上可以達到接近全精度的一個性能,
這也是首次在ImageNet資料集上達到這麼高精度的網絡。
           

該網絡主要是對W 進行二值化,主要是一些數學公式的推導,公式推導如下:

對W進行二值化,使用 B 和縮放比例 a 來近似表達W
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
全精度權重W 和 權重二進制權重 aB 的誤差函數,求解縮放比例a和二值權重B,使得誤差函數值最小
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
誤差函數展開
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
二值權重B的求解,誤差最小,得到 W轉置*B最大
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
縮放比例a的求解,由全精度權重W求解得到
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結

3. XNOR-Net是BinaryNet的更新版

主要思想: 
    1. 二值化時增加了縮放因子,同時梯度函數也有相應改變:
    W≈W^=αB=1n∑|W|ℓ1×sign(W)
    ∂C∂W=∂C∂W^(1n+signWα)

    2. XNOR-Net在激活量二值化前增加了BN層 
    3. 第一層與最後一層不進行二值化 
實驗結果: 
    在ImageNet資料集AlexNet架構下,BWN的準确率有全精度幾乎一樣,XNOR-Net還有較大差距(Δ=11%) 
    減少∼32×的參數大小,在CPU上inference階段最高有∼58× 的加速。
           

**4. 量化網絡 nbit量化 **

QNN

代碼

對BNN的簡單擴充,
    量化激活函數,
    有線性量化與log量化兩種,
    其1-bit量化即為BinaryNet。
    在正向傳播過程中加入了均值為0的噪音。 
    BNN約差于XNOR-NET(<3%),
    QNN-2bit activation 略優于DoReFaNet 2-bit activation

激活函數量 線性量化:

    LinearQuant(x, bitwidth)= Clip(round(x/bitwidth)*bitwidth,  minV, maxV )

    激活函數為 整數階梯函數  
    最小值 minV
    最大值 maxV
    中間   線性階梯整數

log量化:

    LogQuant(x, bitwidth)、 = Clip (AP2(x), minV, maxV )

    AP2(x) = sign(x) × 2^round(log2|x|)
     平方近似
           

5. 限制低比特(3比特)量化 Extremely Low Bit Neural Networks

論文 Extremely Low Bit Neural Network: Squeeze the Last Bit Out with ADMM

翻譯

解析2

ADMM 算法了解 對原函數不好求解,轉而求解它的對偶函數,基于對對偶函數的優化,從來解出原問題

ADMM 算法實作

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
上圖展示了阿裡巴巴冷聰等人做的通過ADMM算法求解binary限制的低比特量化工作。
從凸優化的角度,在第一個優化公式中,f(w)是網絡的損失函數,
後面會加入一項W在集合C上的loss來轉化為一個優化問題。
這個集合C取值隻有正負1,如果W在滿足限制C的時候,它的loss就是0;
W在不滿足限制C的時候它的loss就是正無窮。
為了友善求解還引進了一個增廣變量,保證W是等于G的,
這樣的話就可以用ADMM的方法去求解。

提出一種基于低比特表示技術的神經網絡壓縮和加速算法。
我們将神經網絡的權重表示成離散值,
并且離散值的形式為 2 的幂次方的形式,比如 {-4,-2,-1,0,1,2,4}。
這樣原始 32 比特的浮點型權重可以被壓縮成 1-3 比特的整形權重,
同時,原始的浮點數乘法操作可以被定點數的移位操作所替代。
在現代處理器中,定點移位操作的速度和能耗是遠遠優于浮點數乘法操作的。

{-1,0,1 }, 三值網絡,存儲隻需要2bit,極大地壓縮存儲空間,
同時也可以避免乘法運算,隻是符号位的變化和加減操作,進而提升計算速度。
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
{-2,-1,0,1,2}, 五值網絡 和 {-4,-2,-1,0,1,2,4} 七值網絡,
需要3bit存儲

首先,我們将離散值權重的神經網絡訓練定義成一個離散限制優化問題。
以三值網絡為例,其目标函數可以表示為:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
在限制條件中引入一個 scale(尺度)參數。
對于三值網絡,我們将限制條件寫成 {-a, 0, a}, a>0.

這樣做并不會增加計算代價,
因為在卷積或者全連接配接層的計算過程中可以先和三值權重 {-1, 0, 1} 進行矩陣操作,
然後對結果進行一個标量 scale。
從優化的角度看,增加這個 scale 參數可以大大增加限制空間的大小,

這有利于算法的收斂。如下圖所示:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
對于三值網絡而言,scale 參數可以将限制空間從離散的 9 個點擴增到 4 條直線。

為了求解上述限制優化問題,我們引入 ADMM 算法。
在此之前,我們需要對目标函數的形式做一個等價變換(對偶變換)。
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
其中 Ic 為訓示函數,
如果 G 符合限制條件,則 Ic(G)=0,
否則 Ic(G) 為無窮大。
該目标函數的增廣拉格朗日形式為( 将條件 引入到 目标函數):
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
ADMM 算法将上述問題分成三個子問題進行求解,即:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
與其它算法不同的是,我們在實數空間和離散空間分别求解,
然後通過拉格朗日乘子的更新将兩組解聯系起來。
第一個子問題需要找到一個網絡權重最小化
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
在實驗中我們發現使用正常的梯度下降算法求解這個問題收斂速度很慢。
在這裡我們使用 Extra-gradient 算法來對這個問題進行求解。
Extra-gradient 算法包含兩個基本步驟,分别是:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
第二個子問題在離散空間中進行優化。通過簡單的數學變換第二個子問題可以寫成:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
該問題可以通過疊代優化的方法進行求解。當 a 或 Q 固定時,很容易就可以獲得 Q 和 a 的解析解。

除上述三值網絡外,還有以下幾種常用的參數空間:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
參數空間中加入2、4、8等值後,仍然不需要乘法運算,隻需進行移位操作。
是以,通過這種方法将神經網絡中的乘法操作全部替換為移位和加操作。
           

6. 哈希函數兩比特縮放量化 BWNH

論文

部落格解析

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結

保留内積哈希方法是沈老師團隊在15年ICCV上提出的 Learning Binary Codes for Maximum Inner Product Search

通過Hashing方法做的網絡權值二值化工作。
第一個公式是我們最常用的雜湊演算法的公式,其中S表示相似性,
後面是兩個哈希函數之間的内積。
我們在神經網絡做權值量化的時候采用第二個公式,
第一項表示輸出的feature map,其中X代表輸入的feature map,W表示量化前的權值,
第二項表示量化後輸出的feature map,其中B相當于量化後的權值,
通過第二個公式就将網絡的量化轉化成類似第一個公式的Hashing方式。
通過最後一行的定義,就可以用Hashing的方法來求解Binary限制。

本文在二值化權重(BWN)方面做出了創新,發表在AAAI2018上,作者是自動化所程建團隊。
本文的主要貢獻是提出了一個新的訓練BWN的方法,
揭示了哈希與BW(Binary Weights)之間的關聯,表明訓練BWN的方法在本質上可以當做一個哈希問題。
基于這個方法,本文還提出了一種交替更新的方法來有效的學習hash codes而不是直接學習Weights。
在小資料和大資料集上表現的比之前的方法要好。

為了減輕用哈希方法所帶來的loss,
本文将binary codes乘以了一個scaling factor并用交替優化的政策來更新binary codes以及factor.
           

3. 三值化網絡

TNN 全三值網絡

Ternary Neural Networks TNN

代碼

訓練時激活量三值化,參數全精度 
infernce時,激活量,參數都三值化(不使用任何乘法) 
用FPGA和ASIC設計了硬體
           

TWN 三值系數網絡

權值三值化的核心:
    首先,認為多權值相對比于二值化具有更好的網絡泛化能力。
    其次,認為權值的分布接近于一個正态分布和一個均勻分布的組合。
    最後,使用一個 scale 參數去最小化三值化前的權值和三值化之後的權值的 L2 距離。   
           

Ternary weight networks

論文翻譯參考

參考2

算法
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
這個算法的核心是隻在前向和後向過程中使用使用權值簡化,但是在update是仍然是使用連續的權值。

簡單的說就是先利用公式計算出三值網絡中的門檻值:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
也就是說,将每一層的權值絕對值求平均值乘以0.7算出一個deta作為三值網絡離散權值的門檻值,
具體的離散過程如下:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
其實就是簡單的選取一個門檻值(Δ),
大于這個門檻值的權值變成 1,小于-門檻值的權值變成 -1,其他變成 0。
當然這個門檻值其實是根據權值的分布的先驗知識算出來的。
本文最核心的部分其實就是門檻值和 scale 參數 alpha 的推導過程。

在參數三值化之後,作者使用了一個 scale 參數去讓三值化之後的參數更接近于三值化之前的參數。
根據一個誤差函數 推導出 alpha 再推導出 門檻值(Δ)

這樣,我們就可以把連續的權值變成離散的(1,0,-1),

那麼,接下來我們還需要一個alpha參數,具體幹什麼用後面會說(增強表達能力)
這個參數的計算方式如下:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
|I(deta)|這個參數指的是權值的絕對值大于deta的權值個數,計算出這個參數我們就可以簡化前向計算了,
具體簡化過程如下:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
可以看到,在把alpha乘到前面以後,我們把複雜的乘法運算變成了簡單的加法運算,進而加快了整個的訓練速度。

主要思想就是三值化參數(激活量與梯度精度),參照BWN使用了縮放因子。
由于相同大小的filter,
三值化比二值化能蘊含更多的資訊,
是以相比于BWN準确率有所提高。
           

訓練三值量化 TTQ 訓練浮點數量化

Trained Ternary Quantization TTQ

部落格參考

提供一個三值網絡的訓練方法。
對AlexNet在ImageNet的表現,相比32全精度的提升0.3%。
與TWN類似,
隻用參數三值化(訓練得到的浮點數),
但是正負縮放因子不同,
且可訓練,由此提高了準确率。
ImageNet-18模型僅有3%的準确率下降。

對于每一層網絡,三個值是32bit浮點的{−Wnl,0,Wpl},
Wnl、Wpl是可訓練的參數。
另外32bit浮點的模型也是訓練的對象,但是門檻值Δl是不可訓練的。 
由公式(6)從32bit浮點的到量化的三值: 
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
由(7)算出Wnl、Wpl的梯度:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
其中:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
由(8)算出32bit浮點模型的梯度
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
由(9)給出門檻值,這種方法在CIFAR-10的實驗中使用門檻值t=0.05。
而在ImageNet的實驗中,并不是由通過欽定門檻值的方式進行量化的劃分,
而是欽定0值的比率r,即稀疏度。 
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
整個流程:
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結

三值 矩陣分解和定點變換

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
借助了矩陣分解和定點變換的優勢,
對原始權值矩陣直接做一個定點分解,限制分解後的權值隻有+1、-1、0三個值。
将網絡變成三層的網絡,首先是正常的3×3的卷積,對feature map做一個尺度的縮放,
最後是1×1的卷積,所有的卷積的操作都有+1、-1、0。
           

4. 二進制位量化網絡 哈希函數的味道啊

ShiftCNN

部落格

神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結
一個利用低精度和量化技術實作的神經網絡壓縮與加速方案。
           
最優量化
量化可以看作用離散碼本描述樣本分布。 
優化目标(最大機率準則)和優化方法(L1和L2正則化)通常導緻了神經網絡參數呈現中心對稱的非均勻分布。
是以,一個最佳的量化碼本應當是一個非均勻分布的碼本。 
這也是為什麼BinaryNet(-1,+1)、ternary quantization(-1,0,+1)這種政策性能不足的一個重要原因。

需要注意的是,
量化之前需要對參數進行範圍歸一化,
即除以最大值的絕對值,這樣保證參數的絕對值都小于1。
該量化方法具有碼本小、量化簡單、量化誤差小的優點。
           
量化
ShiftCNN所采用是一種相當巧妙的類似于殘差量化的方法。

完整的碼本包含 N 個子碼本。 
每個碼本包含 M=2^B−1 個碼字,即每一個碼字可以用 B bit 表示。 
每個碼本定義如下:

 Cn=0, ±2^−n+1, ±2^−n, …, ±2^−n−⌊M/2⌋+2
假設 N=2,B=4,則碼本為

C1=0, ±2^−1, ±2^−2, ±2^−3, ±2^−4, ±2^−5, ±2^−6
C2=0, ±2^−2, ±2^−3, ±2^−4, ±2^−5, ±2^−6, ±2^−7

于是,每一個權重都可以使用 N*B bit 的索引通過下式求和計算得到:
wi' = sum(Cn[id(n)])
           
卷積計算
卷積計算的複雜度主要來自乘法計算。
ShiftCNN采用簡單的移位和加法來實作乘法,進而減少計算量。
比如計算 y=wx, 而 w 通過量化已經被我們表示成了,
類似于 2^−1 + 2^−2 + 2^−3 這種形式,
于是 y = x>>1 + x>>2 + x>>3 
           

3. 編碼(Huffman Encoding)

4. 遷移學習方法 基于教師——學生網絡的方法

基于教師——學生網絡的方法,屬于遷移學習的一種。
遷移學習也就是将一個模型的性能遷移到另一個模型上,
而對于教師——學生網絡,教師網絡往往是一個更加複雜的網絡,
具有非常好的性能和泛化能力,
可以用這個網絡來作為一個soft target來指導另外一個更加簡單的學生網絡來學習,
使得更加簡單、參數運算量更少的學生模型也能夠具有和教師網絡相近的性能,
也算是一種模型壓縮的方式。
           

a. Distilling the Knowledge in a Neural Network

論文參考

較大、較複雜的網絡雖然通常具有很好的性能,
但是也存在很多的備援資訊,是以運算量以及資源的消耗都非常多。
而所謂的Distilling就是将複雜網絡中的有用資訊提取出來遷移到一個更小的網絡上,
這樣學習來的小網絡可以具備和大的複雜網絡想接近的性能效果,并且也大大的節省了計算資源。
這個複雜的網絡可以看成一個教師,而小的網絡則可以看成是一個學生。 

這個複雜的網絡是提前訓練好具有很好性能的網絡,
學生網絡的訓練含有兩個目标:
一個是hard target,即原始的目标函數,為小模型的類别機率輸出與label真值的交叉熵;
另一個為soft target,為小模型的類别機率輸出與大模型的類别機率輸出的交叉熵.
在soft target中,機率輸出的公式調整如下,
這樣當T值很大時,可以産生一個類别機率分布較緩和的輸出

作者認為,由于soft target具有更高的熵,它能比hard target提供更加多的資訊,
是以可以使用較少的資料以及較大的學習率。
将hard和soft的target通過權重平均來作為學生網絡的目标函數,
soft target所占的權重更大一些。 
作者同時還指出,T值取一個中間值時,效果更好,
而soft target所配置設定的權重應該為T^2,hard target的權重為1。 
這樣訓練得到的小模型也就具有與複雜模型近似的性能效果,但是複雜度和計算量卻要小很多。

對于distilling而言,複雜模型的作用事實上是為了提高label包含的資訊量。
通過這種方法,可以把模型壓縮到一個非常小的規模。
模型壓縮對模型的準确率沒有造成太大影響,而且還可以應付部分資訊缺失的情況。
           

b.使用複雜網絡中能夠提供視覺相關位置資訊的Attention map來監督小網絡的學習

論文參考

代碼

作者借鑒Distilling的思想,
使用複雜網絡中能夠提供視覺相關位置資訊的Attention map來監督小網絡的學習,
并且結合了低、中、高三個層次的特征.

教師網絡從三個層次的Attention Transfer對學生網絡進行監督。
其中三個層次對應了ResNet中三組Residual Block的輸出。
在其他網絡中可以借鑒。 
這三個層次的Attention Transfer基于Activation,
Activation Attention為feature map在各個通道上的值求和,

但是就需要兩次反向傳播的過程,實作起來較困難并且效果提升不明顯。
基于Activation的Attention Transfer效果較好,而且可以和Hinton的Distilling結合。 
           

模型壓縮總結

1. 核參數稀疏
   在損失函數中添加使得參數趨向于稀疏的項,
使得模型在訓練過程中,其參數權重趨向于稀疏。

2. 權重矩陣低秩分解
   核心思想就是把較大的卷積核分解為兩個級聯的行卷積核和列卷積核,
   例如 3*3卷積分成 1*3卷積和 3*1卷積 級聯。
   這裡對于1*1的卷積核無效。

3. 剪枝
   可分為在filter級别上剪枝或者在參數級别上剪枝:
   a. 對于單個filter,有門檻值剪枝方法,将filter變得稀疏。
   b. 宏觀上使用一種評價方法(能量大小)來計算每個filter的重要性得分,
      去除重要性低的filter。

4. 量化
   a. 降低資料數值範圍
      單精度浮點數(32)-> 半精度浮點數(16)
      ->無符号(8) -> 三值 -> 二值
   b. 聚類編碼實作權值共享的方法
      對卷積核參數進行k_means聚類,得到聚類中心。,
      對原始參數,使用其所屬的中心id來代替。
      然後通過儲存這k個類别的中心值,以及id局矩陣來壓縮網絡。
      
5. 遷移學習
   通過将較大較複雜較優秀的網絡(老師)中的有用資訊提取出來遷移到一個更小的網絡上(學生),
   這樣學習來的小網絡可以具備和大的複雜網絡相想接近的性能效果,實作網絡的壓縮。
           
神經網絡壓縮 剪枝 量化 嵌入式計算優化NCNN mobilenet squeezenet shufflenet性能提升方法AI晶片壓縮算法在實際硬體晶片的應用模型壓縮模型壓縮總結

繼續閱讀