Ejemplo n.º 1
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--model', type=str, default='yolov3_80')
    parser.add_argument('--train_set', type=str, default='wheat1')
    parser.add_argument('--val_set', type=str, default='wheat1')

    parser.add_argument('--super_batchsize', type=int, default=32)
    parser.add_argument('--initial_imgsize', type=int, default=None)
    parser.add_argument('--optimizer', type=str, default='SGDMN')
    parser.add_argument('--lr', type=float, default=0.0001)
    parser.add_argument('--warmup', type=int, default=1000)

    parser.add_argument('--checkpoint', type=str, default='')

    parser.add_argument('--print_interval', type=int, default=20)
    parser.add_argument('--eval_interval', type=int, default=100)
    parser.add_argument('--checkpoint_interval', type=int, default=2000)
    parser.add_argument('--demo_interval', type=int, default=20)
    parser.add_argument('--demo_images', type=str, default='wheat1')

    parser.add_argument('--debug_mode', type=str, default='overfit')
    args = parser.parse_args()
    assert torch.cuda.is_available()
    print('Initialing model...')
    model, global_cfg = name_to_model(args.model)

    # -------------------------- settings ---------------------------
    ap_conf_thres = global_cfg.get('test.ap_conf_thres', 0.005)
    if args.debug_mode == 'overfit':
        print(f'Running debug mode: {args.debug_mode}...')
        global_cfg['train.img_sizes'] = [640]
        global_cfg['train.initial_imgsize'] = 640
        global_cfg['test.preprocessing'] = 'resize_pad_square'
        target_size = 640
        global_cfg['train.data_augmentation'] = None
        enable_multiscale = False
        batch_size = 1
        accumulate = 1
        num_cpu = 0
        warmup_iter = 40
    elif args.debug_mode == 'local':
        print(f'Running debug mode: {args.debug_mode}...')
        # train on local laptop with a small resolution and batch size
        TRAIN_RESOLUTIONS = [384, 512]
        AUTO_BATCHSIZE = {'384': 4, '512': 2}
        initial_size = TRAIN_RESOLUTIONS[-1]
        global_cfg['train.initial_imgsize'] = initial_size
        batch_size = 2
        super_batchsize = 8
        accumulate = int(np.ceil(super_batchsize / batch_size))
        # data augmentation setting
        enable_multiscale = True
        num_cpu = 0
        warmup_iter = args.warmup
        # testing setting
        target_size = global_cfg.get('test.default_input_size', None)
    elif args.debug_mode == None:
        # training setting
        TRAIN_RESOLUTIONS = global_cfg['train.img_sizes']
        AUTO_BATCHSIZE = global_cfg['train.imgsize_to_batch_size']
        if args.initial_imgsize is not None:
            initial_size = args.initial_imgsize
            assert initial_size in TRAIN_RESOLUTIONS
        else:
            initial_size = TRAIN_RESOLUTIONS[-1]
        global_cfg['train.initial_imgsize'] = initial_size
        batch_size = AUTO_BATCHSIZE[str(initial_size)]
        super_batchsize = args.super_batchsize
        accumulate = int(np.ceil(super_batchsize / batch_size))
        # data augmentation setting
        enable_multiscale = True
        assert 'train.imgsize_to_batch_size' in global_cfg
        print(
            'Auto-batchsize enabled. Automatically selecting the batch size.')
        # optimizer setting
        num_cpu = 4 if global_cfg[
            'train.hard_example_mining'] != 'probability' else 0
        warmup_iter = args.warmup
        # testing setting
        target_size = global_cfg.get('test.default_input_size', None)
    else:
        raise Exception('Unknown debug mode')

    job_name = f'{args.model}_{args.train_set}_{args.lr}'

    # Prepare model
    pnum = sum(p.numel() for p in model.parameters() if p.requires_grad)
    print(f'Number of trainable parameters in {args.model}:', pnum)
    model = model.cuda()
    model.train()

    # Training set and validation set setting
    print(f'Initializing training set {args.train_set}...')
    global_cfg['train.dataset_name'] = args.train_set
    dataset = get_trainingset(global_cfg)
    dataset.to_iterator(batch_size=batch_size,
                        shuffle=True,
                        num_workers=num_cpu,
                        pin_memory=True)
    print(f'Initializing validation set {args.val_set}...')
    eval_info, validation_func = get_valset(args.val_set)
    # validation function for hard example mining
    eval_func_ = eval_info['val_func']

    if args.checkpoint:
        print("Loading checkpoint...", args.checkpoint)
        weights_path = f'{PROJECT_ROOT}/weights/{args.checkpoint}'
        previous_state = torch.load(weights_path)
        try:
            model.load_state_dict(previous_state['model'])
        except:
            print('Cannot load weights. Trying to set strict=False...')
            model.load_state_dict(previous_state['model'], strict=False)
            print('Successfully loaded part of the weights.')

    print('Initializing tensorboard SummaryWriter...')
    if args.debug_mode:
        logger = SummaryWriter(f'{PROJECT_ROOT}/logs/debug/{job_name}')
    else:
        logger = SummaryWriter(f'{PROJECT_ROOT}/logs/{job_name}')

    print(f'Initializing optimizer with lr: {args.lr}')
    # set weight decay only on conv.weight
    pg0, pg1, pg2 = [], [], []  # optimizer parameter groups
    for k, v in model.named_parameters():
        if v.requires_grad:
            assert '.conv' in k or '.bn' in k
            if '.bias' in k:
                pg2.append(v)  # biases
            elif '.conv' in k and '.weight' in k:
                pg1.append(v)  # apply weight decay
            else:
                pg0.append(v)  # all else

    optimizer = optim.get_optimizer(name=args.optimizer,
                                    params=pg0,
                                    lr=args.lr,
                                    global_cfg=global_cfg)
    decay = global_cfg['train.sgd.weight_decay']
    optimizer.add_param_group({'params': pg1, 'weight_decay': decay})
    optimizer.add_param_group({'params': pg2})
    print(
        f'Optimizer groups: {len(pg1)} conv.weight, {len(pg2)} .bias, {len(pg0)} other'
    )
    del pg0, pg1, pg2

    start_iter = -1
    if args.checkpoint and args.optimizer in previous_state:
        optimizer.load_state_dict(previous_state[args.optimizer])
        start_iter = previous_state.get('iter', -2) + 1
        print(f'Start from iteration: {start_iter}')
    # Learning rate scheduler
    lr_schedule_func = lambda x: optim.lr_warmup(x, warm_up=warmup_iter)
    from torch.optim.lr_scheduler import LambdaLR
    scheduler = LambdaLR(optimizer, lr_schedule_func, last_epoch=start_iter)

    print('Start training...')
    today = timer.today()
    start_time = timer.tic()
    for iter_i in range(start_iter, 1000000):
        # evaluation
        if iter_i > 0 and iter_i % args.eval_interval == 0:
            if not args.debug_mode:
                model.eval()
            with timer.contexttimer() as t0:
                model_eval = api.Detector(model_and_cfg=(model, global_cfg))
                dts = model_eval.evaluation_predict(
                    eval_info,
                    input_size=target_size,
                    conf_thres=ap_conf_thres,
                    catIdx2id=dataset.catIdx2id)
                eval_str, ap, ap50, ap75 = validation_func(dts)
            del model_eval
            s = f'\nCurrent time: [ {timer.now()} ], iteration: [ {iter_i} ]\n\n'
            s += eval_str + '\n\n'
            s += f'Validation elapsed time: [ {t0.time_str} ]'
            print(s)
            logger.add_text('Validation summary', s, iter_i)
            logger.add_scalar('Validation AP[IoU=0.5]', ap50, iter_i)
            logger.add_scalar('Validation AP[IoU=0.75]', ap75, iter_i)
            logger.add_scalar('Validation AP[IoU=0.5:0.95]', ap, iter_i)
            model.train()

        torch.cuda.reset_max_memory_allocated(0)
        # accumulate loop
        optimizer.zero_grad()
        for _ in range(accumulate):
            batch = dataset.get_next()
            imgs, labels = batch['images'], batch['labels']
            # for t_im, lbl in zip(imgs, labels):
            #     np_im = image_ops.tensor_to_np(t_im, model.input_format, 'RGB_uint8')
            #     lbl.draw_on_np(np_im, class_map='COCO', imshow=True)
            imgs = imgs.cuda()
            # try:
            dts, loss = model(imgs, labels)
            assert not torch.isnan(loss)
            loss.backward()
            # except RuntimeError as e:
            #     if 'CUDA out of memory' in str(e):
            #         print(f'CUDA out of memory at imgsize={dataset.img_size},',
            #               f'batchsize={batch_size}')
            #     raise e
            #     if 'CUDA out of memory' in str(e):
            #         print(f'CUDA out of memory at imgsize={dataset.img_size},',
            #               f'batchsize={batch_size}')
            #         print('Trying to reduce the batchsize at that image size...')
            #         AUTO_BATCHSIZE[str(dataset.img_size)] -= 1
            #         dataset.to_iterator(batch_size=batch_size-1, shuffle=True,
            #                             num_workers=num_cpu, pin_memory=True)
            #     else:
            #         raise e
            # assert AUTO_BATCHSIZE[str(dataset.img_size)] == batch_size
            if global_cfg['train.hard_example_mining'] in {'probability'}:
                # calculate AP for each image
                idxs, img_ids, anns = batch['indices'], batch[
                    'image_ids'], batch['anns']
                for d, _idx, _id, g in zip(dts, idxs, img_ids, anns):
                    d: ImageObjects
                    d = d.post_process(conf_thres=ap_conf_thres,
                                       nms_thres=global_cfg['test.nms_thres'])
                    d = d.to_json(img_id=_id, eval_type=eval_info['eval_type'])
                    _, ap, ap50, ap75 = eval_func_(d, g, str_print=False)
                    dataset.update_ap(_idx, ap)

        for p in model.parameters():
            if p.grad is not None:
                p.grad.data.mul_(1.0 / accumulate)
        optimizer.step()
        scheduler.step()

        # logging
        if iter_i % args.print_interval == 0:
            sec_used = timer.tic() - start_time
            time_used = timer.sec2str(sec_used)
            _ai = sec_used / (iter_i + 1 - start_iter)
            avg_iter = timer.sec2str(_ai)
            avg_100img = timer.sec2str(_ai / batch_size / accumulate * 100)
            avg_epoch = timer.sec2str(_ai / batch_size / accumulate * 118287)
            print(f'\nTotal time: {time_used}, 100 imgs: {avg_100img}, ',
                  f'iter: {avg_iter}, COCO epoch: {avg_epoch}')
            print(f'effective batch size = {batch_size} * {accumulate}')
            max_cuda = torch.cuda.max_memory_allocated(0) / 1024 / 1024 / 1024
            print(f'Max GPU memory usage: {max_cuda:.3f} GB')
            current_lr = scheduler.get_last_lr()[0]
            print(f'[Iteration {iter_i}] [learning rate {current_lr:.3g}]',
                  f'[Total loss {loss:.2f}] [img size {dataset.img_size}]')
            print(model.loss_str)

        # random resizing
        if enable_multiscale and iter_i > 0 and (iter_i % 10 == 0):
            # # Randomly pick a input resolution
            imgsize = np.random.choice(TRAIN_RESOLUTIONS)
            # Set the image size in datasets
            batch_size = AUTO_BATCHSIZE[str(imgsize)]
            accumulate = int(np.ceil(super_batchsize / batch_size))
            dataset.img_size = imgsize
            dataset.to_iterator(batch_size=batch_size,
                                shuffle=True,
                                num_workers=num_cpu,
                                pin_memory=True)

        # save checkpoint
        if iter_i > 0 and (iter_i % args.checkpoint_interval == 0):
            state_dict = {
                'iter': iter_i,
                'model': model.state_dict(),
                args.optimizer: optimizer.state_dict(),
                'dataset': dataset.hem_state
            }
            save_path = f'{PROJECT_ROOT}/weights/{job_name}_{today}_{iter_i}.pth'
            torch.save(state_dict, save_path)

        # save detection
        if iter_i > 0 and iter_i % args.demo_interval == 0:
            if not args.debug_mode:
                model.eval()
            model_eval = api.Detector(model_and_cfg=(model, global_cfg))
            demo_images_dir = f'{PROJECT_ROOT}/images/{args.demo_images}'
            for imname in os.listdir(demo_images_dir):
                # if not imname.endswith('.jpg'): continue
                impath = os.path.join(demo_images_dir, imname)
                np_img = model_eval.detect_one(img_path=impath,
                                               return_img=True,
                                               conf_thres=0.3,
                                               input_size=target_size)
                if args.debug_mode:
                    cv2_im = cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)
                    log_dir = f'{PROJECT_ROOT}/logs/{args.model}_debug/'
                    if not os.path.exists(log_dir): os.mkdir(log_dir)
                    s = os.path.join(log_dir,
                                     f'{imname[:-4]}_iter{iter_i}.jpg')
                    cv2.imwrite(s, cv2_im)
                else:
                    if min(np_img.shape[:2]) > 512:
                        _h, _w = np_img.shape[:2]
                        _r = 512 / min(_h, _w)
                        np_img = cv2.resize(np_img,
                                            (int(_w * _r), int(_h * _r)))
                    logger.add_image(impath, np_img, iter_i, dataformats='HWC')
            model.train()
