From f984f0580c9f0b8792a15af913567d079c37b2e6 Mon Sep 17 00:00:00 2001
From: Liufang Sang
Date: Sat, 12 Oct 2019 12:03:32 +0800
Subject: [PATCH] [PaddleSlim] add eval and infer cmd example in doc (#3519)
---
PaddleSlim/classification/eval.py | 34 +++++++++++---
PaddleSlim/classification/infer.py | 9 ++--
.../classification/quantization/README.md | 44 ++++++++++++++++++-
3 files changed, 77 insertions(+), 10 deletions(-)
diff --git a/PaddleSlim/classification/eval.py b/PaddleSlim/classification/eval.py
index 43e10659..f091a9e9 100644
--- a/PaddleSlim/classification/eval.py
+++ b/PaddleSlim/classification/eval.py
@@ -29,6 +29,8 @@ parser = argparse.ArgumentParser(description=__doc__)
add_arg = functools.partial(add_arguments, argparser=parser)
add_arg('use_gpu', bool, False, "Whether to use GPU or not.")
add_arg('model_path', str, "./pruning/checkpoints/resnet50/2/eval_model/", "Whether to use pretrained model.")
+add_arg('model_name', str, "__model__", "model filename for inference model")
+add_arg('params_name', str, "__params__", "params filename for inference model")
# yapf: enable
def eval(args):
@@ -39,8 +41,8 @@ def eval(args):
val_program, feed_target_names, fetch_targets = fluid.io.load_inference_model(args.model_path,
exe,
- model_filename="__model__",
- params_filename="__params__")
+ model_filename=args.model_name,
+ params_filename=args.params_name)
val_reader = paddle.batch(reader.val(), batch_size=128)
feeder = fluid.DataFeeder(place=place, feed_list=feed_target_names, program=val_program)
@@ -48,11 +50,33 @@ def eval(args):
for batch_id, data in enumerate(val_reader()):
# top1_acc, top5_acc
- result = exe.run(val_program,
+ if len(feed_target_names) == 1:
+ # eval "infer model", which input is image, output is classification probability
+ image = [[d[0]] for d in data]
+ label = [[d[1]] for d in data]
+ feed_data = feeder.feed(image)
+ pred = exe.run(val_program,
+ feed=feed_data,
+ fetch_list=fetch_targets)
+ pred = np.array(pred[0])
+ label = np.array(label)
+ sort_array = pred.argsort(axis=1)
+ top_1_pred = sort_array[:, -1:][:, ::-1]
+ top_1 = np.mean(label == top_1_pred)
+ top_5_pred = sort_array[:, -5:][:, ::-1]
+ acc_num = 0
+ for i in range(len(label)):
+ if label[i][0] in top_5_pred[i]:
+ acc_num += 1
+ top_5 = acc_num / len(label)
+ results.append([top_1, top_5])
+ else:
+ # eval "eval model", which inputs are image and label, output is top1 and top5 accuracy
+ result = exe.run(val_program,
feed=feeder.feed(data),
fetch_list=fetch_targets)
- result = [np.mean(r) for r in result]
- results.append(result)
+ result = [np.mean(r) for r in result]
+ results.append(result)
result = np.mean(np.array(results), axis=0)
print("top1_acc/top5_acc= {}".format(result))
sys.stdout.flush()
diff --git a/PaddleSlim/classification/infer.py b/PaddleSlim/classification/infer.py
index 127b1404..9f872301 100644
--- a/PaddleSlim/classification/infer.py
+++ b/PaddleSlim/classification/infer.py
@@ -29,6 +29,8 @@ parser = argparse.ArgumentParser(description=__doc__)
add_arg = functools.partial(add_arguments, argparser=parser)
add_arg('use_gpu', bool, False, "Whether to use GPU or not.")
add_arg('model_path', str, "./pruning/checkpoints/resnet50/2/eval_model/", "Whether to use pretrained model.")
+add_arg('model_name', str, "__model__.infer", "inference model filename")
+add_arg('params_name', str, "__params__", "inference model params filename")
# yapf: enable
def infer(args):
@@ -39,8 +41,8 @@ def infer(args):
test_program, feed_target_names, fetch_targets = fluid.io.load_inference_model(args.model_path,
exe,
- model_filename="__model__.infer",
- params_filename="__params__")
+ model_filename=args.model_name,
+ params_filename=args.params_name)
test_reader = paddle.batch(reader.test(), batch_size=1)
feeder = fluid.DataFeeder(place=place, feed_list=feed_target_names, program=test_program)
@@ -51,7 +53,8 @@ def infer(args):
result = exe.run(test_program,
feed=feeder.feed(data),
fetch_list=fetch_targets)
- print result
+ result = np.array(result[0])
+ print(result.argsort(axis=1)[:,-1:][::-1])
sys.stdout.flush()
def main():
diff --git a/PaddleSlim/classification/quantization/README.md b/PaddleSlim/classification/quantization/README.md
index be65ff71..77a81207 100644
--- a/PaddleSlim/classification/quantization/README.md
+++ b/PaddleSlim/classification/quantization/README.md
@@ -94,6 +94,13 @@ QuantizationFreezePass主要用于改变IrGraph中量化op和反量化op的顺
图4:应用TransformForMobilePass后的结果
+> 综上,可得在量化过程中有以下几种模型结构:
+1. 原始模型
+2. 经QuantizationTransformPass之后得到的适用于训练的量化模型结构,在${checkpoint_path}下保存的`eval_model`是这种结构,在训练过程中每个epoch结束时也使用这个网络结构进行评估,虽然这个模型结构不是最终想要的模型结构,但是每个epoch的评估结果可用来挑选模型。
+3. 经QuantizationFreezePass之后得到的FP32模型结构,具体结构已在上面进行介绍。本文档中列出的数据集的评估结果是对FP32模型结构进行评估得到的结果。这种模型结构在训练过程中只会保存一次,也就是在量化配置文件中设置的`end_epoch`结束时进行保存,如果想将其他epoch的训练结果转化成FP32模型,可使用脚本 PaddleSlim/classification/quantization/freeze.py进行转化,具体使用方法在[评估](#评估)中介绍。
+4. 经ConvertToInt8Pass之后得到的8-bit模型结构,具体结构已在上面进行介绍。这种模型结构在训练过程中只会保存一次,也就是在量化配置文件中设置的`end_epoch`结束时进行保存,如果想将其他epoch的训练结果转化成8-bit模型,可使用脚本 PaddleSlim/classification/quantization/freeze.py进行转化,具体使用方法在[评估](#评估)中介绍。
+5. 经TransformForMobilePass之后得到的mobile模型结构,具体结构已在上面进行介绍。这种模型结构在训练过程中只会保存一次,也就是在量化配置文件中设置的`end_epoch`结束时进行保存,如果想将其他epoch的训练结果转化成mobile模型,可使用脚本 PaddleSlim/classification/quantization/freeze.py进行转化,具体使用方法在[评估](#评估)中介绍。
+
## 评估
### 每个epoch保存的评估模型
@@ -106,14 +113,38 @@ QuantizationFreezePass主要用于改变IrGraph中量化op和反量化op的顺
脚本PaddleSlim/classification/eval.py中为使用该模型在评估数据集上做评估的示例。
-在评估之后,选取效果最好的epoch的模型,可使用脚本 PaddleSlim/classification/freeze.py将该模型转化为以上介绍的三种模型:FP32模型,8-bit模型,mobile模型,需要配置的参数为:
+运行命令示例:
+```
+python eval.py \
+ --use_gpu 1 \
+ --model_path ${checkpoint_path}/${epoch_id}/eval_model
+```
+
+在评估之后,选取效果最好的epoch的模型,可使用脚本 PaddleSlim/classification/quantization/freeze.py将该模型转化为以上介绍的三种模型:FP32模型,8-bit模型,mobile模型,需要配置的参数为:
- model_path, 加载的模型路径,`为${checkpoint_path}/${epoch_id}/eval_model/`
- weight_quant_type 模型参数的量化方式,和配置文件中的类型保持一致
- save_path `FP32`, `8-bit`, `mobile`模型的保存路径,分别为 `${save_path}/float/`, `${save_path}/int8/`, `${save_path}/mobile/`
+运行命令示例:
+```
+python freeze.py \
+ --model_path ${checkpoint_path}/${epoch_id}/eval_model/ \
+ --weight_quant_type ${weight_quant_type} \
+ --save_path ${any path you want}
+```
+
### 最终评估模型
-最终使用的评估模型是FP32模型,使用脚本PaddleSlim/classification/eval.py中为使用该模型在评估数据集上做评估的示例。
+最终使用的评估模型是FP32模型,使用脚本PaddleSlim/classification/eval.py该模型在评估数据集上做评估。
+运行命令示例:
+```
+python eval.py \
+ --use_gpu 1 \
+ --model_path ${save_path}/float \
+ --model_name model \
+ --params_name weights
+
+```
## 预测
@@ -123,6 +154,15 @@ FP32模型可直接使用原生PaddlePaddle Fluid预测方法进行预测。
在脚本PaddleSlim/classification/infer.py中展示了如何使用fluid python API加载使用预测模型进行预测。
+运行命令示例:
+```
+python infer.py \
+ --model_path ${save_path}/float \
+ --use_gpu 1 \
+ --model_name model \
+ --params_name weights
+```
+
### PaddleLite预测
FP32模型可使用Paddle-Lite进行加载预测,可参见教程[Paddle-Lite如何加载运行量化模型](https://github.com/PaddlePaddle/Paddle-Lite/wiki/model_quantization)。
--
GitLab