From 2f7b54da49faa38c1c1eda647c71004455580e78 Mon Sep 17 00:00:00 2001 From: zhouzj <41366441+zzjjay@users.noreply.github.com> Date: Tue, 6 Sep 2022 12:04:08 +0800 Subject: [PATCH] Add demo for evaling on paddle-inference. (#1412) --- .../semantic_segmentation/README.md | 12 ++ .../semantic_segmentation/infer.py | 125 +++++++++++++++--- 2 files changed, 116 insertions(+), 21 deletions(-) diff --git a/example/auto_compression/semantic_segmentation/README.md b/example/auto_compression/semantic_segmentation/README.md index a923ec35..8ea2a4a4 100644 --- a/example/auto_compression/semantic_segmentation/README.md +++ b/example/auto_compression/semantic_segmentation/README.md @@ -244,6 +244,18 @@ python infer.py \ --precision "int8" ``` +执行以下命令,使用Paddle Inference在相应数据集上测试精度: + +``` +export CUDA_VISIBLE_DEVICES=0 +python infer.py \ +--model_path "./pp_humanseg_qat/model.pdmodel" \ +--params_path "./pp_humanseg_qat/model.pdiparams" \ +--dataset_config configs/dataset/humanseg_dataset.yaml \ +--use_trt True \ +--precision "int8" +``` + diff --git a/example/auto_compression/semantic_segmentation/infer.py b/example/auto_compression/semantic_segmentation/infer.py index 5e556256..f806b576 100644 --- a/example/auto_compression/semantic_segmentation/infer.py +++ b/example/auto_compression/semantic_segmentation/infer.py @@ -12,19 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os import cv2 import numpy as np import argparse import time -import PIL -from PIL import Image +from tqdm import tqdm import paddle import paddleseg.transforms as T from paddleseg.cvlibs import Config as PaddleSegDataConfig from paddleseg.core.infer import reverse_transform -from paddleseg.utils import get_image_list from paddleseg.utils.visualize import get_pseudo_color_map +from paddleseg.utils import metrics from paddle.inference import create_predictor, PrecisionType from paddle.inference import Config as PredictConfig @@ -38,10 +36,9 @@ def _transforms(dataset): elif dataset == "cityscape": transforms.append(T.Normalize()) return transforms - return T.Compose(transforms) -def auto_tune_trt(args): +def auto_tune_trt(args, data): auto_tuned_shape_file = "./auto_tuning_shape" pred_cfg = PredictConfig(args.model_path, args.params_path) pred_cfg.enable_use_gpu(100, 0) @@ -49,18 +46,13 @@ def auto_tune_trt(args): predictor = create_predictor(pred_cfg) input_names = predictor.get_input_names() input_handle = predictor.get_input_handle(input_names[0]) - transforms = _transforms(args.dataset) - transform = T.Compose(transforms) - img = cv2.imread(args.image_file).astype('float32') - data, _ = transform(img) - data = np.array(data)[np.newaxis, :] input_handle.reshape(data.shape) input_handle.copy_from_cpu(data) predictor.run() return auto_tuned_shape_file -def load_predictor(args): +def load_predictor(args, data): pred_cfg = PredictConfig(args.model_path, args.params_path) pred_cfg.disable_glog_info() pred_cfg.enable_memory_optim() @@ -70,7 +62,7 @@ def load_predictor(args): if args.use_trt: # To collect the dynamic shapes of inputs for TensorRT engine - auto_tuned_shape_file = auto_tune_trt(args) + auto_tuned_shape_file = auto_tune_trt(args, data) precision_map = { "fp16": PrecisionType.Half, "fp32": PrecisionType.Float32, @@ -90,7 +82,7 @@ def load_predictor(args): return predictor -def predict_image(args, predictor): +def predict_image(args): transforms = _transforms(args.dataset) transform = T.Compose(transforms) @@ -100,7 +92,10 @@ def predict_image(args, predictor): data, _ = transform(im) data = np.array(data)[np.newaxis, :] - # Step2: Inference + # Step2: Prepare prdictor + predictor = load_predictor(args, data) + + # Step3: Inference input_names = predictor.get_input_names() input_handle = predictor.get_input_handle(input_names[0]) output_names = predictor.get_output_names() @@ -123,26 +118,107 @@ def predict_image(args, predictor): avg_time = float(total_time) / repeats print(f"Average inference time: \033[91m{round(avg_time*1000, 2)}ms\033[0m") - # Step3: Post process + # Step4: Post process if args.dataset == "human": results = reverse_transform( paddle.to_tensor(results), im.shape, transforms, mode='bilinear') results = np.argmax(results, axis=1) result = get_pseudo_color_map(results[0]) - # Step4: Save result to file + # Step5: Save result to file if args.save_file is not None: result.save(args.save_file) print(f"Saved result to \033[91m{args.save_file}\033[0m") +def eval(args): + # DataLoader need run on cpu + paddle.set_device('cpu') + data_cfg = PaddleSegDataConfig(args.dataset_config) + eval_dataset = data_cfg.val_dataset + + batch_sampler = paddle.io.BatchSampler( + eval_dataset, batch_size=1, shuffle=False, drop_last=False) + loader = paddle.io.DataLoader( + eval_dataset, + batch_sampler=batch_sampler, + num_workers=1, + return_list=True) + + total_iters = len(loader) + intersect_area_all = 0 + pred_area_all = 0 + label_area_all = 0 + + print("Start evaluating (total_samples: {}, total_iters: {})...".format( + len(eval_dataset), total_iters)) + + init_predictor = False + for (image, label) in tqdm(loader): + label = np.array(label).astype('int64') + ori_shape = np.array(label).shape[-2:] + data = np.array(image) + + if not init_predictor: + predictor = load_predictor(args, data) + init_predictor = True + + input_names = predictor.get_input_names() + input_handle = predictor.get_input_handle(input_names[0]) + input_handle.reshape(data.shape) + input_handle.copy_from_cpu(data) + + predictor.run() + + output_names = predictor.get_output_names() + output_handle = predictor.get_output_handle(output_names[0]) + results = output_handle.copy_to_cpu() + + logit = reverse_transform( + paddle.to_tensor(results), + ori_shape, + eval_dataset.transforms.transforms, + mode='bilinear') + pred = paddle.to_tensor(logit) + if len( + pred.shape + ) == 4: # for humanseg model whose prediction is distribution but not class id + pred = paddle.argmax(pred, axis=1, keepdim=True, dtype='int32') + + intersect_area, pred_area, label_area = metrics.calculate_area( + pred, + paddle.to_tensor(label), + eval_dataset.num_classes, + ignore_index=eval_dataset.ignore_index) + intersect_area_all = intersect_area_all + intersect_area + pred_area_all = pred_area_all + pred_area + label_area_all = label_area_all + label_area + + class_iou, miou = metrics.mean_iou(intersect_area_all, pred_area_all, + label_area_all) + class_acc, acc = metrics.accuracy(intersect_area_all, pred_area_all) + kappa = metrics.kappa(intersect_area_all, pred_area_all, label_area_all) + class_dice, mdice = metrics.dice(intersect_area_all, pred_area_all, + label_area_all) + + infor = "[EVAL] #Images: {} mIoU: {:.4f} Acc: {:.4f} Kappa: {:.4f} Dice: {:.4f}".format( + len(eval_dataset), miou, acc, kappa, mdice) + print(infor) + + if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument( - '--image_file', type=str, help="Image path to be processed.") + '--image_file', + type=str, + default=None, + help="Image path to be processed.") parser.add_argument( - '--save_file', type=str, help="The path to save the processed image.") + '--save_file', + type=str, + default=None, + help="The path to save the processed image.") parser.add_argument( '--model_path', type=str, help="Inference model filepath.") parser.add_argument( @@ -153,6 +229,11 @@ if __name__ == '__main__': default="human", choices=["human", "cityscape"], help="The type of given image which can be 'human' or 'cityscape'.") + parser.add_argument( + '--dataset_config', + type=str, + default=None, + help="path of dataset config.") parser.add_argument( '--benchmark', type=bool, @@ -178,5 +259,7 @@ if __name__ == '__main__': help="The precision of inference. It can be 'fp32', 'fp16' or 'int8'. Default is 'fp16'." ) args = parser.parse_args() - predictor = load_predictor(args) - predict_image(args, predictor) + if args.image_file: + predict_image(args) + else: + eval(args) -- GitLab