|
| 1 | +# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. |
| 2 | +# |
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +# you may not use this file except in compliance with the License. |
| 5 | +# You may obtain a copy of the License at |
| 6 | +# |
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +# |
| 9 | +# Unless required by applicable law or agreed to in writing, software |
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +# See the License for the specific language governing permissions and |
| 13 | +# limitations under the License. |
| 14 | + |
| 15 | +import argparse |
| 16 | +import codecs |
| 17 | +import os |
| 18 | +import sys |
| 19 | + |
| 20 | +import time |
| 21 | +import yaml |
| 22 | +import numpy as np |
| 23 | +import paddle |
| 24 | + |
| 25 | +LOCAL_PATH = os.path.dirname(os.path.abspath(__file__)) |
| 26 | +sys.path.append(os.path.join(LOCAL_PATH, '..', '..')) |
| 27 | + |
| 28 | +from paddleseg.cvlibs import manager |
| 29 | +from paddleseg.utils import logger, metrics, progbar |
| 30 | + |
| 31 | +from infer import Predictor |
| 32 | + |
| 33 | + |
| 34 | +def parse_args(): |
| 35 | + parser = argparse.ArgumentParser(description='Model Infer') |
| 36 | + parser.add_argument( |
| 37 | + "--config", |
| 38 | + dest="cfg", |
| 39 | + help="The config file.", |
| 40 | + default=None, |
| 41 | + type=str, |
| 42 | + required=True) |
| 43 | + |
| 44 | + parser.add_argument( |
| 45 | + '--dataset_type', |
| 46 | + dest='dataset_type', |
| 47 | + help='The name of dataset, such as Cityscapes, PascalVOC and ADE20K.', |
| 48 | + type=str, |
| 49 | + default=None, |
| 50 | + required=True) |
| 51 | + parser.add_argument( |
| 52 | + '--dataset_path', |
| 53 | + dest='dataset_path', |
| 54 | + help='The directory of the dataset to be predicted. If set dataset_path, ' |
| 55 | + 'it use the test and label images to calculate the mIoU.', |
| 56 | + type=str, |
| 57 | + default=None, |
| 58 | + required=True) |
| 59 | + parser.add_argument( |
| 60 | + '--dataset_mode', |
| 61 | + dest='dataset_mode', |
| 62 | + help='The dataset mode, such as train, val.', |
| 63 | + type=str, |
| 64 | + default="val") |
| 65 | + parser.add_argument( |
| 66 | + '--batch_size', |
| 67 | + dest='batch_size', |
| 68 | + help='Mini batch size of one gpu or cpu.', |
| 69 | + type=int, |
| 70 | + default=1) |
| 71 | + |
| 72 | + parser.add_argument( |
| 73 | + '--device', |
| 74 | + choices=['cpu', 'gpu'], |
| 75 | + default="gpu", |
| 76 | + help="Select which device to inference, defaults to gpu.") |
| 77 | + |
| 78 | + parser.add_argument( |
| 79 | + '--use_trt', |
| 80 | + default=False, |
| 81 | + type=eval, |
| 82 | + choices=[True, False], |
| 83 | + help='Whether to use Nvidia TensorRT to accelerate prediction.') |
| 84 | + parser.add_argument( |
| 85 | + "--precision", |
| 86 | + default="fp32", |
| 87 | + type=str, |
| 88 | + choices=["fp32", "fp16", "int8"], |
| 89 | + help='The tensorrt precision.') |
| 90 | + |
| 91 | + parser.add_argument( |
| 92 | + '--cpu_threads', |
| 93 | + default=10, |
| 94 | + type=int, |
| 95 | + help='Number of threads to predict when using cpu.') |
| 96 | + parser.add_argument( |
| 97 | + '--enable_mkldnn', |
| 98 | + default=False, |
| 99 | + type=eval, |
| 100 | + choices=[True, False], |
| 101 | + help='Enable to use mkldnn to speed up when using cpu.') |
| 102 | + |
| 103 | + parser.add_argument( |
| 104 | + '--with_argmax', |
| 105 | + dest='with_argmax', |
| 106 | + help='Perform argmax operation on the predict result.', |
| 107 | + action='store_true') |
| 108 | + |
| 109 | + parser.add_argument( |
| 110 | + '--print_detail', |
| 111 | + dest='print_detail', |
| 112 | + help='Print GLOG information of Paddle Inference.', |
| 113 | + action='store_true') |
| 114 | + |
| 115 | + return parser.parse_args() |
| 116 | + |
| 117 | + |
| 118 | +class DatasetPredictor(Predictor): |
| 119 | + def __init__(self, args): |
| 120 | + super().__init__(args) |
| 121 | + |
| 122 | + def test_dataset(self): |
| 123 | + """ |
| 124 | + Read the data from dataset and calculate the accurary of the inference model. |
| 125 | + """ |
| 126 | + comp = manager.DATASETS |
| 127 | + if self.args.dataset_type not in comp.components_dict: |
| 128 | + raise RuntimeError("The dataset is not supported.") |
| 129 | + kwargs = { |
| 130 | + 'transforms': self.cfg.transforms.transforms, |
| 131 | + 'dataset_root': self.args.dataset_path, |
| 132 | + 'mode': self.args.dataset_mode |
| 133 | + } |
| 134 | + dataset = comp[self.args.dataset_type](**kwargs) |
| 135 | + |
| 136 | + input_names = self.predictor.get_input_names() |
| 137 | + input_handle = self.predictor.get_input_handle(input_names[0]) |
| 138 | + output_names = self.predictor.get_output_names() |
| 139 | + output_handle = self.predictor.get_output_handle(output_names[0]) |
| 140 | + |
| 141 | + intersect_area_all = 0 |
| 142 | + pred_area_all = 0 |
| 143 | + label_area_all = 0 |
| 144 | + total_time = 0 |
| 145 | + progbar_val = progbar.Progbar(target=len(dataset), verbose=1) |
| 146 | + |
| 147 | + for idx, (img, label) in enumerate(dataset): |
| 148 | + data = np.array([img]) |
| 149 | + input_handle.reshape(data.shape) |
| 150 | + input_handle.copy_from_cpu(data) |
| 151 | + |
| 152 | + start_time = time.time() |
| 153 | + self.predictor.run() |
| 154 | + end_time = time.time() |
| 155 | + total_time += (end_time - start_time) |
| 156 | + |
| 157 | + pred = output_handle.copy_to_cpu() |
| 158 | + pred = self.postprocess(paddle.to_tensor(pred)) |
| 159 | + label = paddle.to_tensor(label, dtype="int32") |
| 160 | + |
| 161 | + intersect_area, pred_area, label_area = metrics.calculate_area( |
| 162 | + pred, |
| 163 | + label, |
| 164 | + dataset.num_classes, |
| 165 | + ignore_index=dataset.ignore_index) |
| 166 | + |
| 167 | + intersect_area_all = intersect_area_all + intersect_area |
| 168 | + pred_area_all = pred_area_all + pred_area |
| 169 | + label_area_all = label_area_all + label_area |
| 170 | + |
| 171 | + progbar_val.update(idx + 1) |
| 172 | + |
| 173 | + class_iou, miou = metrics.mean_iou(intersect_area_all, pred_area_all, |
| 174 | + label_area_all) |
| 175 | + class_acc, acc = metrics.accuracy(intersect_area_all, pred_area_all) |
| 176 | + kappa = metrics.kappa(intersect_area_all, pred_area_all, label_area_all) |
| 177 | + |
| 178 | + logger.info( |
| 179 | + "[EVAL] #Images: {} mIoU: {:.4f} Acc: {:.4f} Kappa: {:.4f} ".format( |
| 180 | + len(dataset), miou, acc, kappa)) |
| 181 | + logger.info("[EVAL] Class IoU: \n" + str(np.round(class_iou, 4))) |
| 182 | + logger.info("[EVAL] Class Acc: \n" + str(np.round(class_acc, 4))) |
| 183 | + logger.info("[EVAL] Average time: %.3f second/img" % |
| 184 | + (total_time / len(dataset))) |
| 185 | + |
| 186 | + |
| 187 | +def main(args): |
| 188 | + predictor = DatasetPredictor(args) |
| 189 | + if args.dataset_type and args.dataset_path: |
| 190 | + predictor.test_dataset() |
| 191 | + else: |
| 192 | + raise RuntimeError("Please set dataset_type and dataset_path.") |
| 193 | + |
| 194 | + |
| 195 | +if __name__ == '__main__': |
| 196 | + """ |
| 197 | + Based on the infer config and dataset, this program read the test and |
| 198 | + label images, applys the transfors, run the predictor, ouput the accuracy. |
| 199 | +
|
| 200 | + For example: |
| 201 | + python deploy/python/infer_benchmark.py \ |
| 202 | + --config path/to/bisenetv2/deploy.yaml \ |
| 203 | + --dataset_type Cityscapes \ |
| 204 | + --dataset_path path/to/cityscapes |
| 205 | + """ |
| 206 | + args = parse_args() |
| 207 | + main(args) |
0 commit comments