Ejemplo n.º 2
0
import api
from utils.evaluation import get_valset
from settings import PROJECT_ROOT

model_name = 'rapid'
weight_name = 'rapid_H1MW1024_Mar11_4000'
# val_set_names = ['Lunch2_mot', 'Edge_cases_mot', 'High_activity_mot',
#                  'All_off_mot', 'IRfilter_mot', 'IRill_mot']
# val_set_names = ['Lunch1', 'Lunch2', 'Lunch3', 'Edge_cases', 'High_activity',
#                  'All_off', 'IRfilter', 'IRill']
val_set_names = ['youtube_val']
input_size = 1024
conf_thres = 0.005

model_eval = api.Detector(
    model_name=model_name,
    weights_path=f'{PROJECT_ROOT}/weights/{weight_name}.pth')

csv_dic = OrderedDict()
csv_dic['weights'] = weight_name
csv_dic['inpu_size'] = input_size
csv_dic['tta'] = None
csv_dic['metric'] = 'AP_50'
csv_dic['date'] = datetime.now().strftime('%Y-%b-%d (%H:%M:%S)')

save_dir = f'./results/{weight_name}'
if not os.path.exists(save_dir):
    os.makedirs(save_dir)

for val_name in val_set_names:
    eval_info, val_func = get_valset(val_name)
