精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身


WAVE SUMMIT 2019 深度學習開發者峰會上,PaddleSlim 全新發布,對於在內存緊張、功耗限制、存儲有限的設備上進行深度學習應用的開發者是一份重磅驚喜。

PaddleSlim 是一個無論是新手還是經驗者都可以很方便用來優化模型以進行部署的模型壓縮庫:在普通的模型訓練上,只需要兩行 python 代碼,構造一個 Compressor 對象,即可調用。PaddleSlim 實現了目前主流的網絡量化、剪枝、蒸餾三種壓縮策略,並可快速配置多種壓縮策略組合使用。針對體積已經很小的 MobileNet 模型,在模型效果不損失的前提下實現 70% 以上的體積壓縮。

項目地址:https://github.com/PaddlePaddle/models/tree/v1.4/PaddleSlim

 

深度學習技術已經在互聯網的諸多方向產生影響,關於深度學習和神經網絡的討論越來越多。深度學習技術近幾年在計算機視覺、語音識別、自然語言處理等領域大放異彩,各種互聯網產品都爭相應用深度學習技術,我們的生活中也越來越多的 AI 時代新能力,例如人臉識別、智能翻譯、語音助手等。

根據《2019 年移動市場報告》,2018 年,用戶支出已經突破了 1010 億美元。用戶越來越習慣於在手機上完成各種事項,平均每天在移動設備上花費的時間已經達到 3 小時。隨着移動設備被廣泛使用,在移動互聯網產品應用深度學習和神經網絡技術已經成為必然趨勢。而移動端設備通常內存少、運算能力也比較弱小,並且移動端的 CPU 需要將功耗指標維持在很低的水平,當前主流的模型很難直接部署到移動設備中。在這種情況下,PaddleSlim 應運而生,實現了目前主流的網絡量化、剪枝、蒸餾三種壓縮策略,並可快速配置多種壓縮策略組合使用,在多種壓縮策略上達到了業績領先的效果。

深度學習技術已經在互聯網的諸多方向產生影響,關於深度學習和神經網絡的討論越來越多。深度學習技術近幾年在計算機視覺、語音識別、自然語言處理等領域大放異彩,各種互聯網產品都爭相應用深度學習技術,我們的生活中也越來越多的 AI 時代新能力,例如人臉識別、智能翻譯、語音助手等。

根據《2019 年移動市場報告》,2018 年,用戶支出已經突破了 1010 億美元。用戶越來越習慣於在手機上完成各種事項,平均每天在移動設備上花費的時間已經達到 3 小時。隨着移動設備被廣泛使用,在移動互聯網產品應用深度學習和神經網絡技術已經成為必然趨勢。而移動端設備通常內存少、運算能力也比較弱小,並且移動端的 CPU 需要將功耗指標維持在很低的水平,當前主流的模型很難直接部署到移動設備中。在這種情況下,PaddleSlim 應運而生,實現了目前主流的網絡量化、剪枝、蒸餾三種壓縮策略,並可快速配置多種壓縮策略組合使用,在多種壓縮策略上達到了業績領先的效果。

PaddleSlim架構圖

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

 

如圖所示,PaddleSlim 從上到下為 API 依賴關系。蒸餾、量化和剪切模塊都依賴底層的基礎框架。最上層為用戶接口,在 Python 腳本中調用模型壓縮功能時,只需要構造一個 Compressor 對象即可。我們將每個壓縮算法稱為壓縮策略,在迭代訓練模型的過程中調用用戶注冊的壓縮策略完成模型壓縮。模型壓縮工具封裝好了模型訓練邏輯,用戶只需要提供訓練模型需要的網絡結構、數據、優化策略(optimizer)等。

PaddleSlim 特點

接口簡單

  • 以配置文件方式集中管理可配參數,方便實驗管理
  • 在普通模型訓練腳本上,添加極少代碼即可完成模型壓縮

 

效果好

  • 對於冗余信息較少的 MobileNetv1 模型,卷積核剪切策略依然可縮減模型大小,並保持盡量少的精度損失。
  • 蒸餾壓縮策略可明顯提升原始模型的精度。
  • 量化訓練與蒸餾的組合使用,可同時做到縮減模型大小和提升模型精度。

 

功能更強更靈活

  • 剪切壓縮過程自動化
  • 剪切壓縮策略支持更多網絡結構
  • 蒸餾支持多種方式,用戶可自定義組合 loss
  • 支持快速配置多種壓縮策略組合使用

 

PaddleSlim 蒸餾、剪切、量化簡要介紹

蒸餾

模型蒸餾是將復雜網絡中的有用信息提取出來,遷移到一個更小的網絡中去,PaddleSlim 提供傳統的蒸餾方法和基於 FSP 的蒸餾方法。用戶可以在配置文件中,用 FSP_loss, L2_loss 和 softmax_with_cross_entropy_loss

這三種 loss 組合 teacher net 和 student net 的任意一層。

卷積核剪切

該策略通過減少指定卷積層中卷積核的數量,達到縮減模型大小和計算復雜度的目的。根據選取剪切比例的策略的不同,PaddleSlim 提供以下兩個方式:

  • uniform pruning: 每層剪切一樣比例的卷積核。在剪切一個卷積核之前,按 l1_norm 對 filter 從高到低排序,越靠后的 filter 越不重要,優先剪掉靠后的 filter.
  • sensitive pruning: 根據每層敏感度,剪切掉不同比例的卷積核數量。

 

兩種剪切方式都需要加載預訓練模型。

量化

