如何輕量化深度學習模型

在這裏插入圖片描述
概述卷積神經網絡依靠神經網絡中數以千萬計的網絡參數共同參與計算,存在網絡結構複雜,運算量大,速度慢的缺點,並且很難移植到嵌入式設備中。隨着網絡模型層數越來越深,參數越來越多,減少他們的大小和計算損耗至關重要,特別是對於在線學習和增強學習這樣的實時應用來說。不僅如此,近年來 VR,AR 以及智能可穿戴設備的高速發展,需要研究者們解決將大規模學習系統部署到移動設備上的問題。而達到這個目標需要從很多方面獲取整合的解決方案,包括但不限於機器學習,優化方法,計算機結構,數據壓縮,索引和硬件設計。這是一個重要且十分活躍的領域。近年來,許多學者在深度學習壓縮和加速方面已經做出許多成果, 出了多種神經網絡輕量化的算法,主要可分爲以下幾類。1. 網絡剪枝網絡剪枝目的在於找出這些冗餘連接並將其移除,使其不再參與網絡的前向或後向運算過程中,起到減少網絡計算量的作用,如下圖所示。移除的神經元及相應連接也不再存儲,減少了模型的存儲量。在這個過程中,一個原本稠密的神經網絡由於部分連接的移除而變得稀疏。image.png由於全連接層冗餘度遠遠高於卷積層,傳統的網絡剪枝方法多用於全連接層中。網絡剪枝往往針對已經訓練好的模型進行,在得到訓練好的模型後,根據某種評價標準定義每條連接的重要程度。一種廣泛使用的評價標準是連接權重的絕對值大小,該值越小,說明對應的神經元對網絡輸出結果影響越小,屬於不重要的神經元,應該被移除,對應的連接也應被剪除。雖然移除的連接不那麼重要,但隨着網絡計算過程中的錯誤累積,網絡性能和準確度依然會受到較大的影響,爲了消除這些影響,一個很重要的步驟是對剪枝後的網絡進行微調訓練來恢復網絡性能。整個網絡剪枝和調優交替進行,直至達到模型大小與模型性能間的最佳平衡。 權重剪枝主要有兩種方式: (1)後剪枝:拿到一個模型直接對權重進行剪枝,不需要其他條件。 (2)訓練時剪枝:訓練迭代時邊剪枝,使網絡在訓練過程中權重逐漸趨於0,但是由於訓練時權重動態調整,使得剪枝操作對網絡精度的影響可以減少,所以訓練時剪枝比後剪枝更加穩定。在剪枝結束後,權值矩陣由稠密矩陣變爲稀疏矩陣。爲了減少參數的存儲量,通常使用存儲稀疏矩陣的壓縮存儲方式存儲參數,代表方式爲稀疏行壓縮方法 (Compressed Sparse Row,CSR)和稀疏列壓縮方法 (Compressed SparseColumn,CSC)。image.pngTF官方提供了詳盡的Keras剪枝教程和Python API文檔,以及訓練稀疏模型等高級用法的指導。2. 權值量化 量化概念網絡量化通過減少表示每個權重的比特數的方法來壓縮神經網絡。 量化的思想非常簡單,就是對權重數值進行聚類。統計網絡權重和激活值的取值範圍,找到最大值最小值後進行min-max映射把所有的權重和激活映射到到INT8整型範圍(-127~128)。 在卷積神經網絡中,參數所分佈在的數值空間,通過一定的劃分方法,總是可以劃分爲 k 個類別,因此可以通過存儲這 k 個類別的中心值或者映射值從而壓縮網絡的存儲。 通過全值量化方法,一方面可以減少模型的存儲佔用的空間。模型的權值參數往往以 32 位浮點數的形式保存,神經網絡中往往具有數以千萬計的參數,會佔據極大的存儲空間,因此,如果在存儲模型參數時將 32 位浮點數量化爲 8 位的定點數,可以把參數大小縮小爲原來的 1/4,整個模型的大小也可以縮小爲原來的 1/4,不僅如此,隨着參數量化後模型的減小,網絡前向運算階段所需要的計算資源也會大大減少。 量化步驟量化具體步驟如下: (1)量化:首先對權重矩陣中的所有權值進行 k 均值聚類,以圖示爲例,將其聚爲四類,不同類用不同顏色表示,聚類結束後同一類的權重值用對應的聚類索引和聚類中心值表示。 image.png (2)反向傳播:使用普通的梯度計算方法得到每個權重所對應的梯度,根據之前的權重分組,將同一組的權重梯度值進行累加,得到聚類中心這一輪網絡訓練中的更新量,聚類中心值減去更新量與學習率的乘積,就得到本輪訓練更新後的聚類中心。 經過多次聚類-訓練-更新步驟後,就可以得到量化後的神經網絡模型,每個權重可以僅僅由其對應的聚類中心值和聚類索引來表示。 一種更爲極端的方式是二值量化,即僅僅使用 (-1) 和 (+1) 來表示權重值,此時一個權重值僅僅只佔用一個比特位,參數模型壓縮到僅爲原來的 1/32,並且-1,+1 相比普通的浮點數權值,在乘加運算中具有天然的計算優勢,計算效率極高。量化爲什麼有效首先量化會損失精度,這相當於給網絡引入了噪聲,但是神經網絡一般對噪聲是不太敏感的,只要控制好量化的程度,對高級任務精度影響可以做到很小。 其次,傳統的卷積操作都是使用FP32浮點,浮點運算時需要很多時間週期來完成,但是如果我們將權重參數和激活在輸入各個層之前量化到INT8,位數少了乘法操作少了,而且此時做的卷積操作都是整型的乘加運算,比浮點快很多,運算結束後再將結果乘上scale_factor變回FP32,這整個過程就比傳統卷積方式快很多。 從體系結構的考量角度思考量化帶來的另一個好處是節能和芯片面積,每個數使用了更少的位數,做運算時需要搬運的數據量少了,減少了訪存開銷(節能),同時所需的乘法器數目也減少(減少芯片面積)。3. 低秩近似基於低秩分解的方法從分解矩陣運算的角度對模型計算過程進行了優化,具有清晰的數學解釋,是減少模型冗餘和加速模型運算的一種非常有效的方法,特別是對於全連接層的壓縮和加速。 大多數的計算量分佈在卷積層中。在卷積層結構中,網絡層的參數通常以多維矩陣的形式保存。通過使用線性代數的方法將參數矩陣分解爲一系列小矩陣的組合,使得小矩陣的組合在表達能力上與原始卷積層基本一致,這就是基於低秩分解方法的本質。 該方法可以保持模型一定的精度並能夠極大地降低參數存儲所佔用的空間並按照從淺到深的順序逐層對卷積層做低秩近似處理,在一層經過低秩分解後,固定該層參數,並用一種重構誤差進行微調。 缺點: 1. 低秩分解實現並不容易,且計算成本高昂;2. 目前沒有特別好的卷積層實現方式,而目前研究已知,卷積神經網絡計算複雜度集中在卷積層;3. 低秩近似只能逐層進行,無法執行全局參數壓縮。4. 知識蒸餾使用一個大型預先訓練的網絡(即教師網絡)來訓練一個更小的網絡(又名學生網絡)。一旦對一個繁瑣笨重的網絡模型進行了訓練,就可以使用另外一種訓練(一種蒸餾的方式),將知識從繁瑣的模型轉移到更適合部署的小模型。 KD算法 使用兩個目標函數的加權平均。首先以一個較高的溫度 T 去訓練複雜模型,然後訓練簡單模型,在同樣的溫度 T 下,將複雜模型輸出的 logits 與簡單模型輸出的 logits 求交叉熵,將之作爲第一個目標函數。然後在 T 1 的情況下,求簡單模型輸出的 logits 與正確標籤的交叉熵,作爲第二的目標函數。最後將兩個目標函數加權平均作爲簡單模型總的目標函數,用於網絡的訓練。 image.pngTAS算法 引入多級知識蒸餾,利用一箇中等規模的網絡(又稱教師助理)來彌補學生和教師之間的鴻溝。從一個複雜的教師模型中提取一個小型的蒸餾模型(即學生模型),當兩個網絡模型相差很大時,複雜模型的參數越多,準確度就越高時,反而會比一個較其更小的教師模型那裏提取的學生模型差。所以創造一個教師助理網絡模型,去填補教師和學生網絡之間的空隙。學生模型只能從助理模型中提取知識。image.png5. 高效網絡結構由於神經網絡對於噪聲不敏感,所以許多早期經典模型的參數其實是存在很大冗餘度的,這樣的模型很難部署在存儲有限的邊緣設備,嵌入式設備的高需求刺激了高效網絡結構的設計。例如 GoogleNet 使用了Inception 模塊而不再是簡單的堆疊網絡層從而減小了計算量。ResNet 通過引入瓶頸結構取得了極好的圖像識別效果。ShuffleNet 結合了羣組概念和深度可分離卷積,在 ResNet 上取得了很好的加速效果。MobileNet 採用了深度可分離卷積實現了目前的最好網絡壓縮效果。減小卷積核大小 使用更小的3x3卷積(加深網絡來彌補感受野變小) 將大卷積核分解成一系列小的卷積核的操作組合 減少通道數(1)1x1卷積的應用。在大卷積核前應用1X1卷積,可以靈活地縮減feature map通道數(同時1X1卷積也是一種融合通道信息的方式),最終達到減少參數量和乘法操作次數的效果。 (2)組卷積的應用。將feature map的通道進行分組,每個filter對各個分組進行操作即可,例如分成兩組,每個filter的參數減少爲傳統方式的二分之一(乘法操作也減少)。 (3)深度可分離卷積(depthwise convolution)的應用,是組卷積的極端情況,將卷積的過程分爲逐通道卷積與逐點1×1卷積兩步,每一個組只有一個通道。雖然深度可分離卷積將一步卷積過程擴展爲兩步,但減少了冗餘計算,因此總體上計算量有了大幅度降低。 如果只採用分組卷積操作,相比傳統卷積方式,不同組的feature map信息無法交互,因此可以在組卷積之後在feature map間進行Shuffle Operation來加強通道間信息融合。 或者更巧妙的是像Pointwise convolution那樣將原本卷積操作分解成兩步,先進行 depthwise convolution,之後得到的多個通道的feature map再用一個1X1卷積進行通道信息融合,拆解成這樣兩步,卷積參數也減少了。 減少filter數目 直接減少的filter數目雖然可以減少參數,但是導致每層產生的feature map數目減少,網絡的表達能力也會下降不少。一個方法是像DenseNet那樣,一方面減少每層filter數目,同時在每層輸入前充分重用之前每一層輸出的feature map。池化操作池化操作是操作卷積神經網絡的標準操作,池化層沒有參數,同時又可以靈活縮減上一級的feature map大小,從而減少下一級卷積的乘法操作。6. 卷積運算的優化卷積轉化爲矩陣乘法大部分深度學習框架會把卷積操作轉化成矩陣乘法操作,這樣可以利用現有成熟的矩陣乘法優化方案,比較常見的轉化方式是img2col。全連接層可以直接轉化爲矩陣乘法,因爲全連接的操作本質上就是Y=WX的矩陣操作。從另一個角度,全連接的操作其實還可以看作 每個神經元爲1x1filter,所進行的卷積操作。而對於卷積層,轉化爲矩陣乘法後,會引入一定冗餘度。優化矩陣乘法操作矩陣分塊可以更好地匹配各級cache的大小,這樣cache局部性更好,訪存時的miss率更低。除此之外,對矩陣的內存數據佈局進行重排布來增加待計算數據放置的連續性,這樣取數的時候cache miss率也會更低,像常見的 NCWH 和 NWHC 排布模式都是這方面考慮。矩陣乘法的近似計算使用其它的卷積近似替代算法,可以減少複雜度。不過有些算法有使用條件,像Winograd只是對小卷積核操作有比較大的優化效果。傅里葉變換似乎不太常用,因爲要達到理論上的加速,要求卷積核要很大纔可以,而實際上深度學習用的都是小卷積核。參考:1.分佈式機器學習:算法、理論與實踐 (豆瓣)2.李沐 Mu Li. Scaling Distributed Machine Learning with System and Algorithm Co-design. https://www.cs.cmu.edu/~muli/file/mu-thesis.pdf3.深度學習加速綜述:算法、編譯器、體系結構與硬件設計https://zhuanlan.zhihu.com/p/101544149 5. https://blog.skymind.ai/distributed-deep-learning-part-1-an-introduction-to-distributed-training-of-neural-networks/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章