Ejemplo n.º 3
0
        optimizer.load_state_dict(state['optimizer_state_dict'])
        print(f'begin from iteration: {start_iter}')
    scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer,
                                                  burnin_schedule,
                                                  last_epoch=start_iter)

    # start training loop
    today = timer.today()
    start_time = timer.tic()
    for iter_i in range(start_iter, 500000):
        # evaluation
        if iter_i % args.eval_interval == 0 and (args.dataset != 'COCO'
                                                 or iter_i > 0):
            with timer.contexttimer() as t0:
                model.eval()
                model_eval = api.Detector(conf_thres=0.005, model=model)
                dts = model_eval.detect_imgSeq(val_img_dir,
                                               input_size=target_size)
                str_0 = val_set.evaluate_dtList(dts, metric='AP')
            s = f'\nCurrent time: [ {timer.now()} ], iteration: [ {iter_i} ]\n\n'
            s += str_0 + '\n\n'
            s += f'Validation elapsed time: [ {t0.time_str} ]'
            print(s)
            logger.add_text('Validation summary', s, iter_i)
            logger.add_scalar('Validation AP[IoU=0.5]', val_set._getAP(0.5),
                              iter_i)
            logger.add_scalar('Validation AP[IoU=0.75]', val_set._getAP(0.75),
                              iter_i)
            logger.add_scalar('Validation AP[IoU=0.5:0.95]', val_set._getAP(),
                              iter_i)
            model.train()