PaddleSlim 為開發者提供在訓練過程中對量化進行建模以確定量化參數的 Quantization Aware Training 量化模式,提供更高的預測精度。現階段的量化訓練主要針對卷積層(包括二維卷積和 Depthwise 卷積)以及全連接層進行量化。卷積層和全連接層在 PaddlePaddle 框架中對應算子包括 conv2d、depthwise_conv2d 和 mul 等。量化訓練會對所有的 conv2d、depthwise_conv2d 和 mul 進行量化操作,且要求它們的輸入中必須包括激活和參數兩部分。

PaddleSlim 使用示例

該示例參考 PaddlePaddle/models/fluid/PaddleCV/image_classification 下代碼,分別實現了以下策略:

  • 蒸餾:用 ResNet50 對 MobileNetv1 的在 ImageNet 1000 數據上的蒸餾訓練。
  • 剪切:對預訓練好的 MobileNetv1 進行剪切
  • 量化:對預訓練好的 MobileNetv1 進行 int8 量化訓練
  • 蒸餾量化組合:先用 ResNet50 對 MobileNetv1 進行蒸餾,再對蒸餾后得到的模型進行 int8 量化訓練。
  • 剪切量化組合:先用 Uniform 剪切策略對 MobileNetv1 進行剪切,再對剪切后的模型進行 int8 量化訓練

 

本示例完整代碼鏈接:https://github.com/PaddlePaddle/models/tree/develop/fluid/PaddleSlim

使用方式:克隆 PaddlePaddle/models 到本地,並進入 models/fluid/PaddleSlim 路徑。

文件結構

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

 

 

本示例中的五個壓縮策略使用相同的訓練數據和壓縮 Python 腳本 compress.py,每種策略對應獨立的配置文件。

1. 數據准備

1.1 訓練數據准備

參考 models/fluid/PaddleCV/image_classification 下的數據准備教程准備訓練數據,並放入 PaddleSlim/data 路徑下。

1.2 預訓練模型准備

腳本 run.sh 會自動從 models/fluid/PaddleCV/image_classification 下載 ResNet50 和 MobileNetv1 的預訓練模型,並放入 PaddleSlim/pretrain 路徑下。

2. 壓縮腳本介紹

在 compress.py 中定義了執行壓縮任務需要的所有模型相關的信息,這里對幾個關鍵的步驟進行簡要介紹:

2.1 目標網絡的定義

compress.py 的以下代碼片段定義了 train program, 這里 train program 只有前向計算操作。

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

然后,通過 clone 方法得到 eval_program, 用來在壓縮過程中評估模型精度,如下:

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

定義完目標網絡結構,需要對其初始化,並根據需要加載預訓練模型。

2.2 定義 feed_list 和 fetch_list

對於 train program, 定義 train_feed_list 用於指定從 train data reader 中取的數據 feed 給哪些 variable。定義 train_fetch_list 用於指定在訓練時,需要在 log 中展示的結果。如果需要在訓練過程中在 log 中打印 accuracy 信心,則將 ('acc_top1', acc_top1.name) 添加到 train_fetch_list 中即可。

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

注意: 在 train_fetch_list 里必須有 loss 這一項。

對於 eval program. 同上定義 eval_feed_list 和 train_fetch_list:

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

2.3 定義 teacher 網絡

以下代碼片段定義了 teacher 網絡,並對其進行了初始化操作。

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

 

 

需要注意的是:

  • teacher 網絡只有一個輸入,直接 clone 在 train program(fluid.default_main_program) 中定義的 image 變量即可。
  • teacher 網絡的輸出只需要到 predict 即可,不用加 loss 和 accuracy 等操作。
  • teacher 網絡需要初始化並加載預訓練模型。

 

注意: ResNet50 和 MobileNetv1 的 fc layer 的 weight parameter 的名稱都為『fc_1.weight』,所以需要到 PaddleSlim/models/resnet.py 中修改一下 ResNet fc layer 的名稱, 同時,修改 ResNet50 pretrain model 中響應 weight 的文件名,使其與 resnet.py 中的名稱保持一致。

3. 執行壓縮策略示例

所有示例的執行命令都放在 run.sh 文件中,用戶可以修改 run.sh 后,執行不同的壓縮策略示例。

3.1 蒸餾

在該示例中,用預訓練好的 ResNet50 模型監督訓練 MobileNetv1 模型。修改 run.sh, 執行以下命令,執行蒸餾壓縮示例:

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

該示例在評估數據集上的准確率結果如下:

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

3.2 Uniform 剪切

在該示例中,將 MobileNetv1 模型剪掉 50% 的 FLOPS. 修改 run.sh, 執行以下命令,執行 Uniform 卷積核剪切模型壓縮示例:

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

該示例在評估數據集上的准確率結果如下:

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

3.3 敏感度剪切

在該示例中,將 MobileNetv1 模型剪掉 50% 的 FLOPS. 修改 run.sh, 執行以下命令,執行敏感度卷積核剪切壓縮示例:

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

該示例在評估數據集上的准確率結果如下:

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

3.4 int8 量化訓練

修改 run.sh, 執行以下命令,執行 int8 量化訓練示例:

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

該示例結果如下:

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

3.5 蒸餾后 int8 量化

本示例先用 ResNet50 模型對 MobileNetv1 蒸餾訓練 120 個 epochs,然后再對 MobileNetv1 模型進行動態 int8 量化訓練。修改 run.sh, 執行以下命令,執行蒸餾與 int8 量化訓練結合的模型壓縮示例:

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

該示例結果如下:

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

3.6 剪切后 int8 量化

本示例先將預訓練好的 MobileNetv1 模型剪掉 50% FLOPS, 讓后再對其進行動態 int8 量化訓練。修改 run.sh, 執行以下命令,執行剪切與 int8 量化訓練結合的模型壓縮示例:

 

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

該示例結果如下:

精度無損,體積壓縮70%以上,百度PaddleSlim為你的模型瘦身

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM