eval.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. # Copyright (c) 2019 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. from __future__ import absolute_import
  15. from __future__ import division
  16. from __future__ import print_function
  17. import os
  18. import sys
  19. # add python path of PadleDetection to sys.path
  20. parent_path = os.path.abspath(os.path.join(__file__, *(['..'] * 3)))
  21. if parent_path not in sys.path:
  22. sys.path.append(parent_path)
  23. import paddle.fluid as fluid
  24. import logging
  25. FORMAT = '%(asctime)s-%(levelname)s: %(message)s'
  26. logging.basicConfig(level=logging.INFO, format=FORMAT)
  27. logger = logging.getLogger(__name__)
  28. try:
  29. from ppdet.utils.eval_utils import parse_fetches, eval_run, eval_results, json_eval_results
  30. import ppdet.utils.checkpoint as checkpoint
  31. from ppdet.utils.check import check_gpu, check_version, check_config, enable_static_mode
  32. from ppdet.data.reader import create_reader
  33. from ppdet.core.workspace import load_config, merge_config, create
  34. from ppdet.utils.cli import ArgsParser
  35. except ImportError as e:
  36. if sys.argv[0].find('static') >= 0:
  37. logger.error("Importing ppdet failed when running static model "
  38. "with error: {}\n"
  39. "please try:\n"
  40. "\t1. run static model under PaddleDetection/static "
  41. "directory\n"
  42. "\t2. run 'pip uninstall ppdet' to uninstall ppdet "
  43. "dynamic version firstly.".format(e))
  44. sys.exit(-1)
  45. else:
  46. raise e
  47. # import paddleslim
  48. from paddleslim.quant import quant_aware, convert
  49. def main():
  50. """
  51. Main evaluate function
  52. """
  53. cfg = load_config(FLAGS.config)
  54. merge_config(FLAGS.opt)
  55. check_config(cfg)
  56. # check if set use_gpu=True in paddlepaddle cpu version
  57. check_gpu(cfg.use_gpu)
  58. # check if paddlepaddle version is satisfied
  59. check_version()
  60. main_arch = cfg.architecture
  61. # define executor
  62. place = fluid.CUDAPlace(0) if cfg.use_gpu else fluid.CPUPlace()
  63. exe = fluid.Executor(place)
  64. # build program
  65. model = create(main_arch)
  66. startup_prog = fluid.Program()
  67. eval_prog = fluid.Program()
  68. with fluid.program_guard(eval_prog, startup_prog):
  69. with fluid.unique_name.guard():
  70. inputs_def = cfg['EvalReader']['inputs_def']
  71. test_feed_vars, loader = model.build_inputs(**inputs_def)
  72. test_fetches = model.eval(test_feed_vars)
  73. eval_prog = eval_prog.clone(True)
  74. reader = create_reader(cfg.EvalReader)
  75. # When iterable mode, set set_sample_list_generator(reader, place)
  76. loader.set_sample_list_generator(reader)
  77. # eval already exists json file
  78. if FLAGS.json_eval:
  79. logger.info(
  80. "In json_eval mode, PaddleDetection will evaluate json files in "
  81. "output_eval directly. And proposal.json, bbox.json and mask.json "
  82. "will be detected by default.")
  83. json_eval_results(
  84. cfg.metric, json_directory=FLAGS.output_eval, dataset=dataset)
  85. return
  86. assert cfg.metric != 'OID', "eval process of OID dataset \
  87. is not supported."
  88. if cfg.metric == "WIDERFACE":
  89. raise ValueError("metric type {} does not support in tools/eval.py, "
  90. "please use tools/face_eval.py".format(cfg.metric))
  91. assert cfg.metric in ['COCO', 'VOC'], \
  92. "unknown metric type {}".format(cfg.metric)
  93. extra_keys = []
  94. if cfg.metric == 'COCO':
  95. extra_keys = ['im_info', 'im_id', 'im_shape']
  96. if cfg.metric == 'VOC':
  97. extra_keys = ['gt_bbox', 'gt_class', 'is_difficult']
  98. keys, values, cls = parse_fetches(test_fetches, eval_prog, extra_keys)
  99. # whether output bbox is normalized in model output layer
  100. is_bbox_normalized = False
  101. if hasattr(model, 'is_bbox_normalized') and \
  102. callable(model.is_bbox_normalized):
  103. is_bbox_normalized = model.is_bbox_normalized()
  104. dataset = cfg['EvalReader']['dataset']
  105. sub_eval_prog = None
  106. sub_keys = None
  107. sub_values = None
  108. not_quant_pattern = []
  109. if FLAGS.not_quant_pattern:
  110. not_quant_pattern = FLAGS.not_quant_pattern
  111. config = {
  112. 'weight_quantize_type': 'channel_wise_abs_max',
  113. 'activation_quantize_type': 'moving_average_abs_max',
  114. 'quantize_op_types': ['depthwise_conv2d', 'mul', 'conv2d'],
  115. 'not_quant_pattern': not_quant_pattern
  116. }
  117. eval_prog = quant_aware(eval_prog, place, config, for_test=True)
  118. # load model
  119. exe.run(startup_prog)
  120. if 'weights' in cfg:
  121. checkpoint.load_params(exe, eval_prog, cfg.weights)
  122. eval_prog = convert(eval_prog, place, config, save_int8=False)
  123. compile_program = fluid.CompiledProgram(eval_prog).with_data_parallel()
  124. results = eval_run(exe, compile_program, loader, keys, values, cls, cfg,
  125. sub_eval_prog, sub_keys, sub_values)
  126. # evaluation
  127. resolution = None
  128. if 'mask' in results[0]:
  129. resolution = model.mask_head.resolution
  130. # if map_type not set, use default 11point, only use in VOC eval
  131. map_type = cfg.map_type if 'map_type' in cfg else '11point'
  132. eval_results(
  133. results,
  134. cfg.metric,
  135. cfg.num_classes,
  136. resolution,
  137. is_bbox_normalized,
  138. FLAGS.output_eval,
  139. map_type,
  140. dataset=dataset)
  141. if __name__ == '__main__':
  142. enable_static_mode()
  143. parser = ArgsParser()
  144. parser.add_argument(
  145. "--json_eval",
  146. action='store_true',
  147. default=False,
  148. help="Whether to re eval with already exists bbox.json or mask.json")
  149. parser.add_argument(
  150. "-f",
  151. "--output_eval",
  152. default=None,
  153. type=str,
  154. help="Evaluation file directory, default is current directory.")
  155. parser.add_argument(
  156. "--not_quant_pattern",
  157. nargs='+',
  158. type=str,
  159. help="Layers which name_scope contains string in not_quant_pattern will not be quantized"
  160. )
  161. FLAGS = parser.parse_args()
  162. main()