Ejemplo n.º 4
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--model', type=str, default='yv3a1_agg_dev')
    parser.add_argument('--train_set', type=str, default='HBMWR_mot_train')
    parser.add_argument('--val_set', type=str, default='Lab1_mot')

    parser.add_argument('--super_batchsize', type=int, default=32)
    parser.add_argument('--initial_imgsize', type=int, default=None)
    parser.add_argument('--optimizer', type=str, default='SGDMR')
    parser.add_argument('--optim_params', type=str, default='all')
    parser.add_argument('--lr', type=float, default=0.0001)
    parser.add_argument('--warmup', type=int, default=1000)
    parser.add_argument('--checkpoint',
                        type=str,
                        default='rapid_H1MW1024_Mar11_4000_.pth')

    parser.add_argument('--print_interval', type=int, default=20)
    parser.add_argument('--eval_interval', type=int, default=200)
    parser.add_argument('--checkpoint_interval', type=int, default=2000)
    parser.add_argument('--demo_interval', type=int, default=100)
    parser.add_argument('--demo_images', type=str, default='fisheye')

    parser.add_argument('--debug_mode', type=str, default=None)
    args = parser.parse_args()

    assert torch.cuda.is_available()
    print('Initialing model...')
    model, global_cfg = name_to_model(args.model)

    # -------------------------- settings ---------------------------
    if args.debug_mode == 'overfit':
        raise NotImplementedError()
        print(f'Running debug mode: {args.debug_mode}...')
        # overfitting on one or a few images
        global_cfg['train.img_sizes'] = [640]
        global_cfg['train.initial_imgsize'] = 640
        global_cfg['test.preprocessing'] = 'resize_pad_square'
        target_size = 640
        global_cfg['train.data_augmentation'] = None
        enable_multiscale = False
        batch_size = 1
        subdivision = 1
        num_cpu = 0
        warmup_iter = 40
    elif args.debug_mode == 'local':
        print(f'Running debug mode: {args.debug_mode}...')
        # train on local laptop with a small resolution and batch size
        TRAIN_RESOLUTIONS = [384, 512]
        AUTO_BATCHSIZE = {'384': 4, '512': 2}
        initial_size = TRAIN_RESOLUTIONS[-1]
        global_cfg['train.initial_imgsize'] = initial_size
        batch_size = 2
        seq_len = global_cfg['train.sequence_length']
        super_batchsize = args.super_batchsize
        subdivision = int(np.ceil(super_batchsize / batch_size / seq_len))
        # data augmentation setting
        enable_multiscale = True
        num_cpu = 0
        warmup_iter = args.warmup
        # testing setting
        target_size = global_cfg.get('test.default_input_size', None)
    elif args.debug_mode == None:
        print(f'Debug mode disabled.')
        # normal training
        AUTO_BATCHSIZE = global_cfg['train.imgsize_to_batch_size']
        TRAIN_RESOLUTIONS = global_cfg['train.img_sizes']
        if args.initial_imgsize is not None:
            initial_size = args.initial_imgsize
            assert initial_size in TRAIN_RESOLUTIONS
        else:
            initial_size = TRAIN_RESOLUTIONS[-1]
        global_cfg['train.initial_imgsize'] = initial_size
        batch_size = AUTO_BATCHSIZE[str(initial_size)]
        seq_len = global_cfg['train.sequence_length']
        super_batchsize = args.super_batchsize
        subdivision = int(np.ceil(super_batchsize / batch_size / seq_len))
        # data augmentation setting
        enable_multiscale = True
        assert 'train.imgsize_to_batch_size' in global_cfg
        print(
            'Auto-batchsize enabled. Automatically selecting the batch size.')
        num_cpu = 4
        warmup_iter = args.warmup
        # testing setting
        target_size = global_cfg.get('test.default_input_size', None)
    else:
        raise Exception('Unknown debug mode')

    job_name = f'{args.model}_{args.train_set}_{args.lr}'

    # Prepare model
    pnum = sum(p.numel() for p in model.parameters() if p.requires_grad)
    print(f'Number of trainable parameters of {args.model} =', pnum)
    model = model.cuda()
    model.train()

    # Training set and validation set setting
    print(f'Initializing training set {args.train_set}...')
    global_cfg['train.dataset_name'] = args.train_set
    dataset = get_trainingset(global_cfg)
    dataset.to_iterator(batch_size=batch_size,
                        num_workers=num_cpu,
                        pin_memory=True)
    print(f'Initializing validation set {args.val_set}...')
    eval_info, validation_func = get_valset(args.val_set)

    start_iter = -1
    if args.checkpoint:
        print("Loading checkpoint...", args.checkpoint)
        weights_path = os.path.join(f'{PROJECT_ROOT}/weights', args.checkpoint)
        previous_state = torch.load(weights_path)
        if 'input' in global_cfg['model.agg.hidden_state_names']:
            for k in list(previous_state['model'].keys()):
                if 'netlist.0' in k:
                    previous_state['model'].pop(k)
        try:
            model.load_state_dict(previous_state['model'])
        except:
            print('Cannot load weights. Trying to set strict=False...')
            model.load_state_dict(previous_state['model'], strict=False)
            print('Successfully loaded part of the weights.')
        start_iter = previous_state.get('iter', start_iter)
        print(f'Start from iteration: {start_iter}')

    print('Initializing tensorboard SummaryWriter...')
    if args.debug_mode:
        logger = SummaryWriter(f'{PROJECT_ROOT}logs/debug/{job_name}')
    else:
        logger = SummaryWriter(f'{PROJECT_ROOT}logs/{job_name}')

    print(f'Initializing optimizer with lr: {args.lr}')
    # set weight decay only on conv.weight
    params = []
    if args.optim_params == 'all':
        for key, value in model.named_parameters():
            decay = global_cfg[
                'train.sgd.weight_decay'] if 'conv' in key else 0.0
            params += [{'params': value, 'weight_decay': decay}]
    elif args.optim_params == 'fix_backbone':
        for key, value in model.fpn.named_parameters():
            decay = global_cfg[
                'train.sgd.weight_decay'] if 'conv' in key else 0.0
            params += [{'params': value, 'weight_decay': decay}]
        for key, value in model.agg.named_parameters():
            decay = global_cfg[
                'train.sgd.weight_decay'] if 'conv' in key else 0.0
            params += [{'params': value, 'weight_decay': decay}]
        for key, value in model.rpn.named_parameters():
            decay = global_cfg[
                'train.sgd.weight_decay'] if 'conv' in key else 0.0
            params += [{'params': value, 'weight_decay': decay}]
    elif args.optim_params == 'agg_only':
        for key, value in model.agg.named_parameters():
            decay = global_cfg[
                'train.sgd.weight_decay'] if 'conv' in key else 0.0
            params += [{'params': value, 'weight_decay': decay}]
    else:
        raise NotImplementedError()
    pnum = sum(p['params'].numel() for p in params
               if p['params'].requires_grad)
    print(f'Number of training parameters =', pnum)
    # Initialize optimizer
    optimizer = optim.get_optimizer(name=args.optimizer,
                                    params=params,
                                    lr=args.lr,
                                    cfg=global_cfg)
    if args.checkpoint and args.optimizer in previous_state:
        try:
            optimizer.load_state_dict(previous_state[args.optimizer])
        except:
            print(
                'Failed loading optimizer state. Initialize optimizer from scratch.'
            )
            start_iter = -1
    # Learning rate scheduler
    lr_schedule_func = lambda x: lr_warmup(x, warm_up=warmup_iter)
    from torch.optim.lr_scheduler import LambdaLR
    scheduler = LambdaLR(optimizer, lr_schedule_func, last_epoch=start_iter)

    print('Start training...')
    today = timer.today()
    start_time = timer.tic()
    for iter_i in range(start_iter, 1000000):
        # evaluation
        if iter_i > 0 and iter_i % args.eval_interval == 0:
            # if iter_i % args.eval_interval == 0:
            if args.debug_mode != 'overfit':
                model.eval()
            model.clear_hidden_state()
            with timer.contexttimer() as t0:
                model_eval = api.Detector(model_and_cfg=(model, global_cfg))
                dts = model_eval.eval_predict_vod(eval_info,
                                                  input_size=target_size,
                                                  conf_thres=global_cfg.get(
                                                      'test.ap_conf_thres',
                                                      0.005))
                eval_str, ap, ap50, ap75 = validation_func(dts)
            del model_eval
            s = f'\nCurrent time: [ {timer.now()} ], iteration: [ {iter_i} ]\n\n'
            s += eval_str + '\n\n'
            s += f'Validation elapsed time: [ {t0.time_str} ]'
            print(s)
            logger.add_text('Validation summary', s, iter_i)
            logger.add_scalar('Validation AP[IoU=0.5]', ap50, iter_i)
            logger.add_scalar('Validation AP[IoU=0.75]', ap75, iter_i)
            logger.add_scalar('Validation AP[IoU=0.5:0.95]', ap, iter_i)
            model.train()

        torch.cuda.reset_max_memory_allocated(0)
        seq_len = dataset.seq_len
        # subdivision loop
        optimizer.zero_grad()
        for _ in range(subdivision):
            seq_imgs, seq_labels, seq_flags, img_ids = dataset.get_next()
            assert len(seq_imgs) == len(seq_labels) == len(seq_flags)
            # visualize the clip for debugging
            if False:
                for b in range(batch_size):
                    for _im, _lab in zip(seq_imgs, seq_labels):
                        _im = image_ops.img_tensor_to_np(
                            _im[b], model.input_format, 'BGR_uint8')
                        _lab[b].draw_on_np(_im)
                        cv2.imshow('', _im)
                        cv2.waitKey(500)
            model.clear_hidden_state()
            for imgs, labels, is_start in zip(seq_imgs, seq_labels, seq_flags):
                imgs = imgs.cuda()
                loss = model(imgs, is_start, labels)
                assert not torch.isnan(loss)
                loss.backward()
        for p in model.parameters():
            if p.grad is not None:
                p.grad.data.mul_(1.0 / subdivision / seq_len)
        optimizer.step()
        scheduler.step()

        # logging
        if iter_i % args.print_interval == 0:
            sec_used = timer.tic() - start_time
            time_used = timer.sec2str(sec_used)
            _ai = sec_used / (iter_i + 1 - start_iter)
            avg_iter = timer.sec2str(_ai)
            avg_img = _ai / batch_size / subdivision / seq_len
            avg_100img = timer.sec2str(avg_img * 100)
            avg_epoch = timer.sec2str(avg_img * 118287)
            print(f'\nTotal time: {time_used}, 100 imgs: {avg_100img}, ',
                  f'iter: {avg_iter}, COCO epoch: {avg_epoch}')
            print(
                f'effective batch size = {batch_size} * {subdivision} * {seq_len}'
            )
            max_cuda = torch.cuda.max_memory_allocated(0) / 1024 / 1024 / 1024
            print(f'Max GPU memory usage: {max_cuda:.3f} GB')
            current_lr = scheduler.get_last_lr()[0]
            print(f'[Iteration {iter_i}] [learning rate {current_lr:.3g}]',
                  f'[Total loss {loss:.2f}] [img size {dataset.img_size}]')
            print(model.loss_str)

        # random resizing
        if enable_multiscale and iter_i > 0 and (iter_i % 10 == 0):
            # # Randomly pick a input resolution
            imgsize = np.random.choice(TRAIN_RESOLUTIONS)
            # Set the image size in datasets
            batch_size = AUTO_BATCHSIZE[str(imgsize)]
            subdivision = int(np.ceil(super_batchsize / batch_size / seq_len))
            dataset.img_size = imgsize
            dataset.to_iterator(batch_size=batch_size,
                                num_workers=num_cpu,
                                pin_memory=True)

        # save checkpoint
        if iter_i > 0 and (iter_i % args.checkpoint_interval == 0):
            state_dict = {
                'iter': iter_i,
                'model': model.state_dict(),
                args.optimizer: optimizer.state_dict(),
            }
            save_path = f'{PROJECT_ROOT}/weights/{job_name}_{today}_{iter_i}.pth'
            torch.save(state_dict, save_path)

        # save detection
        if iter_i > 0 and iter_i % args.demo_interval == 0:
            if args.debug_mode != 'overfit':
                model.eval()
            model_eval = api.Detector(model_and_cfg=(model, global_cfg))
            demo_images_dir = f'{PROJECT_ROOT}/images/{args.demo_images}'
            for imname in os.listdir():
                if not imname.endswith('.jpg'): continue
                impath = os.path.join(demo_images_dir, imname)
                model_eval.model.clear_hidden_state()
                np_img = model_eval.detect_one(img_path=impath,
                                               return_img=True,
                                               conf_thres=0.3,
                                               input_size=target_size)
                if args.debug_mode is not None:
                    cv2_im = cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)
                    log_dir = f'{PROJECT_ROOT}/logs/{args.model}_debug/'
                    if not os.path.exists(log_dir): os.mkdir(log_dir)
                    s = os.path.join(log_dir,
                                     f'{imname[:-4]}_iter{iter_i}.jpg')
                    cv2.imwrite(s, cv2_im)
                else:
                    if min(np_img.shape[:2]) > 512:
                        _h, _w = np_img.shape[:2]
                        _r = 512 / min(_h, _w)
                        np_img = cv2.resize(np_img,
                                            (int(_w * _r), int(_h * _r)))
                    logger.add_image(impath, np_img, iter_i, dataformats='HWC')
            model.train()
