Эх сурвалжийг харах

Merge pull request #382 from PaddlePaddle/doc1105

Doc1105
Jason 5 жил өмнө
parent
commit
7f6cff18da

+ 14 - 0
docs/slim/index.rst

@@ -0,0 +1,14 @@
+模型压缩
+=======================================
+
+PaddleX集成了PaddleSlim, 可帮助用户对模型进行裁剪和量化,减小模型的计算量和体积,提升模型的预测性能。
+
+- 模型裁剪多适用于低性能设备,如CPU、移动端和端侧部署时使用,对于性能较好的GPU,裁剪不一定能带来性能的提升。
+- 模型量化将模型的浮点型计算转为整型计算,从而加速模型的预测速度,减小模型的体积,对于PaddleLite在Arm设备上部署性能有明显提升。
+
+.. toctree::
+   :maxdepth: 1
+   :caption: 文档目录:
+
+   prune.md
+   quant.md

+ 78 - 0
docs/slim/prune.md

@@ -0,0 +1,78 @@
+# 模型裁剪
+
+模型裁剪可以更好地满足在端侧、移动端上部署场景下的性能需求,可以有效得降低模型的体积,以及计算量,加速预测性能。PaddleX集成了PaddleSlim的基于敏感度的通道裁剪算法,用户可以在PaddleX的训练代码里轻松使用起来。
+
+在本文档中展示了分类模型的裁剪过程,文档中代码以及更多其它模型的的裁剪代码可在Github中的[tutorials/slim/prune](https://github.com/PaddlePaddle/PaddleX/tree/develop/tutorials/slim/prune)目录获取。
+
+
+## 使用方法
+
+模型裁剪相对比我们普通训练一个模型,步骤会多出两步
+
+- 1.采用正常的方式训练一个模型  
+- 2.对模型的参数进行敏感度分析
+- 3.根据第2步得到的敏感度信息,对模型进行裁剪,并以第1步训练好的模型作为预训练权重,继续进行训练
+
+具体我们以图像分类模型MobileNetV2为例,本示例中所有代码均可在Github的[tutorials/slim/prune/image_classification]中获得。
+
+### 第一步 正常训练模型
+
+此步骤中采用正常的代码进行模型训练,在获取[本示例代码](https://github.com/PaddlePaddle/PaddleX/tree/develop/tutorials/slim/prune/image_classification)后,直接执行如下命令即可
+```
+python mobilenetv2_train.py
+```
+在训练完成后,我们以`output/mobilenetv2/best_model`保存的模型,继续接下来的步骤
+
+
+### 第二步 参数敏感度分析
+
+此步骤中,我们需要加载第一步训练保存的模型,并通过不断地遍历参数,分析各参数裁剪后在验证数据集上的精度损失,以此判断各参数的敏感度。敏感度分析的代码很简单, 用户可直接查看[params_analysis.py](https://github.com/PaddlePaddle/PaddleX/tree/develop/tutorials/slim/prune/image_classification)。在命令行终端执行如下命令开始参数分析。
+```
+python params_analysis.py
+```
+
+在此步骤中,我们会得到保存的`mobilenetv2.sensi.data`文件,这个文件保存了模型中每个参数的敏感度,在后续的裁剪训练中,会根据此文件中保存的信息,对各个参数进行裁剪。同时,我们也可以对这个文件进行可视化分析,判断`eval_metric_loss`的大小设置与模型被裁剪比例的关系。(`eval_metric_loss`的说明见第三步)
+
+模型裁剪比例可视化分析代码见[slim_visualize.py](https://github.com/PaddlePaddle/PaddleX/tree/develop/tutorials/slim/prune/image_classification),执行如下命令即可
+```
+python slim_visualize.py
+```
+可视化结果如下,该图表明,当我们将`eval_metric_loss`设为0.05时,模型将被裁剪掉65%;将`eval_metric_loss`设为0.10,模型将被裁剪掉68.0%。因此在实际使用时,我们可以根据自己的需求,去设置`eval_metric_loss`控制裁剪比例。
+
+### 第三步 模型裁剪训练
+
+在前两步,我们得到了正常训练保存的模型`output/mobilenetv2/best_model`和基于该保存模型得到的参数敏感度信息文件`mobilenetv2.sensi.data`,接下来则是进行模型裁剪训练。  
+模型裁剪训练的代码第第一步基本一致,唯一区别在最后的`train`函数中,我们修改了`pretrain_weights`,`save_dir`,`sensitivities_file`和`eval_metric_loss`四个参数,如下所示
+```
+model.train(
+	num_epoch=10,
+	train_dataset=train_dataset,
+	train_batch_size=32,
+	eval_dataset=eval_dataset,
+	lr_decay_epochs=[4,6,8],
+	learning_rate=0.025,
+	pretrain_weights='output/mobilenetv2/best_model',
+	save_dir='output/mobilenetv2_prune',
+	sensitivities_file='./mobilenetv2.sensi.data',
+	eval_metric_loss=0.05,
+	use_vdl=True)
+```
+具体代码见[tutorials/slim/prune/image_classification/mobilenetv2_prune_train.py](https://github.com/PaddlePaddle/PaddleX/tree/develop/tutorials/slim/prune/image_classification),执行如下命令即可
+```
+python mobilenetv2_prune_train.py
+```
+其中修改的4个参数函数如下
+- pretrain_weights: 预训练权重,在裁剪训练中,将其指定为第一步正常训练得到的模型路径
+- save_dir: 裁剪训练过程中,模型保存的新路径
+- sensitivities_file: 第二步中分析得到的各参数敏感度信息文件
+- eval_metric_loss: 可用于控制模型最终被裁剪的比例,见第二步中的可视化说明
+
+## 裁剪效果
+
+在本示例的数据集上,经过裁剪训练后,模型的效果对比如下,其中预测速度不包括图像的预处理和结果的后处理。  
+从表中可以看到,对于本示例中的简单数据集,模型裁剪掉68%后,模型准确度没有降低,在CPU的单张图片预测用时减少了37%
+
+| 模型 | 参数大小 | CPU预测速度(MKLDNN关闭) | 准确率 |
+| :--- | :----- | :-------------------- | :--- |
+| output/mobilenetv2/best_model | 8.7M | 0.057s | 0.92 | 
+| output/mobilenetv2_prune/best_model | 2.8M | 0.036s | 0.99 |

+ 36 - 0
docs/slim/quant.md

@@ -0,0 +1,36 @@
+# 模型量化
+
+模型量化将模型的计算从浮点型转为整型,从而加速模型的预测计算速度,在移动端/边缘端设备上降低模型的体积。
+
+> 注:量化后的模型,通过PaddleLite转换为PaddleLite部署的模型格式后,模型体积将会大幅压缩。如若量化后的模型仍是以服务端本地部署格式(文件包括__model__和__params__),那么模型的文件大小是无法呈现参数变化情况的。
+
+## 使用方法
+
+PaddleX中已经将量化功能作为模型导出的一个API,代码使用方式如下,本示例代码和模型数据均可通过GitHub项目上代码[tutorials/slim/quant/image_classification](https://github.com/PaddlePaddle/PaddleX/tree/develop/tutorials/slim/quant/image_classification)获取得到
+```
+import paddlex as pdx
+model = pdx.load_model('mobilenetv2_vegetables')
+# 加载数据集用于量化
+dataset = pdx.datasets.ImageNet(
+                data_dir='vegetables_cls',
+                file_list='vegetables_cls/train_list.txt',
+                label_list='vegetables_cls/labels.txt',
+                transforms=model.test_transforms)
+
+# 开始量化
+pdx.slim.export_quant_model(model, dataset, 
+	                  save_dir='./quant_mobilenet', 
+	                  cache_dir='./tmp')
+```
+
+在获取本示例代码后,执行如下命令即可完成量化和PaddleLite的模型导出
+```
+# 将mobilenetv2模型量化保存
+python mobilenetv2_quant.py
+# 将量化后的模型导出为PaddleLite部署格式
+python paddlelite_export.py
+```
+
+## 量化效果
+
+在本示例中,我们可以看到模型量化后的服务端部署模型格式`server_mobilenet`和`quant_mobilenet`两个目录中,模型参数大小并无变化。 但在使用PaddleLite导出后,`mobilenetv2.nb`和`mobilenetv2_quant.nb`大小分别为8.8M, 2.7M,压缩至原来的31%。