如何減小機器學習模型的大小

      網友投稿 996 2022-05-30

      機器學習模型變得越來越大,計算成本也越來越高。嵌入式設備的內存、計算能力和電池都受到限制。但我們可以對模型進行優化,使其在這些設備上能夠順利運行。通過減小模型的大小,我們減少了需要執行的操作數量,從而減少了計算量。較小的模型也很容易轉化為更少的內存使用,也就更節能。人們一定會認為,減少計算次數可以減少功耗,但相反,從內存訪問獲得的功耗比進行加法或乘法運算要高出 1000 倍左右。現在,既然沒有免費的午餐,也就是說,所有一切都是有代價的,因此,我們就會失去模型的正確率。記住,這些加速的措施并不是為了訓練模型,而是為了進行推理。

      剪枝

      剪枝(Pruning)就是刪除對輸出貢獻不大的多余網絡連接。剪枝網絡的想法可以追溯到 20 世紀 90 年代,即“最優腦損傷”(Optimal Brain Damage)和“最優腦手術”(Optimal Brain Surgeon)。這些方法使用 Hessians 來確定連接的重要性,這也使得它們不適用于深度網絡。剪枝方法使用迭代訓練技術,即訓練 → 剪枝 → 微調。剪枝后的微調恢復了網絡經剪枝后丟失的正確率。一種方法是使用 L1/L2 范數對網絡中的權重進行排序,并去掉最后的 x% 的權重。其他類型的方法也使用排序,使用神經元的平均激活,神經元在驗證集上的激活次數為零,還有許多其他創造性的方法。這種方法是由 Han 等人在 2015 年的論文中首創的。

      神經網絡的剪枝。Han 等人

      更近一些的是 2019 年,Frankle 等人在論文《彩票假說》(?The Lottery Ticket Hypothesis)中發現,在每個深度神經網絡中都存在一個子集,在同等數量的訓練下,該子集也具有同樣的正確率。這些結果適用于非結構化剪枝,即剪枝整個網絡,從而得到一個稀疏網絡。稀疏網絡在 GPU 上效率低下,因為它們的計算沒有結構。為了補修這一點,需要進行結構化剪枝,即對網絡的一部分進行剪枝,例如某一層或某一通道。?Liu 等人發現,前面討論的彩票假說在這里并不適用。相反,他們發現,在剪枝之后重新訓練網絡比微調更好。除了性能之外,稀疏網絡還有其他用途嗎?是的,正如?Ahmed 等人的論文所指出的那樣,稀疏網絡在噪聲輸入的情況下更具健壯性。在 TensorFlow(tensorflow_model_optimization?包)和 PyTorch(torch.nn.utils.prune)都支持剪枝。

      要在 PyTorch 中使用剪枝,你可以從?torch.nn.utils.prune?中選擇一個技術類,或者實現?BasePruningMethod?的子類。

      from?torch.nn.utils?import?prune tensor?=?torch.rand(2,?5) pruner?=?prune.L1Unstructured(amount=0.7) pruned_tensor?=?pruner.prune(tensor)

      為了對模塊進行剪枝,我們可以使用?torch.nn.utils.prune?中給出的剪枝方法(基本上就是上述的類的包裝器),并指定哪個模塊要進行剪枝,甚至是該模塊的哪個參數。

      conv_1?=?nn.Conv(3,?1,?2) prune.ln_structured(module=conv_1,?name='weight',?amount=5,?n=2,?dim=1)

      如何減小機器學習模型的大小

      這將使用剪枝后的結果替換參數權重,并添加一個參數?weight_orig?來存儲輸入的未剪枝版本。剪枝掩碼(pruning mask)存儲為?weight_mask,并作為模塊緩沖區保存。這些參數可以通過?module.named_parameters()?和?module.named_buffers()?來檢查。為了實現迭代剪枝,我們可以只在下一次迭代中應用剪枝方法,這樣它就可以正常工作了,這是因為?PurningContainer?在處理最終掩碼的計算時,考慮到了之前使用?computer_mask?方法的剪枝。

      量化

      量化(Quantization)是為了限制一個權重可以取的可能值的數量,這將減少一個權重可以減少的內存,從而減小模型的大小。實現這一點的一種方法是,更改用于存儲權重的浮點數的位寬。以 32 位浮點數或 FP32 到 FP16、或 8 位定點數形式存儲的數字,越來越多地以 8 位整數的形式存儲。減少位寬具有以下許多優點:

      從 32 位轉換到 8 位,可以讓我們立即獲得 4 倍的內存優勢。

      較低的位寬還意味著,我們可以在寄存器 / 高速緩存中壓縮更多的數字,從而減少內存訪問,進而減少時間和功耗。

      整數計算總是比浮點計算要快。

      之所以可行,是因為神經網絡對其權重的微小擾動是非常健壯的,我們可以很輕松地舍去它們,而不會對網絡的正確率產生太大的影響。此外,由于訓練中使用的正則化技術,權重并不包含在非常大的范圍內,因此我們不必使用過大的范圍,比如,對于 32 位浮點數,取-3.4×10^38?到 3.4×10^38?就可以了。例如,在下圖中,MoboileNet 中的權重值都非常接近于零。

      一個量化方案是我們如何將實際權重轉換為量化權重,該方案的一個最基本的形式是線性縮放。假設我們要講范圍 [r_min, r_max]?的值轉換為 [0, I_max] 的整數范圍,其中,I_max 為 2^B - 1 是整數表示的位寬。 因此,

      其中, r 是權重的原始值,s 是比例,q 是量化值,z?是映射到?0.0f?的值。這也稱為仿射變換(affine mapping)。由于 q 為整數,因此對結果進行四舍五入。現在的問題是,我們如何選擇 r_min 和 r_max 。實現這一點的簡單方法是生成權重和激活的分布,然后用量化分布計算他們的?KL 散度(Kullback-Leibler divergence,縮寫為 KLD 或 KL divergences),并使用與原始值差異最小的那個。一種更為優雅的方法是使用偽量化(Fake Quantization),即,在訓練期間將量化感知層引入網絡。這個想法是由?Jacob 等人?提出的。

      在訓練時,偽量化節點計算權重和激活的范圍,并存儲它們的移動平均值。完成訓練后,我們用這個范圍來對網絡進行量化,以獲得更好的性能。

      Rastegari 等人的關于異或(XOR)網絡的論文、Courbariaux 等人的關于三值(Ternary)網絡的論文、Zhu 等人的關于二值(Binary)網絡的論文中也探討了更大的位寬。在 PyTorch 1.3 中,引入了量化支持。為量化操作引入了三種新的數據類型:torch.quint8、torch.qint8?和?torch.qint32。它還提供了各種量化技術,包含在?torch.quantization?中。

      訓練后動態量化:將浮點權重替換為其動態量化版本。默認情況下,只對權重交大的層(即線性和 RNN 變體)進行權重量化。

      quantized_model?=?torch.quantization.quantize_dynamic( ????model,?{nn.LSTM,?nn.Linear},?dtype=torch.qint8 ????)

      訓練后靜態量化:靜態量化不僅可以將浮點數權重轉換為整數,還可以記錄激活的分布情況,并用于確定推理時的量化比例。為了支持這種校準類型的量化,我們在模型的開頭和結尾分別添加了?QuantStub?和?DeQuantStub。它涉及下面提到的步驟。

      myModel?=?load_model(saved_model_dir?+?float_model_file).to('cpu') #?Fuse?Conv,?bn?and?relu myModel.fuse_model() #?Specify?quantization?configuration #?Start?with?simple?min/max?range?estimation?and?per-tensor? #?quantization?of?weights myModel.qconfig?=?torch.quantization.default_qconfig torch.quantization.prepare(myModel,?inplace=True) #?Calibrate?with?the?training?set evaluate(myModel,?criterion,?data_loader, ???????????neval_batches=num_calibration_batches) ??????????? #?Convert?to?quantized?model torch.quantization.convert(myModel,?inplace=True)

      量化感知訓練:在訓練時使用偽量化模塊來存儲比例。為了啟用量化感知訓練,我們使用?qconfig?作為?get_default_qat_qconfig('fbgemm'),使用?prepare_qat?來代替?prepare。之后,就可以對模型進行訓練或微調,在訓練結束時,使用 與上述相同的?torch.quantization.convert?得到量化模型。

      PyTorch 中的訓練后量化目前僅支持 CPU 上的操作。

      有關詳細的代碼示例,請參閱?PyTorch 文檔。在 TensorFlow 方面,通過 將?optimizations?參數設置為?tf.lite.Optimize.OPTIMIZE_FOR_SIZE,可以使用 TFLite 的?tf.lite.TFLiteConverter?API 進行量化。偽量化是通過?tf.contrib.quantize?包啟用的。

      Senior software engineer at?99acres.com, previously at?Samsung Research Institute, Noida. Worked extensively on On-device machine learning and NLP problems.

      https://amandeepsp.github.io/ml-model-compression-part1/

      轉載自:

      https://www.infoq.cn/article/a3JBMhBsy9HOsfkOB3UL

      人工智能

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel表格將打印預覽功能怎么添加到工具欄
      下一篇:中科大研二學生,深度學習放棄,淺度學習入門!?
      相關文章
      色老板亚洲视频免在线观| 久久久久亚洲AV片无码下载蜜桃 | 亚洲人成在线观看| 国产亚洲AV夜间福利香蕉149 | 国内精品99亚洲免费高清| 国产偷国产偷亚洲清高APP| 亚洲av无码成人影院一区| 亚洲欧美第一成人网站7777| 亚洲欧洲日产国码久在线| 亚洲国产精品18久久久久久 | 亚洲国产精品一区第二页| 亚洲线精品一区二区三区| 亚洲午夜久久久久妓女影院 | 亚洲一区电影在线观看| 亚洲国产最大av| 亚洲va在线va天堂成人| 中文字幕亚洲情99在线| 亚洲av日韩专区在线观看| 婷婷亚洲综合五月天小说在线 | 亚洲精品视频免费看| 久久精品国产亚洲AV无码麻豆| 亚洲avav天堂av在线不卡| 久久国产亚洲电影天堂| 亚洲福利在线观看| 亚洲蜜芽在线精品一区| 亚洲另类古典武侠| 在线aⅴ亚洲中文字幕| 亚洲人成自拍网站在线观看| 久久久久亚洲精品无码网址色欲 | 亚洲av无码专区在线观看下载 | 亚洲av无码专区在线电影| 亚洲成AⅤ人影院在线观看| 亚洲国产精品第一区二区三区| 亚洲精品无码av天堂| 亚洲精品无码久久千人斩| 久久亚洲国产午夜精品理论片| 久久亚洲综合色一区二区三区| 亚洲一区精品中文字幕| 亚洲三级视频在线观看| 亚洲成a人片在线观看天堂无码 | 亚洲精品91在线|