| | |
| | |
| | |
| |
|
| | import argparse |
| | import os |
| | import random |
| | import warnings |
| | from loguru import logger |
| |
|
| | import torch |
| | import torch.backends.cudnn as cudnn |
| | from torch.nn.parallel import DistributedDataParallel as DDP |
| |
|
| | from yolox.core import launch |
| | from yolox.exp import get_exp |
| | from yolox.utils import ( |
| | configure_module, |
| | configure_nccl, |
| | fuse_model, |
| | get_local_rank, |
| | get_model_info, |
| | setup_logger |
| | ) |
| |
|
| |
|
| | def make_parser(): |
| | parser = argparse.ArgumentParser("YOLOX Eval") |
| | parser.add_argument("-expn", "--experiment-name", type=str, default=None) |
| | parser.add_argument("-n", "--name", type=str, default=None, help="model name") |
| |
|
| | |
| | parser.add_argument( |
| | "--dist-backend", default="nccl", type=str, help="distributed backend" |
| | ) |
| | parser.add_argument( |
| | "--dist-url", |
| | default=None, |
| | type=str, |
| | help="url used to set up distributed training", |
| | ) |
| | parser.add_argument("-b", "--batch-size", type=int, default=64, help="batch size") |
| | parser.add_argument( |
| | "-d", "--devices", default=None, type=int, help="device for training" |
| | ) |
| | parser.add_argument( |
| | "--num_machines", default=1, type=int, help="num of node for training" |
| | ) |
| | parser.add_argument( |
| | "--machine_rank", default=0, type=int, help="node rank for multi-node training" |
| | ) |
| | parser.add_argument( |
| | "-f", |
| | "--exp_file", |
| | default=None, |
| | type=str, |
| | help="please input your experiment description file", |
| | ) |
| | parser.add_argument("-c", "--ckpt", default=None, type=str, help="ckpt for eval") |
| | parser.add_argument("--conf", default=None, type=float, help="test conf") |
| | parser.add_argument("--nms", default=None, type=float, help="test nms threshold") |
| | parser.add_argument("--tsize", default=None, type=int, help="test img size") |
| | parser.add_argument("--seed", default=None, type=int, help="eval seed") |
| | parser.add_argument( |
| | "--fp16", |
| | dest="fp16", |
| | default=False, |
| | action="store_true", |
| | help="Adopting mix precision evaluating.", |
| | ) |
| | parser.add_argument( |
| | "--fuse", |
| | dest="fuse", |
| | default=False, |
| | action="store_true", |
| | help="Fuse conv and bn for testing.", |
| | ) |
| | parser.add_argument( |
| | "--trt", |
| | dest="trt", |
| | default=False, |
| | action="store_true", |
| | help="Using TensorRT model for testing.", |
| | ) |
| | parser.add_argument( |
| | "--legacy", |
| | dest="legacy", |
| | default=False, |
| | action="store_true", |
| | help="To be compatible with older versions", |
| | ) |
| | parser.add_argument( |
| | "--test", |
| | dest="test", |
| | default=False, |
| | action="store_true", |
| | help="Evaluating on test-dev set.", |
| | ) |
| | parser.add_argument( |
| | "--speed", |
| | dest="speed", |
| | default=False, |
| | action="store_true", |
| | help="speed test only.", |
| | ) |
| | parser.add_argument( |
| | "opts", |
| | help="Modify config options using the command-line", |
| | default=None, |
| | nargs=argparse.REMAINDER, |
| | ) |
| | return parser |
| |
|
| |
|
| | @logger.catch |
| | def main(exp, args, num_gpu): |
| | if args.seed is not None: |
| | random.seed(args.seed) |
| | torch.manual_seed(args.seed) |
| | cudnn.deterministic = True |
| | warnings.warn( |
| | "You have chosen to seed testing. This will turn on the CUDNN deterministic setting, " |
| | ) |
| |
|
| | is_distributed = num_gpu > 1 |
| |
|
| | |
| | configure_nccl() |
| | cudnn.benchmark = True |
| |
|
| | rank = get_local_rank() |
| |
|
| | file_name = os.path.join(exp.output_dir, args.experiment_name) |
| |
|
| | if rank == 0: |
| | os.makedirs(file_name, exist_ok=True) |
| |
|
| | setup_logger(file_name, distributed_rank=rank, filename="val_log.txt", mode="a") |
| | logger.info("Args: {}".format(args)) |
| |
|
| | if args.conf is not None: |
| | exp.test_conf = args.conf |
| | if args.nms is not None: |
| | exp.nmsthre = args.nms |
| | if args.tsize is not None: |
| | exp.test_size = (args.tsize, args.tsize) |
| |
|
| | model = exp.get_model() |
| | logger.info("Model Summary: {}".format(get_model_info(model, exp.test_size))) |
| | logger.info("Model Structure:\n{}".format(str(model))) |
| |
|
| | evaluator = exp.get_evaluator(args.batch_size, is_distributed, args.test, args.legacy) |
| | evaluator.per_class_AP = True |
| | evaluator.per_class_AR = True |
| |
|
| | torch.cuda.set_device(rank) |
| | model.cuda(rank) |
| | model.eval() |
| |
|
| | if not args.speed and not args.trt: |
| | if args.ckpt is None: |
| | ckpt_file = os.path.join(file_name, "best_ckpt.pth") |
| | else: |
| | ckpt_file = args.ckpt |
| | logger.info("loading checkpoint from {}".format(ckpt_file)) |
| | loc = "cuda:{}".format(rank) |
| | ckpt = torch.load(ckpt_file, map_location=loc) |
| | model.load_state_dict(ckpt["model"]) |
| | logger.info("loaded checkpoint done.") |
| |
|
| | if is_distributed: |
| | model = DDP(model, device_ids=[rank]) |
| |
|
| | if args.fuse: |
| | logger.info("\tFusing model...") |
| | model = fuse_model(model) |
| |
|
| | if args.trt: |
| | assert ( |
| | not args.fuse and not is_distributed and args.batch_size == 1 |
| | ), "TensorRT model is not support model fusing and distributed inferencing!" |
| | trt_file = os.path.join(file_name, "model_trt.pth") |
| | assert os.path.exists( |
| | trt_file |
| | ), "TensorRT model is not found!\n Run tools/trt.py first!" |
| | model.head.decode_in_inference = False |
| | decoder = model.head.decode_outputs |
| | else: |
| | trt_file = None |
| | decoder = None |
| |
|
| | |
| | *_, summary = evaluator.evaluate( |
| | model, is_distributed, args.fp16, trt_file, decoder, exp.test_size |
| | ) |
| | logger.info("\n" + summary) |
| |
|
| |
|
| | if __name__ == "__main__": |
| | configure_module() |
| | args = make_parser().parse_args() |
| | exp = get_exp(args.exp_file, args.name) |
| | exp.merge(args.opts) |
| |
|
| | if not args.experiment_name: |
| | args.experiment_name = exp.exp_name |
| |
|
| | num_gpu = torch.cuda.device_count() if args.devices is None else args.devices |
| | assert num_gpu <= torch.cuda.device_count() |
| |
|
| | dist_url = "auto" if args.dist_url is None else args.dist_url |
| | launch( |
| | main, |
| | num_gpu, |
| | args.num_machines, |
| | args.machine_rank, |
| | backend=args.dist_backend, |
| | dist_url=dist_url, |
| | args=(exp, args, num_gpu), |
| | ) |
| |
|