Ejemplo n.º 5
0
framerate = subprocess.check_output(['ffprobe', '-v', '0', '-of' ,'csv=p=0', '-select_streams', '0', \
                                     '-show_entries', 'stream=r_frame_rate', infile]).decode("utf-8")
framerate = framerate.split('/')[0]
print('Input video has frame rate', framerate)

assert os.path.isfile(infile), 'Could not find video file ' + infile
starting_dir = os.getcwd()
os.makedirs(tmp_dir, exist_ok=True)

print('Extracting images from video...')
# For scaling, add  ['-vf', 'select=\'\',scale=800:-1']
subprocess.check_call([
    'ffmpeg', '-i', infile, '-qscale:v', '1',
    os.path.join(tmp_dir, 'frame%06d.jpg')
])

print('Loading model...')
det = api.Detector(checkpoint, True, 2)
all_images = list(sorted(glob.glob(tmp_dir + '/*.jpg')))
print('Processing images...')
for img_file in tqdm.tqdm(all_images, total=len(all_images)):
    in_img = PIL.Image.open(img_file)
    out_img = det.annotate_image(in_img, 1000)
    out_img.save(os.path.join(tmp_dir, 'ann_' + os.path.basename(img_file)))

subprocess.check_call(['ffmpeg', '-framerate', '10', '-pattern_type', 'glob', '-i', os.path.join(tmp_dir, 'ann_*.jpg'), \
                             '-c:v', 'libx264', '-r', '30', '-pix_fmt', 'yuv420p', outfile])

shutil.rmtree(tmp_dir)