卷积神经网络训练模拟量化实践
為什么80%的碼農都做不了架構師?>>> ??
前言
????? ? 深度學習在移動端的應用是越來越廣泛,由于移動端的運算力與服務器相比還是有差距,所以在移動端
部署深度學習模型的難點就在于如何保證模型效果的同時,運行效率也有保證。在實驗階段對于模型結構可以
選擇大模型,因為該階段主要是為了驗證方法的有效性。在驗證完了之后,開始著手部署到移動端,這時候就
要精簡模型的結構了,一般是對訓好的大模型進行剪枝,或者參考現有的比如MobileNetV2和ShuffleNetV2
等輕量級的網絡重新設計自己的網絡模塊。而算法層面的優化除了剪枝還有量化,量化就是把浮點數(高精度)
表示的權值和激活值用更低精度的整數來近似表示。低精度的優點有,相比于高精度算術運算,其在單位時間
內能處理更多的數據,而且權值量化之后模型的存儲空間能進一步的減少等等[1]。對訓練好的網絡做量化,
在實踐中嘗試過TensorRT[5][8]的后訓練量化算法,效果還不錯。但是如果能在訓練過程中去模擬量化的過程,
讓網絡學習去修正量化帶來的誤差,那么得到的量化參數應該是更準確的,而且在實際量化推斷中模型的性能
損失應該能更小。而本文的內容就是介紹論文[3][4]和復現其過程中的一些細節。
????按照慣例,先給出本文實驗的代碼:TrainQuantization
訓練模擬量化
方法介紹
????首先來看下量化的具體定義,對于量化激活值到有符號8bit整數,論文中給出的定義如下:
?
????公式中的三角形表示量化的縮放因子,x表示浮點數激活值,首先通過除以縮放因子然后最近鄰取整,
然后把范圍限制到一個區間內,比如量化到有符號8bit,那么范圍就是 [-128, 127]。而對于權值還有一
個小的技巧,就是量化到[-127, 127]:
具體為什么這么做,論文中說了是為了實現上的優化,具體解釋可以看論文[3]附錄B ARM NEON details
這一小節。
? ? 而訓練量化說白了就是在forward階段去模擬量化這個過程,本質就是把權值和激活值量化到8bit再反
量化回有誤差的32bit,所以訓練還是浮點,backward階段是對模擬量化之后權值的求梯度,然后用這個
梯度去更新量化前的權值。然后在下個batch繼續這個過程,通過這樣子能夠讓網絡學會去修正量化帶來的
誤差。
? ? 上面給這個示意圖就很直觀的表示了模擬量化的過程,比如上面那條線表示的是量化前的范圍[rmin, rmax],
然后下面那條線表示的就是量化之后的范圍[-128, 127],比如現在要進行模擬量化的forward,先看上面那
條線從左到右數第4個圓點,通過除以縮放因子之后就會映射124到125之間的一個浮點數,然后通過最近鄰
取整就取到了125,再通過乘以縮放因子返回上面第五個圓點,最后就用這個有誤差的數替換原來的去forward。
forward階段的模擬量化用公式表示如下:
backward階段求梯度的公式表示如下:
? ? 對于縮放因子的計算,權值和激活值的不一樣,權值的計算方法是每次forward直接對權值求絕對值取
最大值,然后縮放因子 weight scale = max(abs(weight)) / 127。然后對于激活值,稍微有些不一樣,
激活值的量化范圍不是簡單的計算最大值,而是通過EMA(exponential moving averages)在訓練中
去統計這個量化范圍,更新公式如下:
moving_max = moving_max * momenta + max(abs(activation)) * (1- momenta)
公式中的activation表示每個batch的激活值,而論文中說momenta取接近1的數就行了,在實驗中
我是取0.95。然后縮放因子 activation scale = moving_max /128。
實現細節
? ? 在實現過程中我沒有按照論文的方法量化到無符號8bit,而是有符號8bit,第一是因為無符號8bit量化
需要引入額外的零點,增加復雜性,其次在實際應用過程中都是量化到有符號8bit。然后論文中提到,
對于權值的量化分通道進行求縮放因子,然后對于激活值的量化整體求一個縮放因子,這樣效果最好。
在實踐中發現有些任務權值不分通道量化效果也不錯,這個還是看具體任務吧,不過本文給的實驗代碼
是沒分的。
? ? 然后對于卷積層之后帶batchnorm的網絡,因為一般在實際使用階段,為了優化速度,batchnorm
的參數都會提前融合進卷積層的參數中,所以訓練模擬量化的過程也要按照這個流程。首先把batchnorm
的參數與卷積層的參數融合,然后再對這個參數做量化。以下兩張圖片分別表示的是訓練過程與實際應用
過程中對batchnorm層處理的區別:
? ? ?
? ? 對于如何融合batchnorm參數進卷積層參數,看以下公式:
公式中的,W和b分別表示卷積層的權值與偏置,x和y分別為卷積層的輸入與輸出,則根據bn的計算
公式,可以推出融合了batchnorm參數之后的權值與偏置,Wmerge和bmerge。
? ? 在實驗中我其實是簡化了融合batchnorm的流程,要是完全按照論文中的實現要復雜很多,
而且是基于已經訓好的網絡去做模擬量化實驗的,不基于預訓練模型訓不起來,可能還有坑要踩。
而且在模擬量化訓練過程中batchnorm層參數固定,融合batchnorm參數也是用已經訓好的移動
均值和方差,而不是用每個batch的均值和方差。
????具體實現的時候就是按照論文中的這個模擬量化卷積層示例圖去寫訓練網絡結構的。
實驗結果
? ? 用VGG在Cifar10上做了下實驗,效果還可以,因為是為了驗證量化訓練的有效性,所以訓
Cifar10的時候沒怎么調過參,數據增強也沒做,訓出來的模型精確度最高只有0.877,比最好的
結果0.93差不少,然后模擬量化是基于這個0.877的模型去做的,可以得到與普通訓練精確度基本
一樣的模型,可能是這個分類任務比較簡單。然后得到訓好的模型與每層的量化因子之后,就可以
模擬真實的量化推斷過程,不過因為MXNet的卷積層不支持整型運算,所以模擬的過程也是用浮點
來模擬,具體實現細節可見示例代碼。
結束語
? ? 以上內容是根據最近的一些工作實踐總結得到的一篇博客,對于論文的實現很多地方都是我自己
個人的理解,如果有讀者發現哪里有誤或者有疑問,也請指出,大家互相交流學習:)。
參考資料
[1]?8-Bit Quantization and TensorFlow Lite: Speeding up mobile inference with low precision
[2]?Building a quantization paradigm from first principles
[3]?Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference
[4]?Quantizing deep convolutional networks for efficient inference: A whitepaper
[5]?8-bit Inference with TensorRT
[6]?TensorRT(5)-INT8校準原理
[7]?caffe-int8-convert-tool.py
轉載于:https://my.oschina.net/Ldpe2G/blog/3000810
總結
以上是生活随笔為你收集整理的卷积神经网络训练模拟量化实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: flash背景透明、置底、禁止放大 右键
- 下一篇: 0002深度学习初体验-基于Tensor