一個利用低精度和量化技術實現的神經網絡壓縮與加速方案。 個人認爲,這是低精度量化方面少有的具有一定工程可行性的方案(雖然文中沒有給出詳細的模型大小速度方面的指標)。
文章鏈接: 《ShiftCNN: Generalized Low-Precision Architecture for Inference of Convolutional Neural Networks》
模型轉換示例代碼: https://github.com/gudovskiy/ShiftCNN
相關背景
(1) 低精度數據表達
通常神經網絡計算使用float32位。 有些人嘗試用16bit或者8bit數據,但由於不再能使用現成的一些BLAS庫,導致實際部署效率可能和設想相差較多。 另外,像BinaryNet(-1,+1)、ternary quantization(-1,0,+1)等,雖然可以採用移位操作來代替乘法,但往往導致網絡性能下降較多。
(2) 卷積計算方式
除了在頻率域計算卷積之外,利用矩陣乘法結合BLAS庫是採用最多的卷積計算方法。 此外,也有一些採用查表法計算卷積的,但往往受限於碼本導致性能不足。
(3) 最優量化
量化可以看作用離散碼本描述樣本分佈。 優化目標(最大概率準則)和優化方法(L1和L2正則化)通常導致了神經網絡參數呈現中心對稱的非均勻分佈。 因此,一個最佳的量化碼本應當是一個非均勻分佈的碼本。 這也是爲什麼BinaryNet(-1,+1)、ternary quantization(-1,0,+1)這種策略性能不足的一個重要原因。
量化
ShiftCNN所採用是一種相當巧妙的類似於殘差量化的方法。
完整的碼本包含 \(N\) 個子碼本。 每個碼本包含 \(M=2^{B}-1\) 個碼字,即每一個碼字可以用 \(B\ bit\) 表示。
每個碼本定義如下:
\(C_n = {0, \pm2^{-n+1},\pm2^{-n},…,\pm2^{-n-\lfloor M/2 \rfloor + 2}}\)
假設 \(N = 2,B=4\),則碼本爲
\(C_1 = {0,\pm2^{-1},\pm2^{-2},\pm2^{-3},\pm2^{-4},\pm2^{-5},\pm2^{-6}}\)
\(C_2 ={0,\pm2^{-2},\pm2^{-3},\pm2^{-4},\pm2^{-5},\pm2^{-6}},\pm2^{-7}\)
於是,每一個權重都可以使用 \(NB\ bit\) 的索引通過下式求和計算得到:
\(\hat{w_i}=\sum_{n=1}^{N}C_n[idx_i(n)]\)
整個對參數進行量化的流程如下:
需要注意的是,量化之前需要對參數進行範圍歸一化,即除以最大值的絕對值,這樣保證參數的絕對值都小於1。
該量化方法具有碼本小、量化簡單、量化誤差小的優點。
卷積計算
卷積計算的複雜度主要來自乘法計算。 ShiftCNN採用簡單的移位和加法來實現乘法,從而減少計算量。
比如計算 \(y = wx\), 而 \(w\) 通過量化已經被我們表示成了類似於 \(2^{-1}+2^{-2}+2^{-3}\) 這種形式,於是 \(y = x>>1 + x>>2+x>>3\)。
應該注意到,儘管\(N\) 個子碼本,每個碼本都包含 \(M=2^{B}-1\) 個碼字,但其實只有 \(P=M+2(N-1)\) 個不同的碼字。
因此,本文的卷積的核心是對輸入數據進行預計算,因爲移位的情況有限。 假設輸入緯度爲 \(C\times H\times W\), 則我們可以提前計算所有可能的移位情況,得到 \((P-1)\times C\times H\times W\)。 這裏減1是因爲忽略碼字爲0的情況。
整個卷積的計算如下所示:其核心爲一個移位單元以及一個累加單元。
其中累加單元如下:(主要是邏輯控制與求和)
實驗
ShiftCNN量化後無需再訓練。 個人覺得再訓練應該會更好一點。
理論複雜度就不說了,沒意思。雖然我預估計算量依然比較大。 文章還給出了一部分FPGA上的實驗,但我其實最想看的是更多的橫向對比,比如在PC或者Android設備上的速度對比之類的。