def test(model, device):
    global cfg
    if args.testset:
        print('test on test-dev 2017')
        evaluator = COCOAPIEvaluator(data_dir=data_dir,
                                     img_size=cfg['min_dim'],
                                     device=device,
                                     testset=True,
                                     transform=BaseTransform(
                                         cfg['min_dim'],
                                         mean=(0.406, 0.456, 0.485),
                                         std=(0.225, 0.224, 0.229)))

    else:
        # eval
        evaluator = COCOAPIEvaluator(data_dir=data_dir,
                                     img_size=cfg['min_dim'],
                                     device=device,
                                     testset=False,
                                     transform=BaseTransform(
                                         cfg['min_dim'],
                                         mean=(0.406, 0.456, 0.485),
                                         std=(0.225, 0.224, 0.229)))

    # COCO evaluation
    ap50_95, ap50 = evaluator.evaluate(model)
    print('ap50 : ', ap50)
    print('ap50_95 : ', ap50_95)
Example #2
0
def main():
    """
    YOLOv3 trainer. See README for details.
    """
    args = parse_args()
    print("Setting Arguments.. : ", args)

    cuda = torch.cuda.is_available() and args.use_cuda
    os.makedirs(args.checkpoint_dir, exist_ok=True)

    # Parse config settings
    with open(args.cfg, 'r') as f:
        cfg = yaml.load(f)

    print("successfully loaded config file: ", cfg)

    momentum = cfg['TRAIN']['MOMENTUM']
    decay = cfg['TRAIN']['DECAY']
    burn_in = cfg['TRAIN']['BURN_IN']
    iter_size = cfg['TRAIN']['MAXITER']
    steps = eval(cfg['TRAIN']['STEPS'])
    batch_size = cfg['TRAIN']['BATCHSIZE']
    subdivision = cfg['TRAIN']['SUBDIVISION']
    ignore_thre = cfg['TRAIN']['IGNORETHRE']
    random_resize = cfg['AUGMENTATION']['RANDRESIZE']
    base_lr = cfg['TRAIN']['LR'] / batch_size / subdivision

    print('effective_batch_size = batch_size * iter_size = %d * %d' %
          (batch_size, subdivision))

    # Initiate model
    model = YOLOv3(cfg['MODEL'], ignore_thre=ignore_thre)

    if args.weights_path:
        print("loading darknet weights....", args.weights_path)
        parse_yolo_weights(model, args.weights_path)
    elif args.checkpoint:
        print("loading pytorch ckpt...", args.checkpoint)
        state = torch.load(args.checkpoint)
        if 'model_state_dict' in state.keys():
            model.load_state_dict(state['model_state_dict'])
        else:
            model.load_state_dict(state)

    if cuda:
        print("using cuda") 
        model = model.cuda()


    model.train()

    imgsize = cfg['TRAIN']['IMGSIZE']

    evaluator = COCOAPIEvaluator(model_type=cfg['MODEL']['TYPE'],
                    data_dir='COCO/',
                    img_size=cfg['TEST']['IMGSIZE'],
                    confthre=cfg['TEST']['CONFTHRE'],
                    nmsthre=cfg['TEST']['NMSTHRE'])
    ap50_95, ap50 = evaluator.evaluate(model)
Example #3
0
def test(model, device):
    global cfg
    evaluator = COCOAPIEvaluator(data_dir=data_dir,
                                 img_size=cfg['min_dim'],
                                 device=device,
                                 transform=BaseTransform(cfg['min_dim'],
                                                         mean=(0.406, 0.456,
                                                               0.485),
                                                         std=(0.225, 0.224,
                                                              0.229)))

    # COCO evaluation
    ap50_95, ap50 = evaluator.evaluate(model)
    print('ap50 : ', ap50)
    print('ap50_95 : ', ap50_95)
Example #4
0
def test(model, device, input_size):
    if args.testset:
        print('test on test-dev 2017')
        evaluator = COCOAPIEvaluator(data_dir=data_dir,
                                     img_size=input_size,
                                     device=device,
                                     testset=True,
                                     transform=BaseTransform(input_size))

    else:
        # eval
        evaluator = COCOAPIEvaluator(data_dir=data_dir,
                                     img_size=input_size,
                                     device=device,
                                     testset=False,
                                     transform=BaseTransform(input_size))

    # COCO evaluation
    ap50_95, ap50 = evaluator.evaluate(model)
    print('ap50 : ', ap50)
    print('ap50_95 : ', ap50_95)
Example #5
0
def coco_test(model, device, input_size, test=False):
    if test:
        # test-dev
        print('test on test-dev 2017')
        evaluator = COCOAPIEvaluator(data_dir=coco_root,
                                     img_size=input_size,
                                     device=device,
                                     testset=True,
                                     transform=BaseTransform(input_size))

    else:
        # eval
        evaluator = COCOAPIEvaluator(data_dir=coco_root,
                                     img_size=input_size,
                                     device=device,
                                     testset=False,
                                     transform=BaseTransform(input_size))

    # COCO evaluation
    evaluator.evaluate(model)
Example #6
0
def main():
    """
    YOLOv3 trainer. See README for details.
    """
    args = parse_args()
    print("Setting Arguments.. : ", args)

    cuda = torch.cuda.is_available() and args.use_cuda
    os.makedirs(args.log_dir, exist_ok=True)
    os.makedirs(args.save_dir, exist_ok=True)

    if args.distributed:
        torch.cuda.set_device(args.local_rank)
        torch.distributed.init_process_group(backend="nccl",
                                             init_method="env://")

    save_prefix = 'yolov3'

    # Parse config settings
    with open(args.cfg, 'r') as f:
        cfg = yaml.safe_load(f)

    print("successfully loaded config file: ", cfg)

    lr = cfg['TRAIN']['LR']
    epochs = cfg['TRAIN']['MAXEPOCH']
    cos = cfg['TRAIN']['COS']
    sybn = cfg['TRAIN']['SYBN']
    mixup = cfg['TRAIN']['MIX']
    no_mixup_epochs = cfg['TRAIN']['NO_MIXUP_EPOCHS']
    label_smooth = cfg['TRAIN']['LABAL_SMOOTH']
    momentum = cfg['TRAIN']['MOMENTUM']
    burn_in = cfg['TRAIN']['BURN_IN']
    batch_size = cfg['TRAIN']['BATCHSIZE']
    decay = cfg['TRAIN']['DECAY']
    ignore_thre = cfg['TRAIN']['IGNORETHRE']
    random_resize = cfg['TRAIN']['RANDRESIZE']
    input_size = (cfg['TRAIN']['IMGSIZE'], cfg['TRAIN']['IMGSIZE'])
    test_size = (args.test_size, args.test_size)
    step = (180, 240)  # for no cos lr shedule training

    # Learning rate setup
    base_lr = lr

    if args.dataset == 'COCO':
        dataset = COCODataset(data_dir='data/COCO/',
                              img_size=input_size,
                              preproc=TrainTransform(rgb_means=(0.485, 0.456,
                                                                0.406),
                                                     std=(0.229, 0.224, 0.225),
                                                     max_labels=50),
                              debug=args.debug)
        num_class = 80
    elif args.dataset == 'VOC':
        train_sets = [('2007', 'trainval'), ('2012', 'trainval')]
        dataset = VOCDetection(root='data/VOC',
                               image_sets=train_sets,
                               input_dim=input_size,
                               preproc=TrainTransform(rgb_means=(0.485, 0.456,
                                                                 0.406),
                                                      std=(0.229, 0.224,
                                                           0.225),
                                                      max_labels=30))
        num_class = 20
    else:
        print('Only COCO and VOC datasets are supported!')
        return

    save_prefix += ('_' + args.dataset)

    if label_smooth:
        save_prefix += '_label_smooth'

    # Initiate model
    if args.asff:
        save_prefix += '_asff'
        from models.yolov3_asff import YOLOv3
        print('Training YOLOv3 with ASFF!')
        model = YOLOv3(num_classes=num_class,
                       ignore_thre=ignore_thre,
                       label_smooth=label_smooth,
                       rfb=args.rfb,
                       vis=args.vis)
    else:
        save_prefix += '_baseline'
        from models.yolov3_baseline import YOLOv3
        print('Training YOLOv3 strong baseline!')
        if args.vis:
            print('Visualization is not supported for YOLOv3 baseline model')
            args.vis = False
        model = YOLOv3(num_classes=num_class,
                       ignore_thre=ignore_thre,
                       label_smooth=label_smooth,
                       rfb=args.rfb)

    save_to_disk = (not args.distributed) or distributed_util.get_rank() == 0

    def init_yolo(m):
        for key in m.state_dict():
            if key.split('.')[-1] == 'weight':
                if 'conv' in key:
                    init.kaiming_normal_(m.state_dict()[key],
                                         a=0.1,
                                         mode='fan_in')
                if 'linear' in key:
                    init.kaiming_normal_(m.state_dict()[key],
                                         a=0.0,
                                         mode='fan_in')
                if 'bn' in key:
                    m.state_dict()[key][...] = 1
            elif key.split('.')[-1] == 'bias':
                m.state_dict()[key][...] = 0

    model.apply(init_yolo)

    if sybn:
        model = apex.parallel.convert_syncbn_model(model)

    if args.checkpoint:
        print("loading pytorch ckpt...", args.checkpoint)
        cpu_device = torch.device("cpu")
        ckpt = torch.load(args.checkpoint, map_location=cpu_device)
        model.load_state_dict(ckpt, strict=False)
        #model.load_state_dict(ckpt)
    if cuda:
        print("using cuda")
        torch.backends.cudnn.benchmark = True
        device = torch.device("cuda")
        model = model.to(device)

    if args.half:
        model = model.half()

    if args.ngpu > 1:
        if args.distributed:
            model = apex.parallel.DistributedDataParallel(model,
                                                          delay_allreduce=True)
            #model = apex.parallel.DistributedDataParallel(model)
        else:
            model = nn.DataParallel(model)

    if args.tfboard and save_to_disk:
        print("using tfboard")
        from torch.utils.tensorboard import SummaryWriter
        tblogger = SummaryWriter(args.log_dir)

    model.train()
    if mixup:
        from dataset.mixupdetection import MixupDetection
        dataset = MixupDetection(
            dataset,
            preproc=TrainTransform(rgb_means=(0.485, 0.456, 0.406),
                                   std=(0.229, 0.224, 0.225),
                                   max_labels=50),
        )
        dataset.set_mixup(np.random.beta, 1.5, 1.5)

        save_prefix += '_mixup'

    if args.distributed:
        sampler = torch.utils.data.DistributedSampler(dataset)
    else:
        sampler = torch.utils.data.RandomSampler(dataset)

    batch_sampler = YoloBatchSampler(sampler=sampler,
                                     batch_size=batch_size,
                                     drop_last=False,
                                     input_dimension=input_size)
    dataloader = DataLoader(dataset,
                            batch_sampler=batch_sampler,
                            num_workers=args.n_cpu,
                            pin_memory=True)

    dataiterator = iter(dataloader)

    if args.dataset == 'COCO':
        evaluator = COCOAPIEvaluator(data_dir='data/COCO/',
                                     img_size=test_size,
                                     confthre=cfg['TEST']['CONFTHRE'],
                                     nmsthre=cfg['TEST']['NMSTHRE'],
                                     testset=args.testset,
                                     vis=args.vis)

    elif args.dataset == 'VOC':
        '''
        # COCO style evaluation, you have to convert xml annotation files into a json file.
        evaluator = COCOAPIEvaluator(
                    data_dir='data/VOC/',
                    img_size=test_size,
                    confthre=cfg['TEST']['CONFTHRE'],
                    nmsthre=cfg['TEST']['NMSTHRE'],
                    testset=args.testset,
                    voc = True)
        '''
        evaluator = VOCEvaluator(data_dir='data/VOC/',
                                 img_size=test_size,
                                 confthre=cfg['TEST']['CONFTHRE'],
                                 nmsthre=cfg['TEST']['NMSTHRE'],
                                 vis=args.vis)

    dtype = torch.float16 if args.half else torch.float32

    # optimizer setup
    # set weight decay only on conv.weight
    if args.no_wd:
        params_dict = dict(model.named_parameters())
        params = []
        for key, value in params_dict.items():
            if 'conv.weight' in key:
                params += [{'params': value, 'weight_decay': decay}]
            else:
                params += [{'params': value, 'weight_decay': 0.0}]

        save_prefix += '_no_wd'
    else:
        params = model.parameters()

    optimizer = optim.SGD(params,
                          lr=base_lr,
                          momentum=momentum,
                          dampening=0,
                          weight_decay=decay)

    if args.half:
        optimizer = FP16_Optimizer(optimizer, verbose=False)

    if cos:
        save_prefix += '_cos'

    tmp_lr = base_lr

    def set_lr(tmp_lr):
        for param_group in optimizer.param_groups:
            param_group['lr'] = tmp_lr

    # start training loop
    start = time.time()
    epoch = args.start_epoch
    epoch_size = len(dataset) // (batch_size * args.ngpu)
    while epoch < epochs + 1:
        if args.distributed:
            batch_sampler.sampler.set_epoch(epoch)

        if epoch > epochs - no_mixup_epochs + 1:
            args.eval_interval = 1
            if mixup:
                print('Disable mix up now!')
                mixup = False
                dataset.set_mixup(None)
                if args.distributed:
                    sampler = torch.utils.data.DistributedSampler(dataset)
                else:
                    sampler = torch.utils.data.RandomSampler(dataset)
                batch_sampler = YoloBatchSampler(sampler=sampler,
                                                 batch_size=batch_size,
                                                 drop_last=False,
                                                 input_dimension=input_size)
                dataloader = DataLoader(dataset,
                                        batch_sampler=batch_sampler,
                                        num_workers=args.n_cpu,
                                        pin_memory=True)

        #### DropBlock Shedule #####
        Drop_layer = [16, 24, 33]
        if args.asff:
            Drop_layer = [16, 22, 29]
        if (epoch == 5 or (epoch == args.start_epoch
                           and args.start_epoch > 5)) and (args.dropblock):
            block_size = [1, 3, 5]
            keep_p = [0.9, 0.9, 0.9]
            for i in range(len(Drop_layer)):
                model.module.module_list[Drop_layer[i]].reset(
                    block_size[i], keep_p[i])

        if (epoch == 80 or (epoch == args.start_epoch
                            and args.start_epoch > 80)) and (args.dropblock):
            block_size = [3, 5, 7]
            keep_p = [0.9, 0.9, 0.9]
            for i in range(len(Drop_layer)):
                model.module.module_list[Drop_layer[i]].reset(
                    block_size[i], keep_p[i])

        if (epoch == 150 or (epoch == args.start_epoch
                             and args.start_epoch > 150)) and (args.dropblock):
            block_size = [7, 7, 7]
            keep_p = [0.9, 0.9, 0.9]
            for i in range(len(Drop_layer)):
                model.module.module_list[Drop_layer[i]].reset(
                    block_size[i], keep_p[i])

        for iter_i, (imgs, targets, img_info, idx) in enumerate(dataloader):
            #evaluation
            if ((epoch % args.eval_interval == 0) and epoch > args.start_epoch
                    and iter_i == 0) or args.test:
                if not args.test and save_to_disk:
                    torch.save(
                        model.module.state_dict(),
                        os.path.join(args.save_dir,
                                     save_prefix + '_' + repr(epoch) + '.pth'))

                if args.distributed:
                    distributed_util.synchronize()
                ap50_95, ap50 = evaluator.evaluate(model, args.half)
                if args.distributed:
                    distributed_util.synchronize()
                if args.test:
                    sys.exit(0)
                model.train()
                if args.tfboard and save_to_disk:
                    tblogger.add_scalar('val/COCOAP50', ap50, epoch)
                    tblogger.add_scalar('val/COCOAP50_95', ap50_95, epoch)

        # learning rate scheduling (cos or step)
            if epoch < burn_in:
                tmp_lr = base_lr * pow((iter_i + epoch * epoch_size) * 1. /
                                       (burn_in * epoch_size), 3)
                set_lr(tmp_lr)
            elif cos:
                if epoch <= epochs - no_mixup_epochs and epoch > 20:
                    min_lr = 0.00001
                    tmp_lr = min_lr + 0.5*(base_lr-min_lr)*(1+math.cos(math.pi*(epoch-20)*1./\
                        (epochs-no_mixup_epochs-20)))
                elif epoch > epochs - no_mixup_epochs:
                    tmp_lr = 0.00001
                set_lr(tmp_lr)

            elif epoch == burn_in:
                tmp_lr = base_lr
                set_lr(tmp_lr)
            elif epoch in steps and iter_i == 0:
                tmp_lr = tmp_lr * 0.1
                set_lr(tmp_lr)

            optimizer.zero_grad()

            imgs = Variable(imgs.to(device).to(dtype))
            targets = Variable(targets.to(device).to(dtype),
                               requires_grad=False)
            loss_dict = model(imgs, targets, epoch)
            loss_dict_reduced = reduce_loss_dict(loss_dict)
            loss = sum(loss for loss in loss_dict['losses'])
            if args.half:
                optimizer.backward(loss)
            else:
                loss.backward()

            #torch.nn.utils.clip_grad_norm_(model.parameters(), 10)

            optimizer.step()

            if iter_i % 10 == 0 and save_to_disk:
                # logging
                end = time.time()
                print(
                    '[Epoch %d/%d][Iter %d/%d][lr %.6f]'
                    '[Loss: anchor %.2f, iou %.2f, l1 %.2f, conf %.2f, cls %.2f, imgsize %d, time: %.2f]'
                    %
                    (epoch, epochs, iter_i, epoch_size, tmp_lr,
                     sum(anchor_loss for anchor_loss in
                         loss_dict_reduced['anchor_losses']).item(),
                     sum(iou_loss for iou_loss in
                         loss_dict_reduced['iou_losses']).item(),
                     sum(l1_loss
                         for l1_loss in loss_dict_reduced['l1_losses']).item(),
                     sum(conf_loss for conf_loss in
                         loss_dict_reduced['conf_losses']).item(),
                     sum(cls_loss
                         for cls_loss in loss_dict_reduced['cls_losses']).item(
                         ), input_size[0], end - start),
                    flush=True)

                start = time.time()
                if args.tfboard and save_to_disk:
                    tblogger.add_scalar(
                        'train/total_loss',
                        sum(loss
                            for loss in loss_dict_reduced['losses']).item(),
                        epoch * epoch_size + iter_i)

            # random resizing
            if random_resize and iter_i % 10 == 0 and iter_i > 0:
                tensor = torch.LongTensor(1).to(device)
                if args.distributed:
                    distributed_util.synchronize()

                if save_to_disk:
                    if epoch > epochs - 10:
                        size = 416 if args.dataset == 'VOC' else 608
                    else:
                        size = random.randint(*(10, 19))
                        size = int(32 * size)
                    tensor.fill_(size)

                if args.distributed:
                    distributed_util.synchronize()
                    dist.broadcast(tensor, 0)

                input_size = dataloader.change_input_dim(
                    multiple=tensor.item(), random_range=None)

                if args.distributed:
                    distributed_util.synchronize()

        epoch += 1
    if not args.test and save_to_disk:
        torch.save(
            model.module.state_dict(),
            os.path.join(args.save_dir,
                         "yolov3_" + args.dataset + '_Final.pth'))

    if args.distributed:
        distributed_util.synchronize()
    ap50_95, ap50 = evaluator.evaluate(model, args.half)

    if args.tfboard and save_to_disk:
        tblogger.close()
def train():
    args = parse_args()
    data_dir = coco_root

    path_to_save = os.path.join(args.save_folder, args.version)
    os.makedirs(path_to_save, exist_ok=True)

    hr = False
    if args.high_resolution:
        print('use hi-res backbone')
        hr = True

    cfg = coco_af

    if args.cuda:
        print('use cuda')
        cudnn.benchmark = True
        device = torch.device("cuda")
    else:
        device = torch.device("cpu")

    if args.mosaic:
        print("use Mosaic Augmentation ...")

    # multi scale
    if args.multi_scale:
        print('Let us use the multi-scale trick.')
        input_size = [640, 640]
    else:
        input_size = [416, 416]

    print("Setting Arguments.. : ", args)
    print("----------------------------------------------------------")
    print('Loading the MSCOCO dataset...')
    # dataset
    dataset = COCODataset(data_dir=data_dir,
                          img_size=input_size[0],
                          transform=SSDAugmentation(input_size),
                          debug=args.debug,
                          mosaic=args.mosaic)

    # build model
    if args.version == 'yolo':
        from models.yolo import myYOLO
        yolo_net = myYOLO(device,
                          input_size=input_size,
                          num_classes=args.num_classes,
                          trainable=True,
                          hr=hr)
        print('Let us train yolo on the COCO dataset ......')

    else:
        print('We only support YOLO !!!')
        exit()

    print("----------------------------------------------------------")
    print('The dataset size:', len(dataset))
    print("----------------------------------------------------------")

    # use tfboard
    if args.tfboard:
        print('use tensorboard')
        from torch.utils.tensorboard import SummaryWriter
        c_time = time.strftime('%Y-%m-%d %H:%M:%S',
                               time.localtime(time.time()))
        log_path = os.path.join('log/coco/', args.version, c_time)
        os.makedirs(log_path, exist_ok=True)

        writer = SummaryWriter(log_path)

    model = yolo_net
    model.to(device).train()

    dataloader = torch.utils.data.DataLoader(dataset,
                                             batch_size=args.batch_size,
                                             shuffle=True,
                                             collate_fn=detection_collate,
                                             num_workers=args.num_workers)

    evaluator = COCOAPIEvaluator(data_dir=data_dir,
                                 img_size=cfg['min_dim'],
                                 device=device,
                                 transform=BaseTransform(cfg['min_dim']))

    # optimizer setup
    base_lr = args.lr
    tmp_lr = base_lr
    optimizer = optim.SGD(model.parameters(),
                          lr=args.lr,
                          momentum=args.momentum,
                          weight_decay=args.weight_decay)

    max_epoch = cfg['max_epoch']
    epoch_size = len(dataset) // args.batch_size

    # start training loop
    t0 = time.time()

    for epoch in range(max_epoch):

        # use cos lr
        if args.cos and epoch > 20 and epoch <= max_epoch - 20:
            # use cos lr
            tmp_lr = 0.00001 + 0.5 * (base_lr - 0.00001) * (
                1 + math.cos(math.pi * (epoch - 20) * 1. / (max_epoch - 20)))
            set_lr(optimizer, tmp_lr)

        elif args.cos and epoch > max_epoch - 20:
            tmp_lr = 0.00001
            set_lr(optimizer, tmp_lr)

        # use step lr
        else:
            if epoch in cfg['lr_epoch']:
                tmp_lr = tmp_lr * 0.1
                set_lr(optimizer, tmp_lr)

        for iter_i, (images, targets) in enumerate(dataloader):
            # WarmUp strategy for learning rate
            if not args.no_warm_up:
                if epoch < args.wp_epoch:
                    tmp_lr = base_lr * pow((iter_i + epoch * epoch_size) * 1. /
                                           (args.wp_epoch * epoch_size), 4)
                    # tmp_lr = 1e-6 + (base_lr-1e-6) * (iter_i+epoch*epoch_size) / (epoch_size * (args.wp_epoch))
                    set_lr(optimizer, tmp_lr)

                elif epoch == args.wp_epoch and iter_i == 0:
                    tmp_lr = base_lr
                    set_lr(optimizer, tmp_lr)

            # to device
            images = images.to(device)

            # multi-scale trick
            if iter_i % 10 == 0 and iter_i > 0 and args.multi_scale:
                # randomly choose a new size
                size = random.randint(10, 19) * 32
                input_size = [size, size]
                model.set_grid(input_size)
            if args.multi_scale:
                # interpolate
                images = torch.nn.functional.interpolate(images,
                                                         size=input_size,
                                                         mode='bilinear',
                                                         align_corners=False)

            # make labels
            targets = [label.tolist() for label in targets]
            targets = tools.gt_creator(input_size=input_size,
                                       stride=yolo_net.stride,
                                       label_lists=targets)
            targets = torch.tensor(targets).float().to(device)

            # forward and loss
            conf_loss, cls_loss, txtytwth_loss, total_loss = model(
                images, target=targets)

            # backprop
            total_loss.backward()
            optimizer.step()
            optimizer.zero_grad()

            if args.tfboard:
                # viz loss
                writer.add_scalar('object loss', conf_loss.item(),
                                  iter_i + epoch * epoch_size)
                writer.add_scalar('class loss', cls_loss.item(),
                                  iter_i + epoch * epoch_size)
                writer.add_scalar('local loss', txtytwth_loss.item(),
                                  iter_i + epoch * epoch_size)

            if iter_i % 10 == 0:

                t1 = time.time()
                print(
                    '[Epoch %d/%d][Iter %d/%d][lr %.6f]'
                    '[Loss: obj %.2f || cls %.2f || bbox %.2f || total %.2f || size %d || time: %.2f]'
                    % (epoch + 1, max_epoch, iter_i, epoch_size, tmp_lr,
                       conf_loss.item(), cls_loss.item(), txtytwth_loss.item(),
                       total_loss.item(), input_size[0], t1 - t0),
                    flush=True)

                t0 = time.time()

        if (epoch + 1) % 10 == 0:
            print('Saving state, epoch:', epoch + 1)
            torch.save(
                model.state_dict(),
                os.path.join(path_to_save,
                             args.version + '_' + repr(epoch + 1) + '.pth'))

        # COCO evaluation
        if (epoch + 1) % args.eval_epoch == 0:
            model.trainable = False
            model.set_grid(cfg['min_dim'])
            # evaluate
            ap50_95, ap50 = evaluator.evaluate(model)
            print('ap50 : ', ap50)
            print('ap50_95 : ', ap50_95)
            # convert to training mode.
            model.trainable = True
            model.train()
            if args.tfboard:
                writer.add_scalar('val/COCOAP50', ap50, epoch + 1)
                writer.add_scalar('val/COCOAP50_95', ap50_95, epoch + 1)
def train(net, device):
    global cfg, hr
    # set GPU

    use_focal = False
    if args.use_focal == 1:
        print("Let's use focal loss for objectness !!!")
        use_focal = True

    if args.multi_scale == 1:
        print('Let us use the multi-scale trick.')
        ms_inds = range(len(cfg['multi_scale']))
        dataset = COCODataset(data_dir=data_dir,
                              img_size=608,
                              transform=SSDAugmentation([608, 608], MEANS),
                              debug=args.debug)
    else:
        dataset = COCODataset(data_dir=data_dir,
                              img_size=cfg['min_dim'][0],
                              transform=SSDAugmentation(cfg['min_dim'], MEANS),
                              debug=args.debug)

    print("Setting Arguments.. : ", args)
    print("----------------------------------------------------------")
    print('Loading the MSCOCO dataset...')
    print('Training model on:', dataset.name)
    print('The dataset size:', len(dataset))
    print('The obj weight : ', args.obj)
    print('The noobj weight : ', args.noobj)
    print("----------------------------------------------------------")

    input_size = cfg['min_dim']
    num_classes = args.num_classes
    batch_size = args.batch_size
    save_folder = args.save_folder

    if not os.path.exists(save_folder):
        os.mkdir(save_folder)

    # using tfboard
    from tensorboardX import SummaryWriter
    c_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
    log_path = 'log/yolo_v2/coco/' + c_time
    if not os.path.exists(log_path):
        os.mkdir(log_path)
    if not os.path.exists(log_path):
        os.mkdir(log_path)

    writer = SummaryWriter(log_path)

    if args.high_resolution == 1:
        hr = True

    print('Let us train yolo-v2 on the MSCOCO dataset ......')

    model = net
    model.to(device).train()

    dataloader = torch.utils.data.DataLoader(dataset,
                                             batch_size=batch_size,
                                             shuffle=True,
                                             collate_fn=detection_collate,
                                             num_workers=args.n_cpu)

    evaluator = COCOAPIEvaluator(data_dir=data_dir,
                                 img_size=cfg['min_dim'],
                                 device=device,
                                 transform=BaseTransform(
                                     cfg['min_dim'], MEANS))

    # optimizer setup
    # optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum,
    #                       dampening=0, weight_decay=args.weight_decay)
    # optimizer = optim.Adam(model.parameters())
    lr = args.lr
    optimizer = optim.RMSprop(model.parameters(), lr=args.lr)

    step_index = 0
    epoch_size = len(dataset) // args.batch_size
    # each part of loss weight
    obj_w = 1.0
    cla_w = 1.0
    box_w = 2.0

    # start training loop
    iteration = 0
    for epoch in range(cfg['max_epoch']):
        batch_iterator = iter(dataloader)

        # No WarmUp strategy or WarmUp tage has finished.
        if epoch in cfg['lr_epoch']:
            step_index += 1
            lr = adjust_learning_rate(optimizer, args.gamma, step_index)

        # COCO evaluation
        if (epoch + 1) % args.eval_epoch == 0:
            model.trainable = False
            ap50_95, ap50 = evaluator.evaluate(model)
            print('ap50 : ', ap50)
            print('ap90_95 : ', ap50_95)
            model.trainable = True
            model.train()
            writer.add_scalar('val/COCOAP50', ap50, epoch + 1)
            writer.add_scalar('val/COCOAP50_95', ap50_95, epoch + 1)

        # subdivision loop
        optimizer.zero_grad()
        for images, targets in batch_iterator:
            iteration += 1

            # multi-scale trick
            if iteration % 10 == 0 and args.multi_scale == 1:
                ms_ind = random.sample(ms_inds, 1)[0]
                input_size = cfg['multi_scale'][int(ms_ind)]

            # multi scale
            if args.multi_scale == 1:
                images = torch.nn.functional.interpolate(images,
                                                         size=input_size,
                                                         mode='bilinear',
                                                         align_corners=True)

            targets = [label.tolist() for label in targets]
            if args.version == 'yolo_v2':
                targets = tools.gt_creator(input_size,
                                           yolo_net.stride,
                                           args.num_classes,
                                           targets,
                                           name='COCO')
            elif args.version == 'yolo_v3':
                targets = tools.multi_gt_creator(input_size,
                                                 yolo_net.stride,
                                                 args.num_classes,
                                                 targets,
                                                 name='COCO')

            targets = torch.tensor(targets).float().to(device)

            t0 = time.time()
            out = model(images.to(device))
            obj_loss, class_loss, box_loss = tools.loss(
                out,
                targets,
                num_classes=args.num_classes,
                use_focal=use_focal,
                obj=args.obj,
                noobj=args.noobj)
            total_loss = obj_w * obj_loss + cla_w * class_loss + box_w * box_loss

            # viz loss
            writer.add_scalar('object loss', obj_loss.item(), iteration)
            writer.add_scalar('class loss', class_loss.item(), iteration)
            writer.add_scalar('local loss', box_loss.item(), iteration)
            writer.add_scalar('total loss', total_loss.item(), iteration)
            # backprop
            total_loss.backward()
            optimizer.step()
            t1 = time.time()

            if iteration % 10 == 0:
                print('timer: %.4f sec.' % (t1 - t0))
                # print(obj_loss.item(), class_loss.item(), box_loss.item())
                print('Epoch[%d / %d]' % (epoch+1, cfg['max_epoch']) + ' || iter ' + repr(iteration) + \
                      ' || Loss: %.4f ||' % (total_loss.item()) + ' || lr: %.8f ||' % (lr) + ' || input size: %d ||' % input_size[0], end=' ')

        if (epoch + 1) % 10 == 0:
            print('Saving state, epoch:', epoch + 1)
            torch.save(
                yolo_net.state_dict(), save_folder + '/' + args.version + '_' +
                repr(epoch + 1) + '.pth')
Example #9
0
def main():
    """
    YOLOv3 trainer. See README for details.
    """
    args = parse_args()
    print("Setting Arguments.. : ", args)

    cuda = torch.cuda.is_available() and args.use_cuda
    os.makedirs(args.checkpoint_dir, exist_ok=True)

    # Parse config settings
    with open(args.cfg, 'r') as f:
        cfg = yaml.load(f)

    print("successfully loaded config file: ", cfg)

    lr = cfg['TRAIN']['LR']
    momentum = cfg['TRAIN']['MOMENTUM']
    decay = cfg['TRAIN']['DECAY']
    burn_in = cfg['TRAIN']['BURN_IN']
    iter_size = cfg['TRAIN']['MAXITER']
    steps = eval(cfg['TRAIN']['STEPS'])
    batch_size = cfg['TRAIN']['BATCHSIZE']
    subdivision = cfg['TRAIN']['SUBDIVISION']
    ignore_thre = cfg['TRAIN']['IGNORETHRE']
    random_resize = cfg['AUGMENTATION']['RANDRESIZE']

    print('effective_batch_size = batch_size * iter_size = %d * %d' %
          (batch_size, subdivision))

    # Learning rate setup
    base_lr = lr

    # Initiate model
    model = YOLOv3(cfg['MODEL'], ignore_thre=ignore_thre)

    if args.weights_path:
        print("loading darknet weights....", args.weights_path)
        #parse_yolo_weights(model, args.weights_path)
        model.load_weights(args.weights_path)
    elif args.checkpoint:
        print("loading pytorch ckpt...", args.checkpoint)
        state = torch.load(args.checkpoint)
        if 'model_state_dict' in state.keys():
            model.load_state_dict(state['model_state_dict'])
        else:
            model.load_state_dict(state)

    if cuda:
        print("using cuda")
        model = model.cuda()
    #model.save_weights('../darknet/torch-yolo-tiny.weights')
    if args.tfboard:
        print("using tfboard")
        from tensorboardX import SummaryWriter
        tblogger = SummaryWriter(args.tfboard)

    model.train()

    imgsize = cfg['TRAIN']['IMGSIZE']

    evaluator = COCOAPIEvaluator(model_type=cfg['MODEL']['TYPE'],
                                 data_dir='COCO/',
                                 img_size=cfg['TEST']['IMGSIZE'],
                                 confthre=cfg['TEST']['CONFTHRE'],
                                 nmsthre=cfg['TEST']['NMSTHRE'])
    print('use image size:', cfg['TEST']['IMGSIZE'])

    # optimizer setup
    # set weight decay only on conv.weight
    params_dict = dict(model.named_parameters())
    params = []
    for key, value in params_dict.items():
        if 'conv.weight' in key:
            params += [{
                'params': value,
                'weight_decay': decay * batch_size * subdivision
            }]
        else:
            params += [{'params': value, 'weight_decay': 0.0}]
    optimizer = optim.SGD(params,
                          lr=base_lr,
                          momentum=momentum,
                          dampening=0,
                          weight_decay=decay * batch_size * subdivision)

    if args.checkpoint:
        if 'optimizer_state_dict' in state.keys():
            optimizer.load_state_dict(state['optimizer_state_dict'])
            iter_state = state['iter'] + 1

    # TODO: replace the following scheduler with the PyTorch's official one

    ap50_95, ap50 = evaluator.evaluate(model)
Example #10
0
def train():
    args = parse_args()
    data_dir = args.dataset_root

    path_to_save = os.path.join(args.save_folder, args.version)
    os.makedirs(path_to_save, exist_ok=True)
    
    cfg = coco_cfg

    if args.cuda:
        print('use cuda')
        cudnn.benchmark = True
        device = torch.device("cuda")
    else:
        device = torch.device("cpu")

    input_size = cfg['min_dim']
    dataset = COCODataset(
                data_dir=data_dir,
                img_size=cfg['min_dim'],
                transform=SSDAugmentation(cfg['min_dim'], mean=(0.406, 0.456, 0.485), std=(0.225, 0.224, 0.229)),
                debug=args.debug)

    # build model
    if args.version == 'centernet':
        from models.centernet import CenterNet
        
        net = CenterNet(device, input_size=input_size, num_classes=args.num_classes, trainable=True)
        print('Let us train centernet on the COCO dataset ......')

    else:
        print('Unknown version !!!')
        exit()

    
    print("Setting Arguments.. : ", args)
    print("----------------------------------------------------------")
    print('Loading the MSCOCO dataset...')
    print('Training model on:', dataset.name)
    print('The dataset size:', len(dataset))
    print("----------------------------------------------------------")


    # use tfboard
    if args.tfboard:
        print('use tensorboard')
        from torch.utils.tensorboard import SummaryWriter
        c_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        log_path = os.path.join('log/coco/', args.version, c_time)
        os.makedirs(log_path, exist_ok=True)

        writer = SummaryWriter(log_path)

    
    model = net
    model.to(device).train()

    dataloader = torch.utils.data.DataLoader(
                    dataset, 
                    batch_size=args.batch_size, 
                    shuffle=True, 
                    collate_fn=detection_collate,
                    num_workers=args.num_workers)

    evaluator = COCOAPIEvaluator(
                    data_dir=data_dir,
                    img_size=cfg['min_dim'],
                    device=device,
                    transform=BaseTransform(cfg['min_dim'], mean=(0.406, 0.456, 0.485), std=(0.225, 0.224, 0.229))
                    )

    # optimizer setup
    base_lr = args.lr
    tmp_lr = base_lr
    optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum,
                                            weight_decay=args.weight_decay)

    max_epoch = cfg['max_epoch']
    epoch_size = len(dataset) // args.batch_size

    # start training loop
    t0 = time.time()

    for epoch in range(max_epoch):

        # use cos lr
        if args.cos and epoch > 20 and epoch <= max_epoch - 20:
            # use cos lr
            tmp_lr = 0.00001 + 0.5*(base_lr-0.00001)*(1+math.cos(math.pi*(epoch-20)*1./ (max_epoch-20)))
            set_lr(optimizer, tmp_lr)

        elif args.cos and epoch > max_epoch - 20:
            tmp_lr = 0.00001
            set_lr(optimizer, tmp_lr)
        
        # use step lr
        else:
            if epoch in cfg['lr_epoch']:
                tmp_lr = tmp_lr * 0.1
                set_lr(optimizer, tmp_lr)

        for iter_i, (images, targets) in enumerate(dataloader):
            # WarmUp strategy for learning rate
            if not args.no_warm_up:
                if epoch < args.wp_epoch:
                    tmp_lr = base_lr * pow((iter_i+epoch*epoch_size)*1. / (args.wp_epoch*epoch_size), 4)
                    # tmp_lr = 1e-6 + (base_lr-1e-6) * (iter_i+epoch*epoch_size) / (epoch_size * (args.wp_epoch))
                    set_lr(optimizer, tmp_lr)

                elif epoch == args.wp_epoch and iter_i == 0:
                    tmp_lr = base_lr
                    set_lr(optimizer, tmp_lr)
        

            targets = [label.tolist() for label in targets]
            targets = tools.gt_creator(input_size, net.stride, args.num_classes, targets)


            # to device
            images = images.to(device)
            targets = torch.tensor(targets).float().to(device)

            # forward and loss
            cls_loss, txty_loss, twth_loss, total_loss = model(images, target=targets)
                     
            # backprop and update
            total_loss.backward()
            optimizer.step()
            optimizer.zero_grad()

            if iter_i % 10 == 0:
                if args.tfboard:
                    # viz loss
                    writer.add_scalar('class loss', cls_loss.item(), iter_i + epoch * epoch_size)
                    writer.add_scalar('txty loss',  txty_loss.item(), iter_i + epoch * epoch_size)
                    writer.add_scalar('twth loss',  twth_loss.item(), iter_i + epoch * epoch_size)
                    writer.add_scalar('total loss', total_loss.item(), iter_i + epoch * epoch_size)
                
                t1 = time.time()
                print('[Epoch %d/%d][Iter %d/%d][lr %.6f]'
                    '[Loss: cls %.2f || txty %.2f || twth %.2f ||total %.2f || size %d || time: %.2f]'
                        % (epoch+1, max_epoch, iter_i, epoch_size, tmp_lr,
                            cls_loss.item(), txty_loss.item(), twth_loss.item(), total_loss.item(), input_size, t1-t0),
                        flush=True)

                t0 = time.time()


        # COCO evaluation
        if (epoch + 1) % args.eval_epoch == 0:
            model.trainable = False
            # evaluate
            ap50_95, ap50 = evaluator.evaluate(model)
            print('ap50 : ', ap50)
            print('ap50_95 : ', ap50_95)
            # convert to training mode.
            model.trainable = True
            model.train()
            if args.tfboard:
                writer.add_scalar('val/COCOAP50', ap50, epoch + 1)
                writer.add_scalar('val/COCOAP50_95', ap50_95, epoch + 1)

        if (epoch + 1) % 10 == 0:
            print('Saving state, epoch:', epoch + 1)
            torch.save(model.state_dict(), os.path.join(path_to_save, 
                        args.version + '_' + repr(epoch + 1) + '.pth')
                        )  
Example #11
0
def main():
    """
    YOLOv3 trainer. See README for details.
    """
    args = parse_args()
    print("Setting Arguments.. : ", args)

    cuda = torch.cuda.is_available() and args.use_cuda
    os.makedirs(args.checkpoint_dir, exist_ok=True)

    # Parse config settings
    with open(args.cfg, 'r') as f:
        cfg = yaml.load(f)

    print("successfully loaded config file: ", cfg)

    momentum = cfg['TRAIN']['MOMENTUM']
    decay = cfg['TRAIN']['DECAY']
    burn_in = cfg['TRAIN']['BURN_IN']
    iter_size = cfg['TRAIN']['MAXITER']
    steps = eval(cfg['TRAIN']['STEPS'])
    batch_size = cfg['TRAIN']['BATCHSIZE']
    subdivision = cfg['TRAIN']['SUBDIVISION']
    ignore_thre = cfg['TRAIN']['IGNORETHRE']
    random_resize = cfg['AUGMENTATION']['RANDRESIZE']
    base_lr = cfg['TRAIN']['LR'] / batch_size / subdivision

    print('effective_batch_size = batch_size * iter_size = %d * %d' %
          (batch_size, subdivision))

    # Learning rate setup
    def burnin_schedule(i):
        if i < burn_in:
            factor = pow(i / burn_in, 4)
        elif i < steps[0]:
            factor = 1.0
        elif i < steps[1]:
            factor = 0.1
        else:
            factor = 0.01
        return factor

    # Initiate model
    model = YOLOv3(cfg['MODEL'], ignore_thre=ignore_thre)

    if args.weights_path:
        print("loading darknet weights....", args.weights_path)
        parse_yolo_weights(model, args.weights_path)
    elif args.checkpoint:
        print("loading pytorch ckpt...", args.checkpoint)
        state = torch.load(args.checkpoint)
        if 'model_state_dict' in state.keys():
            model.load_state_dict(state['model_state_dict'])
        else:
            model.load_state_dict(state)

    if cuda:
        print("using cuda") 
        model = model.cuda()

    if args.tfboard:
        print("using tfboard")
        from tensorboardX import SummaryWriter
        tblogger = SummaryWriter(args.tfboard)

    model.train()

    imgsize = cfg['TRAIN']['IMGSIZE']
    dataset = COCODataset(model_type=cfg['MODEL']['TYPE'],
                  data_dir='COCO/',
                  img_size=imgsize,
                  augmentation=cfg['AUGMENTATION'],
                  debug=args.debug)

    dataloader = torch.utils.data.DataLoader(
        dataset, batch_size=batch_size, shuffle=True, num_workers=args.n_cpu)
    dataiterator = iter(dataloader)

    evaluator = COCOAPIEvaluator(model_type=cfg['MODEL']['TYPE'],
                    data_dir='COCO/',
                    img_size=cfg['TEST']['IMGSIZE'],
                    confthre=cfg['TEST']['CONFTHRE'],
                    nmsthre=cfg['TEST']['NMSTHRE'])

    dtype = torch.cuda.FloatTensor if cuda else torch.FloatTensor

    # optimizer setup
    # set weight decay only on conv.weight
    params_dict = dict(model.named_parameters())
    params = []
    for key, value in params_dict.items():
        if 'conv.weight' in key:
            params += [{'params':value, 'weight_decay':decay * batch_size * subdivision}]
        else:
            params += [{'params':value, 'weight_decay':0.0}]
    optimizer = optim.SGD(params, lr=base_lr, momentum=momentum,
                          dampening=0, weight_decay=decay * batch_size * subdivision)

    iter_state = 0

    if args.checkpoint:
        if 'optimizer_state_dict' in state.keys():
            optimizer.load_state_dict(state['optimizer_state_dict'])
            iter_state = state['iter'] + 1

    scheduler = optim.lr_scheduler.LambdaLR(optimizer, burnin_schedule)

    # start training loop
    for iter_i in range(iter_state, iter_size + 1):

        # COCO evaluation
        if iter_i % args.eval_interval == 0 and iter_i > 0:
            ap50_95, ap50 = evaluator.evaluate(model)
            model.train()
            if args.tfboard:
                tblogger.add_scalar('val/COCOAP50', ap50, iter_i)
                tblogger.add_scalar('val/COCOAP50_95', ap50_95, iter_i)

        # subdivision loop
        optimizer.zero_grad()
        for inner_iter_i in range(subdivision):
            try:
                imgs, targets, _, _ = next(dataiterator)  # load a batch
            except StopIteration:
                dataiterator = iter(dataloader)
                imgs, targets, _, _ = next(dataiterator)  # load a batch
            imgs = Variable(imgs.type(dtype))
            targets = Variable(targets.type(dtype), requires_grad=False)
            loss = model(imgs, targets)
            loss.backward()

        optimizer.step()
        scheduler.step()

        if iter_i % 10 == 0:
            # logging
            current_lr = scheduler.get_lr()[0] * batch_size * subdivision
            print('[Iter %d/%d] [lr %f] '
                  '[Losses: xy %f, wh %f, conf %f, cls %f, total %f, imgsize %d]'
                  % (iter_i, iter_size, current_lr,
                     model.loss_dict['xy'], model.loss_dict['wh'],
                     model.loss_dict['conf'], model.loss_dict['cls'], 
                     model.loss_dict['l2'], imgsize),
                  flush=True)

            if args.tfboard:
                tblogger.add_scalar('train/total_loss', model.loss_dict['l2'], iter_i)

            # random resizing
            if random_resize:
                imgsize = (random.randint(0, 9) % 10 + 10) * 32
                dataset.img_shape = (imgsize, imgsize)
                dataset.img_size = imgsize
                dataloader = torch.utils.data.DataLoader(
                    dataset, batch_size=batch_size, shuffle=True, num_workers=args.n_cpu)
                dataiterator = iter(dataloader)

        # save checkpoint
        if iter_i > 0 and (iter_i % args.checkpoint_interval == 0):
            torch.save({'iter': iter_i,
                        'model_state_dict': model.state_dict(),
                        'optimizer_state_dict': optimizer.state_dict(),
                        },
                        os.path.join(args.checkpoint_dir, "snapshot"+str(iter_i)+".ckpt"))
    if args.tfboard:
        tblogger.close()
Example #12
0
def train():
    args = parse_args()

    path_to_save = os.path.join(args.save_folder, args.dataset, args.version)
    os.makedirs(path_to_save, exist_ok=True)

    # cuda
    if args.cuda:
        print('use cuda')
        cudnn.benchmark = True
        device = torch.device("cuda")
    else:
        device = torch.device("cpu")

    # mosaic augmentation
    if args.mosaic:
        print('use Mosaic Augmentation ...')

    # multi-scale
    if args.multi_scale:
        print('use the multi-scale trick ...')
        train_size = [640, 640]
        val_size = [512, 512]
    else:
        train_size = [512, 512]
        val_size = [512, 512]

    cfg = train_cfg
    # dataset and evaluator
    print("Setting Arguments.. : ", args)
    print("----------------------------------------------------------")
    print('Loading the dataset...')

    if args.dataset == 'voc':
        data_dir = VOC_ROOT
        num_classes = 20
        dataset = VOCDetection(root=data_dir, img_size=train_size[0],
                                transform=SSDAugmentation(train_size),
                                mosaic=args.mosaic
                                )

        evaluator = VOCAPIEvaluator(data_root=data_dir,
                                    img_size=val_size,
                                    device=device,
                                    transform=BaseTransform(val_size),
                                    labelmap=VOC_CLASSES
                                    )

    elif args.dataset == 'coco':
        data_dir = coco_root
        num_classes = 80
        dataset = COCODataset(
                    data_dir=data_dir,
                    img_size=train_size[0],
                    transform=SSDAugmentation(train_size),
                    debug=args.debug,
                    mosaic=args.mosaic
                    )


        evaluator = COCOAPIEvaluator(
                        data_dir=data_dir,
                        img_size=val_size,
                        device=device,
                        transform=BaseTransform(val_size)
                        )
    
    else:
        print('unknow dataset !! Only support voc and coco !!')
        exit(0)
    
    print('Training model on:', dataset.name)
    print('The dataset size:', len(dataset))
    print("----------------------------------------------------------")

    # dataloader
    dataloader = torch.utils.data.DataLoader(
                    dataset, 
                    batch_size=args.batch_size, 
                    shuffle=True, 
                    collate_fn=detection_collate,
                    num_workers=args.num_workers,
                    pin_memory=True
                    )

    # build model
    if args.version == 'centernet':
        from models.centernet import CenterNet
        
        net = CenterNet(device, input_size=train_size, num_classes=num_classes, trainable=True)
        print('Let us train centernet on the %s dataset ......' % (args.dataset))

    else:
        print('Unknown version !!!')
        exit()

    model = net
    model.to(device).train()

    # use tfboard
    if args.tfboard:
        print('use tensorboard')
        from torch.utils.tensorboard import SummaryWriter
        c_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        log_path = os.path.join('log/coco/', args.version, c_time)
        os.makedirs(log_path, exist_ok=True)

        writer = SummaryWriter(log_path)
    
    # keep training
    if args.resume is not None:
        print('keep training model: %s' % (args.resume))
        model.load_state_dict(torch.load(args.resume, map_location=device))

    # optimizer setup
    base_lr = args.lr
    tmp_lr = base_lr
    optimizer = optim.SGD(model.parameters(), 
                            lr=args.lr, 
                            momentum=args.momentum,
                            weight_decay=args.weight_decay
                            )

    max_epoch = cfg['max_epoch']
    epoch_size = len(dataset) // args.batch_size

    # start training loop
    t0 = time.time()

    for epoch in range(args.start_epoch, max_epoch):

        # use cos lr
        if args.cos and epoch > 20 and epoch <= max_epoch - 20:
            # use cos lr
            tmp_lr = 0.00001 + 0.5*(base_lr-0.00001)*(1+math.cos(math.pi*(epoch-20)*1./ (max_epoch-20)))
            set_lr(optimizer, tmp_lr)

        elif args.cos and epoch > max_epoch - 20:
            tmp_lr = 0.00001
            set_lr(optimizer, tmp_lr)
        
        # use step lr
        else:
            if epoch in cfg['lr_epoch']:
                tmp_lr = tmp_lr * 0.1
                set_lr(optimizer, tmp_lr)
    

        for iter_i, (images, targets) in enumerate(dataloader):
            # WarmUp strategy for learning rate
            if not args.no_warm_up:
                if epoch < args.wp_epoch:
                    tmp_lr = base_lr * pow((iter_i+epoch*epoch_size)*1. / (args.wp_epoch*epoch_size), 4)
                    # tmp_lr = 1e-6 + (base_lr-1e-6) * (iter_i+epoch*epoch_size) / (epoch_size * (args.wp_epoch))
                    set_lr(optimizer, tmp_lr)

                elif epoch == args.wp_epoch and iter_i == 0:
                    tmp_lr = base_lr
                    set_lr(optimizer, tmp_lr)
        
            # to device
            images = images.to(device)

            # multi-scale trick
            if iter_i % 10 == 0 and iter_i > 0 and args.multi_scale:
                # randomly choose a new size
                size = random.randint(10, 19) * 32
                train_size = [size, size]
                model.set_grid(train_size)
            if args.multi_scale:
                # interpolate
                images = torch.nn.functional.interpolate(images, size=train_size, mode='bilinear', align_corners=False)
            
            # make train label
            targets = [label.tolist() for label in targets]
            targets = tools.gt_creator(train_size, net.stride, args.num_classes, targets)
            targets = torch.tensor(targets).float().to(device)

            # forward and loss
            cls_loss, txty_loss, twth_loss, total_loss = model(images, target=targets)

            # backprop
            total_loss.backward()        
            optimizer.step()
            optimizer.zero_grad()

            if iter_i % 10 == 0:
                if args.tfboard:
                    # viz loss
                    writer.add_scalar('class loss', cls_loss.item(), iter_i + epoch * epoch_size)
                    writer.add_scalar('txty loss',  txty_loss.item(), iter_i + epoch * epoch_size)
                    writer.add_scalar('twth loss',  twth_loss.item(), iter_i + epoch * epoch_size)
                    writer.add_scalar('total loss', total_loss.item(), iter_i + epoch * epoch_size)
                
                t1 = time.time()
                print('[Epoch %d/%d][Iter %d/%d][lr %.6f]'
                    '[Loss: cls %.2f || txty %.2f || twth %.2f ||total %.2f || size %d || time: %.2f]'
                        % (epoch+1, max_epoch, iter_i, epoch_size, tmp_lr,
                            cls_loss.item(), txty_loss.item(), twth_loss.item(), total_loss.item(), train_size[0], t1-t0),
                        flush=True)

                t0 = time.time()

        # evaluation
        if (epoch) % args.eval_epoch == 0:
            model.trainable = False
            model.set_grid(val_size)
            model.eval()

            # evaluate
            evaluator.evaluate(model)

            # convert to training mode.
            model.trainable = True
            model.set_grid(train_size)
            model.train()

        # save model
        if (epoch + 1) % 10 == 0:
            print('Saving state, epoch:', epoch + 1)
            torch.save(model.state_dict(), os.path.join(path_to_save, 
                        args.version + '_' + repr(epoch + 1) + '.pth')
                        )  
Example #13
0
def main():
    args = parse()
    np.random.seed(args.seed)
    print('arguments: ', args)

    # Model setup
    if args.dataset == 'coco2017':
        train_data = COCODataset()
    test_data = COCODataset(json_file='instances_val2017.json',
                            name='val2017',
                            id_list_file='val2017.txt')
    train_class_ids = train_data.class_ids
    test_ids = test_data.ids
    cocoanns = test_data.coco
    if args.extractor == 'vgg16':
        mask_rcnn = MaskRCNNVGG16(n_fg_class=80,
                                  pretrained_model=args.pretrained,
                                  roi_size=args.roi_size,
                                  roi_align=args.roialign)
    elif args.extractor == 'resnet50':
        mask_rcnn = MaskRCNNResNet(n_fg_class=80,
                                   pretrained_model=args.pretrained,
                                   roi_size=args.roi_size,
                                   n_layers=50,
                                   roi_align=args.roialign,
                                   class_ids=train_class_ids)
    elif args.extractor == 'resnet101':
        mask_rcnn = MaskRCNNResNet(n_fg_class=80,
                                   pretrained_model=args.pretrained,
                                   roi_size=args.roi_size,
                                   n_layers=101,
                                   roi_align=args.roialign,
                                   class_ids=train_class_ids)
    mask_rcnn.use_preset('evaluate')
    model = MaskRCNNTrainChain(mask_rcnn,
                               gamma=args.gamma,
                               roi_size=args.roi_size)

    # Trainer setup
    if args.gpu >= 0:
        chainer.cuda.get_device_from_id(args.gpu).use()
        model.to_gpu()
    optimizer = chainer.optimizers.MomentumSGD(lr=args.lr, momentum=0.9)
    #optimizer = chainer.optimizers.Adam()#alpha=0.001, beta1=0.9, beta2=0.999 , eps=0.00000001)
    optimizer.setup(model)
    optimizer.add_hook(chainer.optimizer.WeightDecay(rate=0.0001))

    train_data = TransformDataset(train_data,
                                  Transform(mask_rcnn, train_class_ids))
    test_data = TransformDataset(test_data,
                                 Transform(mask_rcnn, train_class_ids))
    train_iter = chainer.iterators.SerialIterator(train_data,
                                                  batch_size=args.batchsize)
    test_iter = chainer.iterators.SerialIterator(test_data,
                                                 batch_size=1,
                                                 repeat=False,
                                                 shuffle=False)
    updater = SubDivisionUpdater(train_iter,
                                 optimizer,
                                 device=args.gpu,
                                 subdivisions=args.batchsize)
    #updater = ParallelUpdater(train_iter, optimizer, devices={"main": 0, "second": 1}, converter=convert ) #for training with multiple GPUs
    trainer = training.Trainer(updater, (args.iteration, 'iteration'),
                               out=args.out)

    # Extensions
    trainer.extend(extensions.snapshot_object(model.mask_rcnn,
                                              'snapshot_model.npz'),
                   trigger=(args.snapshot, 'iteration'))
    trainer.extend(extensions.ExponentialShift('lr', 10),
                   trigger=ManualScheduleTrigger([args.lr_initialchange],
                                                 'iteration'))
    trainer.extend(extensions.ExponentialShift('lr', 0.1),
                   trigger=(args.lr_step, 'iteration'))
    if args.resume is not None:
        chainer.serializers.load_npz(args.resume, model.mask_rcnn)
    if args.freeze_bn:
        freeze_bn(model.mask_rcnn)
    if args.bn2affine:
        bn_to_affine(model.mask_rcnn)
    log_interval = 40, 'iteration'
    plot_interval = 160, 'iteration'
    print_interval = 40, 'iteration'

    #trainer.extend(extensions.Evaluator(test_iter, model, device=args.gpu), trigger=(args.validation, 'iteration'))
    #trainer.extend(DetectionCOCOEvaluator(test_iter, model.mask_rcnn), trigger=(args.validation, 'iteration')) #COCO AP Evaluator with VOC metric
    trainer.extend(COCOAPIEvaluator(test_iter, model.mask_rcnn, test_ids,
                                    cocoanns),
                   trigger=(args.validation, 'iteration'))  #COCO AP Evaluator
    trainer.extend(chainer.training.extensions.observe_lr(),
                   trigger=log_interval)
    trainer.extend(extensions.LogReport(trigger=log_interval))
    trainer.extend(extensions.PrintReport([
        'iteration',
        'epoch',
        'elapsed_time',
        'lr',
        'main/loss',
        'main/avg_loss',
        'main/roi_loc_loss',
        'main/roi_cls_loss',
        'main/roi_mask_loss',
        'main/rpn_loc_loss',
        'main/rpn_cls_loss',
        'validation/main/loss',
        'validation/main/map',
    ]),
                   trigger=print_interval)
    trainer.extend(extensions.ProgressBar(update_interval=1000))
    #trainer.extend(extensions.dump_graph('main/loss'))
    try:
        trainer.run()
    except:
        traceback.print_exc()
Example #14
0
def eval():
    """
    YOLOv3 evaler. See README for details.
    """
    args = parse_args()
    print("Setting Arguments.. : ", args)

    cuda = torch.cuda.is_available() and args.use_cuda

    if args.distributed:
        torch.cuda.set_device(args.local_rank)
        torch.distributed.init_process_group(backend="nccl", init_method="env://")


    # Parse config settings
    with open(args.cfg, 'r') as f:
        cfg = yaml.safe_load(f)

    print("successfully loaded config file: ", cfg)

    test_size = (args.test_size,args.test_size)

    if args.dataset == 'COCO':
        evaluator = COCOAPIEvaluator(
                    data_dir='data/COCO/',
                    img_size=test_size,
                    confthre=0.001,
                    nmsthre=0.65,
                    testset=args.testset,
                    vis=args.vis)

        num_class=80

    elif args.dataset == 'VOC':
        '''
        # COCO style evaluation, you have to convert xml annotation files into a json file.
        evaluator = COCOAPIEvaluator(
                    data_dir='data/VOC/',
                    img_size=test_size,
                    confthre=cfg['TEST']['CONFTHRE'],
                    nmsthre=cfg['TEST']['NMSTHRE'],
                    testset=args.testset,
                    voc = True)
        '''
        evaluator = VOCEvaluator(
                    data_dir='data/VOC/',
                    img_size=test_size,
                    confthre=0.001,
                    nmsthre=0.65,
                    vis=args.vis)
        num_class=20
    # Initiate model
    if args.asff:
        from models.yolov3_asff import YOLOv3
        print('Testing YOLOv3 with ASFF!')
        model = YOLOv3(num_classes = num_class, rfb=args.rfb, vis=args.vis)
    else:
        from models.yolov3_baseline import YOLOv3
        print('Testing YOLOv3 strong baseline!')
        if args.vis:
            print('Visualization is not supported for YOLOv3 baseline model')
            args.vis = False
        model = YOLOv3(num_classes = num_class, rfb=args.rfb)


    save_to_disk = (not args.distributed) or distributed_util.get_rank() == 0

    if args.checkpoint:
        print("loading pytorch ckpt...", args.checkpoint)
        cpu_device = torch.device("cpu")
        ckpt = torch.load(args.checkpoint, map_location=cpu_device)
        model.load_state_dict(ckpt,strict=False)
    if cuda:
        print("using cuda")
        torch.backends.cudnn.benchmark = True
        device = torch.device("cuda")
        model = model.to(device)

    if args.half:
        model = model.half()

    if args.ngpu > 1:
        if args.distributed:
            model = apex.parallel.DistributedDataParallel(model, delay_allreduce=True)
            #model = apex.parallel.DistributedDataParallel(model)
        else:
            model = nn.DataParallel(model) 

    dtype = torch.float16 if args.half else torch.float32

    if args.distributed:
        distributed_util.synchronize()

    ap50_95, ap50 = evaluator.evaluate(model, args.half, args.distributed)

    if args.distributed:
        distributed_util.synchronize()
    sys.exit(0) 
Example #15
0
def main():
    """
    YOLOv3 trainer. See README for details.
    """
    date = time.strftime('%Y-%m-%d-%H-%M', time.localtime())
    args = parse_args()
    print("Setting Arguments.. : ", args)
    cuda = torch.cuda.is_available() and args.use_cuda

    # Parse config settings
    with open(args.cfg, 'r') as f:
        cfg = yaml.load(f)

    print("successfully loaded config file: ", cfg)

    lr = cfg['TRAIN']['LR']
    momentum = cfg['TRAIN']['MOMENTUM']
    decay = cfg['TRAIN']['DECAY']
    burn_in = cfg['TRAIN']['BURN_IN']
    iter_size = cfg['TRAIN']['MAXITER']
    steps = eval(cfg['TRAIN']['STEPS'])
    batch_size = cfg['TRAIN']['BATCHSIZE']
    subdivision = cfg['TRAIN']['SUBDIVISION']
    ignore_thre = cfg['TRAIN']['IGNORETHRE']
    random_resize = cfg['AUGMENTATION']['RANDRESIZE']

    print('effective_batch_size = batch_size * iter_size = %d * %d' %
          (batch_size, subdivision))

    # Learning rate setup
    base_lr = lr

    # Initiate model
    model = YOLOv3(cfg['MODEL'], ignore_thre=ignore_thre)
    if args.pretrained:
        if cfg['MODEL']['TYPE'] == 'YOLOv3':
            # self.module_list = create_yolov3_modules(config_model, ignore_thre)
            print('load yolov3 pretrained model')
            model.load_pretrained_weights('weights/darknet53.conv.74', cutoff=75)
        elif cfg['MODEL']['TYPE'].lower() == 'yolov3-tiny':
            print('load yolov3 pretrained model')
            model.load_pretrained_weights('weights/yolov3-tiny.conv.15', cutoff=16)
        else:
            print('no this type pretrained model')

    if args.weights_path:
        print("loading darknet weights....", args.weights_path)
        #parse_yolo_weights(model, args.weights_path)
        model.load_weights(args.weights_path)
    elif args.checkpoint:
        print("loading pytorch ckpt...", args.checkpoint)
        state = torch.load(args.checkpoint)
        if 'model_state_dict' in state.keys():
            model.load_state_dict(state['model_state_dict'])
        else:
            model.load_state_dict(state)

    if cuda:
        print("using cuda") 
        model = model.cuda()
    #model.save_weights('../darknet/torch-yolo-tiny.weights')
    if args.tfboard:
        print("using tfboard")
        from tensorboardX import SummaryWriter
        tblogger = SummaryWriter(args.tfboard)
    #model = torch.nn.DataParallel(model)

    model.train()

    imgsize = cfg['TRAIN']['IMGSIZE']
    dataset = COCODataset(model_type=cfg['MODEL']['TYPE'],
                  data_dir='COCO/',
                  img_size=imgsize,
                  augmentation=cfg['AUGMENTATION'],
                  debug=args.debug)

    dataloader = torch.utils.data.DataLoader(
        dataset, batch_size=batch_size, shuffle=True, num_workers=args.n_cpu)
    dataiterator = iter(dataloader)

    evaluator = COCOAPIEvaluator(model_type=cfg['MODEL']['TYPE'],
                    data_dir='COCO/',
                    img_size=cfg['TEST']['IMGSIZE'],
                    confthre=cfg['TEST']['CONFTHRE'],
                    nmsthre=cfg['TEST']['NMSTHRE'])

    dtype = torch.cuda.FloatTensor if cuda else torch.FloatTensor

    # optimizer setup
    # set weight decay only on conv.weight
    params_dict = dict(model.named_parameters())
    params = []
    for key, value in params_dict.items():
        if 'conv.weight' in key:
            params += [{'params':value, 'weight_decay':decay * batch_size * subdivision}]
        else:
            params += [{'params':value, 'weight_decay':0.0}]
    optimizer = optim.SGD(params, lr=base_lr, momentum=momentum,
                          dampening=0, weight_decay=decay * batch_size * subdivision)

    iter_state = 0

    if args.checkpoint:
        if 'optimizer_state_dict' in state.keys():
            optimizer.load_state_dict(state['optimizer_state_dict'])
            iter_state = state['iter'] + 1

    # TODO: replace the following scheduler with the PyTorch's official one

    tmp_lr = base_lr

    def set_lr(tmp_lr):
        #print('set lr:', tmp_lr / batch_size / subdivision)
        for param_group in optimizer.param_groups:
            param_group['lr'] = tmp_lr / batch_size / subdivision
            #param_group['lr'] = tmp_lr / subdivision

    # start training loop
    for iter_i in range(iter_state, iter_size + 1):
        # COCO evaluation
        if iter_i % args.eval_interval == 0 and iter_i > 0:
            ap50_95, ap50 = evaluator.evaluate(model)
            model.train()
            if args.tfboard:
                tblogger.add_scalar('val/COCOAP50', ap50, iter_i)
                tblogger.add_scalar('val/COCOAP50_95', ap50_95, iter_i)

        # learning rate scheduling
        if iter_i < burn_in:
            tmp_lr = base_lr * pow(iter_i / burn_in, 4)
            set_lr(tmp_lr)
        elif iter_i == burn_in:
            tmp_lr = base_lr
            set_lr(tmp_lr)
        elif iter_i in steps:
            tmp_lr = tmp_lr * 0.1
            set_lr(tmp_lr)

        # subdivision loop
        optimizer.zero_grad()
        for inner_iter_i in range(subdivision):
            try:
                imgs, targets, _, _ = next(dataiterator)  # load a batch
            except StopIteration:
                dataiterator = iter(dataloader)
                imgs, targets, _, _ = next(dataiterator)  # load a batch
            imgs = Variable(imgs.type(dtype))
            targets = Variable(targets.type(dtype), requires_grad=False)
            loss = model(imgs, targets)
            loss.backward()

        optimizer.step()

        if iter_i % 10 == 0:
            # logging
            total_loss = model.loss_dict['xy'] + model.loss_dict['wh'] + model.loss_dict['conf'] + model.loss_dict['cls']
            print('[Iter %d/%d] [lr %f] '
                  '[Losses: xy %f, wh %f, conf %f, cls %f, l2 %f, total %f, imgsize %d]'
                  % (iter_i, iter_size, tmp_lr,
                     model.loss_dict['xy'], model.loss_dict['wh'],
                     model.loss_dict['conf'], model.loss_dict['cls'], 
                     model.loss_dict['l2'], total_loss , imgsize),
                  flush=True)

            if args.tfboard:
                tblogger.add_scalar('train/total_loss', model.loss_dict['l2'], iter_i)

            # random resizing
            if random_resize:
                imgsize = (random.randint(0, 9) % 10 + 10) * 32
                dataset.img_shape = (imgsize, imgsize)
                dataset.img_size = imgsize
                dataloader = torch.utils.data.DataLoader(
                    dataset, batch_size=batch_size, shuffle=True, num_workers=args.n_cpu)
                dataiterator = iter(dataloader)

        # save checkpoint
        if iter_i > 0 and (iter_i % args.checkpoint_interval == 0):
            try:
                args.checkpoint_dir = os.path.join(args.checkpoint_dir, args.snap_name + '_' + date)
                #print(args.checkpoint_dir)
                os.makedirs(args.checkpoint_dir, exist_ok=True)
                time.sleep(5)
                torch.save({'iter': iter_i,
                            'model_state_dict': model.state_dict(),
                            'optimizer_state_dict': optimizer.state_dict(),
                            },
                            os.path.join(args.checkpoint_dir, "snapshot"+str(iter_i)+".pth"))
                time.sleep(5)
                model.save_weights(os.path.join(args.checkpoint_dir, "snapshot"+str(iter_i)+".weights"))
                time.sleep(5)
            except Exception as e:
                print(e)

    if args.tfboard:
        tblogger.close()
def train(net, device):
    global cfg, hr
    # set GPU

    use_focal = False
    if args.use_focal:
        print("Let's use focal loss for objectness !!!")
        use_focal = True

    if args.multi_scale:
        print('Let us use the multi-scale trick.')
        ms_inds = range(len(cfg['multi_scale']))
        dataset = COCODataset(
                    data_dir=data_dir,
                    img_size=608,
                    transform=SSDAugmentation([608, 608], mean=(0.406, 0.456, 0.485), std=(0.225, 0.224, 0.229)),
                    debug=args.debug)
    else:
        dataset = COCODataset(
                    data_dir=data_dir,
                    img_size=cfg['min_dim'][0],
                    transform=SSDAugmentation(cfg['min_dim'], mean=(0.406, 0.456, 0.485), std=(0.225, 0.224, 0.229)),
                    debug=args.debug)
    
    print("Setting Arguments.. : ", args)
    print("----------------------------------------------------------")
    print('Loading the MSCOCO dataset...')
    print('Training model on:', dataset.name)
    print('The dataset size:', len(dataset))
    print('The obj weight : ', args.obj)
    print('The noobj weight : ', args.noobj)
    print("----------------------------------------------------------")

    input_size = cfg['min_dim']
    num_classes = args.num_classes
    batch_size = args.batch_size

    os.makedirs(args.save_folder + args.version, exist_ok=True)

    # using tfboard
    from tensorboardX import SummaryWriter
    c_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
    log_path = 'log/coco/' + c_time
    os.makedirs(log_path, exist_ok=True)

    writer = SummaryWriter(log_path)

    if args.high_resolution == 1:
        hr = True

    print('Let us train yolo-v2 on the MSCOCO dataset ......')
    
    model = net
    model.to(device).train()

    dataloader = torch.utils.data.DataLoader(
                    dataset, 
                    batch_size=batch_size, 
                    shuffle=True, 
                    collate_fn=detection_collate,
                    num_workers=args.n_cpu)

    evaluator = COCOAPIEvaluator(
                    data_dir=data_dir,
                    img_size=cfg['min_dim'],
                    device=device,
                    transform=BaseTransform(cfg['min_dim'], MEANS)
                    )

    # optimizer setup
    lr = args.lr
    # optimizer = optim.SGD(net.parameters(), lr=args.lr, momentum=args.momentum,
    #                                         weight_decay=args.weight_decay)
    # optimizer = optim.Adam(model.parameters())
    optimizer = optim.RMSprop(model.parameters(), lr=args.lr)

    step_index = 0
    epoch_size = len(dataset) // args.batch_size
    # each part of loss weight
    obj_w = 1.0
    cla_w = 1.0
    box_w = 1.0

    # start training loop
    iteration = 0
    t0 = time.time()

    for epoch in range(cfg['max_epoch']):
        batch_iterator = iter(dataloader)

        # use cos lr
        if args.cos and epoch > 20 and epoch <= cfg['max_epoch'] - 20:
            # use cos lr
            lr = cos_lr(optimizer, epoch, cfg['max_epoch'])
        elif args.cos and epoch > cfg['max_epoch'] - 20:
            lr = 0.00001  
            for param_group in optimizer.param_groups:
                param_group['lr'] = lr
        # use step lr
        else:
            if epoch in cfg['lr_epoch']:
                step_index += 1
                lr = adjust_learning_rate(optimizer, args.gamma, step_index)
    
        # COCO evaluation
        if (epoch + 1) % args.eval_epoch == 0:
            model.trainable = False
            ap50_95, ap50 = evaluator.evaluate(model)
            print('ap50 : ', ap50)
            print('ap50_95 : ', ap50_95)
            model.trainable = True
            model.train()
            writer.add_scalar('val/COCOAP50', ap50, epoch + 1)
            writer.add_scalar('val/COCOAP50_95', ap50_95, epoch + 1)

        # subdivision loop
        for images, targets in batch_iterator:
            # WarmUp strategy for learning rate
            if not args.no_warm_up == 'yes':
                if epoch < args.wp_epoch:
                    lr = warmup_strategy(optimizer, epoch_size, iteration)

            iteration += 1
        
            # multi-scale trick
            if iteration % 10 == 0 and args.multi_scale:
                ms_ind = random.sample(ms_inds, 1)[0]
                input_size = cfg['multi_scale'][int(ms_ind)]
            
            # multi scale
            if args.multi_scale:
                images = torch.nn.functional.interpolate(images, size=input_size, mode='bilinear', align_corners=True)

            targets = [label.tolist() for label in targets]
            if args.version == 'yolo_v2' or args.version == 'tiny_yolo_v2':
                targets = tools.gt_creator(input_size, yolo_net.stride, targets, name='COCO')
            elif args.version == 'yolo_v3' or args.version == 'tiny_yolo_v3':
                targets = tools.multi_gt_creator(input_size, yolo_net.stride, targets, name='COCO')

            targets = torch.tensor(targets).float().to(device)

            out = model(images.to(device))

            optimizer.zero_grad()

            obj_loss, class_loss, box_loss = tools.loss(out, targets, num_classes=args.num_classes, 
                                                        use_focal=use_focal,
                                                        obj=args.obj,
                                                        noobj=args.noobj)
            total_loss = obj_w * obj_loss + cla_w * class_loss + box_w * box_loss

            # viz loss
            writer.add_scalar('object loss', obj_loss.item(), iteration)
            writer.add_scalar('class loss', class_loss.item(), iteration)
            writer.add_scalar('local loss', box_loss.item(), iteration)
            writer.add_scalar('total loss', total_loss.item(), iteration)
            # backprop
            total_loss.backward()        
            optimizer.step()

            if iteration % 10 == 0:
                t1 = time.time()
                print('[Epoch %d/%d][Iter %d][lr %.8f]'
                    '[Loss: obj %.2f || cls %.2f || bbox %.2f || total %.2f || imgsize %d || time: %.2f]'
                        % (epoch+1, cfg['max_epoch'], iteration, lr,
                            obj_loss.item(), class_loss.item(), box_loss.item(), total_loss.item(), input_size[0], t1-t0),
                        flush=True)

                t0 = time.time()


        if (epoch + 1) % 10 == 0:
            print('Saving state, epoch:', epoch + 1)
            torch.save(yolo_net.state_dict(), os.path.join(args.save_folder + args.version, 
                        args.version + '_' + repr(epoch + 1) + '.pth')
                        )  
Example #17
0
def train():
    args = parse_args()
    data_dir = args.dataset_root

    path_to_save = os.path.join(args.save_folder, args.version)
    os.makedirs(path_to_save, exist_ok=True)

    hr = False
    if args.high_resolution:
        print('use hi-res backbone')
        hr = True

    cfg = coco_ab

    if args.cuda:
        print('use cuda')
        cudnn.benchmark = True
        device = torch.device("cuda")
    else:
        device = torch.device("cpu")

    if args.multi_scale:
        print('Let us use the multi-scale trick.')
        input_size = [608, 608]
        dataset = COCODataset(data_dir=data_dir,
                              img_size=608,
                              transform=SSDAugmentation([608, 608],
                                                        mean=(0.406, 0.456,
                                                              0.485),
                                                        std=(0.225, 0.224,
                                                             0.229)),
                              debug=args.debug)
    else:
        input_size = cfg['min_dim']
        dataset = COCODataset(data_dir=data_dir,
                              img_size=cfg['min_dim'][0],
                              transform=SSDAugmentation(cfg['min_dim'],
                                                        mean=(0.406, 0.456,
                                                              0.485),
                                                        std=(0.225, 0.224,
                                                             0.229)),
                              debug=args.debug)

    # build model
    if args.version == 'yolo_v2':
        from models.yolo_v2 import myYOLOv2
        total_anchor_size = tools.get_total_anchor_size(name='COCO')

        yolo_net = myYOLOv2(device,
                            input_size=input_size,
                            num_classes=args.num_classes,
                            trainable=True,
                            anchor_size=total_anchor_size,
                            hr=hr)
        print('Let us train yolo-v2 on the COCO dataset ......')

    elif args.version == 'yolo_v3':
        from models.yolo_v3 import myYOLOv3
        total_anchor_size = tools.get_total_anchor_size(multi_level=True,
                                                        name='COCO',
                                                        version='yolo_v3')

        yolo_net = myYOLOv3(device,
                            input_size=input_size,
                            num_classes=args.num_classes,
                            trainable=True,
                            anchor_size=total_anchor_size,
                            hr=hr)
        print('Let us train yolo-v3 on the COCO dataset ......')

    elif args.version == 'slim_yolo_v2':
        from models.slim_yolo_v2 import SlimYOLOv2
        total_anchor_size = tools.get_total_anchor_size(name='COCO')

        yolo_net = SlimYOLOv2(device,
                              input_size=input_size,
                              num_classes=args.num_classes,
                              trainable=True,
                              anchor_size=total_anchor_size,
                              hr=hr)
        print('Let us train slim-yolo-v2 on the COCO dataset ......')

    elif args.version == 'tiny_yolo_v3':
        from models.tiny_yolo_v3 import YOLOv3tiny
        total_anchor_size = tools.get_total_anchor_size(multi_level=True,
                                                        name='COCO',
                                                        version='tiny_yolo_v3')

        yolo_net = YOLOv3tiny(device,
                              input_size=input_size,
                              num_classes=args.num_classes,
                              trainable=True,
                              anchor_size=total_anchor_size,
                              hr=hr)
        print('Let us train tiny-yolo-v3 on the COCO dataset ......')

    else:
        print('Unknown version !!!')
        exit()

    print("Setting Arguments.. : ", args)
    print("----------------------------------------------------------")
    print('Loading the MSCOCO dataset...')
    print('Training model on:', dataset.name)
    print('The dataset size:', len(dataset))
    print("----------------------------------------------------------")

    # use tfboard
    if args.tfboard:
        print('use tensorboard')
        from torch.utils.tensorboard import SummaryWriter
        c_time = time.strftime('%Y-%m-%d %H:%M:%S',
                               time.localtime(time.time()))
        log_path = os.path.join('log/coco/', args.version, c_time)
        os.makedirs(log_path, exist_ok=True)

        writer = SummaryWriter(log_path)

    model = yolo_net

    # keep training
    if args.resume is not None:
        print('keep training model: %s' % (args.resume))
        model.load_state_dict(torch.load(args.resume, map_location=device))

    model.to(device).train()

    dataloader = torch.utils.data.DataLoader(dataset,
                                             batch_size=args.batch_size,
                                             shuffle=True,
                                             collate_fn=detection_collate,
                                             num_workers=args.num_workers)

    evaluator = COCOAPIEvaluator(data_dir=data_dir,
                                 img_size=cfg['min_dim'],
                                 device=device,
                                 transform=BaseTransform(cfg['min_dim'],
                                                         mean=(0.406, 0.456,
                                                               0.485),
                                                         std=(0.225, 0.224,
                                                              0.229)))

    # optimizer setup
    base_lr = args.lr
    tmp_lr = base_lr
    optimizer = optim.SGD(model.parameters(),
                          lr=args.lr,
                          momentum=args.momentum,
                          weight_decay=args.weight_decay)

    max_epoch = cfg['max_epoch']
    epoch_size = len(dataset) // args.batch_size

    # start training loop
    t0 = time.time()

    for epoch in range(args.start_epoch, max_epoch):

        # use cos lr
        if args.cos and epoch > 20 and epoch <= max_epoch - 20:
            # use cos lr
            tmp_lr = 0.00001 + 0.5 * (base_lr - 0.00001) * (
                1 + math.cos(math.pi * (epoch - 20) * 1. / (max_epoch - 20)))
            set_lr(optimizer, tmp_lr)

        elif args.cos and epoch > max_epoch - 20:
            tmp_lr = 0.00001
            set_lr(optimizer, tmp_lr)

        # use step lr
        else:
            if epoch in cfg['lr_epoch']:
                tmp_lr = tmp_lr * 0.1
                set_lr(optimizer, tmp_lr)

        for iter_i, (images, targets) in enumerate(dataloader):
            # WarmUp strategy for learning rate
            if not args.no_warm_up:
                if epoch < args.wp_epoch:
                    tmp_lr = base_lr * pow((iter_i + epoch * epoch_size) * 1. /
                                           (args.wp_epoch * epoch_size), 4)
                    # tmp_lr = 1e-6 + (base_lr-1e-6) * (iter_i+epoch*epoch_size) / (epoch_size * (args.wp_epoch))
                    set_lr(optimizer, tmp_lr)

                elif epoch == args.wp_epoch and iter_i == 0:
                    tmp_lr = base_lr
                    set_lr(optimizer, tmp_lr)

            targets = [label.tolist() for label in targets]
            if args.version == 'yolo_v2' or args.version == 'slim_yolo_v2':
                targets = tools.gt_creator(input_size,
                                           yolo_net.stride,
                                           targets,
                                           name='COCO',
                                           version=args.version)
            elif args.version == 'yolo_v3' or args.version == 'tiny_yolo_v3':
                targets = tools.multi_gt_creator(input_size,
                                                 yolo_net.stride,
                                                 targets,
                                                 name='COCO',
                                                 version=args.version)

            # to device
            images = images.to(device)
            targets = torch.tensor(targets).float().to(device)

            # forward and loss
            conf_loss, cls_loss, txtytwth_loss, total_loss = model(
                images, target=targets)

            # backprop
            total_loss.backward()
            optimizer.step()
            optimizer.zero_grad()

            if iter_i % 10 == 0:
                if args.tfboard:
                    # viz loss
                    writer.add_scalar('object loss', conf_loss.item(),
                                      iter_i + epoch * epoch_size)
                    writer.add_scalar('class loss', cls_loss.item(),
                                      iter_i + epoch * epoch_size)
                    writer.add_scalar('local loss', txtytwth_loss.item(),
                                      iter_i + epoch * epoch_size)

                t1 = time.time()
                print(
                    '[Epoch %d/%d][Iter %d/%d][lr %.6f]'
                    '[Loss: obj %.2f || cls %.2f || bbox %.2f || total %.2f || size %d || time: %.2f]'
                    % (epoch + 1, max_epoch, iter_i, epoch_size, tmp_lr,
                       conf_loss.item(), cls_loss.item(), txtytwth_loss.item(),
                       total_loss.item(), input_size[0], t1 - t0),
                    flush=True)

                t0 = time.time()

            # multi-scale trick
            if iter_i % 10 == 0 and iter_i > 0 and args.multi_scale:
                if epoch >= max_epoch - 10:
                    size = 608
                else:
                    size = random.randint(10, 19) * 32
                input_size = [size, size]
                model.set_grid(input_size)

                # change input dim
                # But this operation will report bugs when we use more workers in data loader, so I have to use 0 workers.
                # I don't know how to make it suit more workers, and I'm trying to solve this question.
                dataloader.dataset.reset_transform(
                    SSDAugmentation(input_size,
                                    mean=(0.406, 0.456, 0.485),
                                    std=(0.225, 0.224, 0.229)))

        # COCO evaluation
        if (epoch + 1) % args.eval_epoch == 0:
            model.trainable = False
            model.set_grid(cfg['min_dim'])
            # evaluate
            ap50_95, ap50 = evaluator.evaluate(model)
            print('ap50 : ', ap50)
            print('ap50_95 : ', ap50_95)
            # convert to training mode.
            model.trainable = True
            model.set_grid(input_size)
            model.train()
            if args.tfboard:
                writer.add_scalar('val/COCOAP50', ap50, epoch + 1)
                writer.add_scalar('val/COCOAP50_95', ap50_95, epoch + 1)

        if (epoch + 1) % 10 == 0:
            print('Saving state, epoch:', epoch + 1)
            torch.save(
                model.state_dict(),
                os.path.join(path_to_save,
                             args.version + '_' + repr(epoch + 1) + '.pth'))
def main():
    """
    YOLOv3 trainer. See README for details.
    """
    args = parse_args()
    print("Setting Arguments.. : ", args)

    if torch.cuda.is_available() and args.gpu >= 0:
        device = torch.device('cuda:{}'.format(args.gpu))
    else:
        device = torch.device('cpu')

    os.makedirs(args.checkpoint_dir, exist_ok=True)

    # Use `file_name` key to load images when train YOLO with VisDrone data
    print("------------------------------------")
    print("  use {} dataset for training.      ".format(args.data))
    print("------------------------------------")

    assert args.data in ['coco', 'drone']
    if args.data == 'coco':
        data_dir = './COCO'
        cfg_path = 'config/yolov3_default.cfg'
        use_filename_key = False
    if args.data == 'drone':
        data_dir = './VisDrone'
        cfg_path = 'config/yolov3_visdrone_default.cfg'
        use_filename_key = True

    # Parse config settings
    with open(cfg_path, 'r') as f:
        cfg = yaml.load(f)

    print("successfully loaded config file: ", cfg)

    lr = cfg['TRAIN']['LR']
    momentum = cfg['TRAIN']['MOMENTUM']
    decay = cfg['TRAIN']['DECAY']
    burn_in = cfg['TRAIN']['BURN_IN']
    iter_size = cfg['TRAIN']['MAXITER']
    steps = eval(cfg['TRAIN']['STEPS'])
    batch_size = cfg['TRAIN']['BATCHSIZE']
    subdivision = cfg['TRAIN']['SUBDIVISION']
    ignore_thre = cfg['TRAIN']['IGNORETHRE']
    random_resize = cfg['TRAIN']['RANDRESIZE']

    print('effective_batch_size = batch_size * iter_size = %d * %d' %
          (batch_size, subdivision))

    # Load data
    print("loading dataset...")
    imgsize = cfg['TRAIN']['IMGSIZE']
    dataset = COCODataset(model_type=cfg['MODEL']['TYPE'],
                          data_dir=data_dir,
                          img_size=imgsize,
                          min_size=cfg['TRAIN']['MINSIZE'],
                          max_labels=cfg['TRAIN']['MAXOBJECTS'],
                          use_filename_key=use_filename_key,
                          debug=args.debug)

    dataloader = torch.utils.data.DataLoader(dataset,
                                             batch_size=batch_size,
                                             shuffle=True,
                                             num_workers=args.n_cpu)
    dataiterator = iter(dataloader)

    evaluator = COCOAPIEvaluator(model_type=cfg['MODEL']['TYPE'],
                                 data_dir=data_dir,
                                 img_size=cfg['TEST']['IMGSIZE'],
                                 confthre=cfg['TEST']['CONFTHRE'],
                                 nmsthre=cfg['TEST']['NMSTHRE'],
                                 min_size=cfg['TEST']['MINSIZE'],
                                 max_labels=cfg['TEST']['MAXOBJECTS'],
                                 use_filename_key=use_filename_key)

    # Learning rate setup
    base_lr = lr

    # Initiate model
    n_classes = len(dataset.class_ids)
    model = YOLOv3(n_classes=n_classes, ignore_thre=ignore_thre)

    if args.weights_path:
        print("loading darknet weights....", args.weights_path)
        parse_yolo_weights(model, args.weights_path)
    elif args.checkpoint:
        print("loading pytorch ckpt...", args.checkpoint)
        model.load_state_dict(torch.load(args.checkpoint))

    print("sending model to device...")
    model = model.to(device)

    if args.tboard:
        print("using tboard")
        from tensorboardX import SummaryWriter
        tblogger = SummaryWriter(os.path.join('logs', args.tboard))

    model.train()

    # optimizer setup
    # set weight decay only on conv.weight
    params_dict = dict(model.named_parameters())
    params = []
    for key, value in params_dict.items():
        if 'conv.weight' in key:
            params += [{
                'params': value,
                'weight_decay': decay * batch_size * subdivision
            }]
        else:
            params += [{'params': value, 'weight_decay': 0.0}]
    optimizer = optim.SGD(params,
                          lr=base_lr,
                          momentum=momentum,
                          dampening=0,
                          weight_decay=decay * batch_size * subdivision)

    tmp_lr = base_lr

    def set_lr(tmp_lr):
        for param_group in optimizer.param_groups:
            param_group['lr'] = tmp_lr / batch_size / subdivision

    # start training loop
    eval_interval = cfg['TRAIN']['ITER_EVAL']
    checkpoint_interval = cfg['TRAIN']['ITER_CKPT']

    # random resizing..
    imgsize_max = imgsize
    imgsize_res = 32
    r_max = int(math.floor(imgsize_max / imgsize_res))
    r_min = int(math.ceil(imgsize_max / imgsize_res / 2.0))

    for iter_i in range(iter_size):

        # COCO evaluation
        if iter_i % eval_interval == 0 and iter_i > 0:
            ap50_95, ap50 = evaluator.evaluate(model)
            model.train()
            if args.tboard:
                tblogger.add_scalar('val/AP50', ap50, iter_i)
                tblogger.add_scalar('val/AP50_95', ap50_95, iter_i)

        # learning rate scheduling
        if iter_i < burn_in:
            tmp_lr = base_lr * pow(iter_i / burn_in, 4)
            set_lr(tmp_lr)
        elif iter_i == burn_in:
            tmp_lr = base_lr
            set_lr(tmp_lr)
        elif iter_i in steps:
            tmp_lr = tmp_lr * 0.1
            set_lr(tmp_lr)

        # subdivision loop
        optimizer.zero_grad()
        for inner_iter_i in range(subdivision):
            try:
                imgs, targets, _, _ = next(dataiterator)  # load a batch
            except StopIteration:
                dataiterator = iter(dataloader)
                imgs, targets, _, _ = next(dataiterator)  # load a batch
            imgs = Variable(imgs.to(device, dtype=torch.float32))
            targets = Variable(targets.to(device, dtype=torch.float32),
                               requires_grad=False)
            loss = model(imgs, targets)
            loss.backward()

        optimizer.step()

        if iter_i % 10 == 0:
            # logging
            print(
                '[Iter %d/%d] [lr %f] '
                '[Losses: xy %f, wh %f, conf %f, cls %f, total %f, imgsize %d]'
                % (iter_i, iter_size, tmp_lr, model.loss_dict['xy'],
                   model.loss_dict['wh'], model.loss_dict['conf'],
                   model.loss_dict['cls'], model.loss_dict['l2'], imgsize),
                flush=True)

            if args.tboard:
                tblogger.add_scalar('train/total_loss', model.loss_dict['l2'],
                                    iter_i)

            # random resizing
            if random_resize:
                imgsize = random.randint(r_min, r_max) * imgsize_res
                dataset.img_shape = (imgsize, imgsize)
                dataset.img_size = imgsize
                dataloader = torch.utils.data.DataLoader(
                    dataset,
                    batch_size=batch_size,
                    shuffle=True,
                    num_workers=args.n_cpu)
                dataiterator = iter(dataiterator)

        # save checkpoint
        if iter_i > 0 and (iter_i % checkpoint_interval == 0):
            torch.save(
                model.state_dict(),
                os.path.join(args.checkpoint_dir,
                             "snapshot_{}.ckpt".format(iter_i)))
    if args.tboard:
        tblogger.close()
Example #19
0
def main():
    """
    YOLOv3 trainer. See README for details.
    """
    args = parse_args()
    print("Setting Arguments.. : ", args)

    cuda = torch.cuda.is_available() and args.use_cuda
    os.makedirs(args.checkpoint_dir, exist_ok=True)

    # Parse config settings
    with open(args.cfg, 'r') as f:
        cfg = yaml.load(f)

    print("successfully loaded config file: ", cfg)

    momentum = cfg['TRAIN']['MOMENTUM']
    decay = cfg['TRAIN']['DECAY']
    burn_in = cfg['TRAIN']['BURN_IN']
    iter_size = cfg['TRAIN']['MAXITER']
    steps = eval(cfg['TRAIN']['STEPS'])
    batch_size = cfg['TRAIN']['BATCHSIZE']
    subdivision = cfg['TRAIN']['SUBDIVISION']
    ignore_thre = cfg['TRAIN']['IGNORETHRE']
    random_resize = cfg['AUGMENTATION']['RANDRESIZE']
    base_lr = cfg['TRAIN']['LR'] / batch_size / subdivision
    datatype = cfg['TRAIN']['DATATYPE']
    print('effective_batch_size = batch_size * iter_size = %d * %d' %
          (batch_size, subdivision))

    # Learning rate setup
    def burnin_schedule(i):
        if i < burn_in:
            factor = pow(i / burn_in, 4)
        elif i < steps[0]:
            factor = 1.0
        elif i < steps[1]:
            factor = 0.1
        else:
            factor = 0.01
        return factor

    # Initiate model
    model = YOLOv3(cfg['MODEL'], ignore_thre=ignore_thre)

    if args.weights_path:
        print("loading darknet weights....", args.weights_path)
        parse_yolo_weights(model, args.weights_path)
    elif args.checkpoint:
        print("loading pytorch ckpt...", args.checkpoint)
        state = torch.load(args.checkpoint)
        if 'model_state_dict' in state.keys():
            model.load_state_dict(state['model_state_dict'])
        else:
            model.load_state_dict(state)

    if cuda:
        print("using cuda")
        model = model.cuda()

    if args.tfboard:
        print("using tfboard")
        from tensorboardX import SummaryWriter
        tblogger = SummaryWriter(args.tfboard)

    model.train()
    coco_class_names, coco_class_ids, coco_class_colors = get_coco_label_names()
    imgsize = cfg['TRAIN']['IMGSIZE']
    if datatype=='voc':
        dataset = VOCDataset(model_type=cfg['MODEL']['TYPE'],
                              data_dir='../../VOCdevkit/VOC2007',
                              img_size=imgsize,
                              augmentation=cfg['AUGMENTATION'],
                              debug=args.debug)
        print('load voc dataset successfully')
    else:
        dataset = COCODataset(model_type=cfg['MODEL']['TYPE'],
                      data_dir='COCO/',
                      img_size=imgsize,
                      augmentation=cfg['AUGMENTATION'],
                      debug=args.debug)
        print('load COCO dataset successfully')

        evaluator = COCOAPIEvaluator(model_type=cfg['MODEL']['TYPE'],
                                     data_dir='COCO/',
                                     img_size=cfg['TEST']['IMGSIZE'],
                                     confthre=cfg['TEST']['CONFTHRE'],
                                     nmsthre=cfg['TEST']['NMSTHRE'])

    dataloader = torch.utils.data.DataLoader(
        dataset, batch_size=batch_size, shuffle=True, num_workers=args.n_cpu)
    dataiterator = iter(dataloader)


    dtype = torch.cuda.FloatTensor if cuda else torch.FloatTensor

    # optimizer setup
    # set weight decay only on conv.weight
    params_dict = dict(model.named_parameters())
    params = []
    for key, value in params_dict.items():
        if 'conv.weight' in key:
            params += [{'params': value, 'weight_decay': decay
                        * batch_size * subdivision}]
        else:
            params += [{'params': value, 'weight_decay': 0.0}]
    optimizer = optim.SGD(params, lr=base_lr, momentum=momentum,
                          dampening=0, weight_decay=decay * batch_size * subdivision)

    iter_state = 0

    if args.checkpoint:
        if 'optimizer_state_dict' in state.keys():
            optimizer.load_state_dict(state['optimizer_state_dict'])
            iter_state = state['iter'] + 1
    #学习率控制 Sets the learning rate of each parameter group to the initial lr times a given function. When last_epoch=-1, sets initial lr as lr.
    scheduler = optim.lr_scheduler.LambdaLR(optimizer, burnin_schedule)

    # result=evals(model)
    # print(result)

    # start training loop
    # print('args.eval_interval',args.eval_interval)
    for iter_i in range(iter_state, iter_size + 1):
        if iter_i % (args.eval_interval*2) == 0 and iter_i > 0:
            if datatype=='voc':
                result=evals(model)
                print(result)
            else:
                ap50_95, ap50 = evaluator.evaluate(model)
                print(ap50_95, ap50)
                model.train()
                if args.tfboard:
                    tblogger.add_scalar('val/COCOAP50', ap50, iter_i)
                    tblogger.add_scalar('val/COCOAP50_95', ap50_95, iter_i)

        if iter_i % (40000) == 0 and iter_i > 0:
            draw(model,datatype,imgsize)
        # subdivision loop
        optimizer.zero_grad()
        for inner_iter_i in range(subdivision):
            try:
                imgs, targets, info_img, id_ = next(dataiterator)  # load a batch
            except StopIteration:
                dataiterator = iter(dataloader)
                imgs, targets, info_img, id_ = next(dataiterator)  # load a batch
            imgs = Variable(imgs.type(dtype))
            targets = Variable(targets.type(dtype), requires_grad=False)
            loss = model(imgs, targets)
            loss.backward()

        optimizer.step()
        scheduler.step()


        if iter_i % 10 == 0:
            # logging

            current_lr = scheduler.get_lr()[0] * batch_size * subdivision
            print('[Iter %d/%d] [lr %f] '
                  '[Losses: xy %f, wh %f, conf %f, cls %f, total %f, imgsize %d]'
                  % (iter_i, iter_size, current_lr,
                     model.loss_dict['xy'], model.loss_dict['wh'],
                     model.loss_dict['conf'], model.loss_dict['cls'],
                     model.loss_dict['l2'], imgsize))

            if args.tfboard:
                tblogger.add_scalar('train/total_loss',
                                    model.loss_dict['l2'], iter_i)

            # random resizing
            # 变输入大小,利用了yolov3网络的全卷积,使得模型不受图像大小的改变而影响参数。
            if random_resize:
                imgsize = (random.randint(0, 9) % 10 + 10) * 32
                dataset.img_shape = (imgsize, imgsize)
                dataset.img_size = imgsize
                dataloader = torch.utils.data.DataLoader(
                    dataset, batch_size=batch_size, shuffle=True, num_workers=args.n_cpu)
                dataiterator = iter(dataloader)

        if iter_i % 100 == 0:
            model.eval()
            if datatype=='voc':
                img_file = os.path.join('../../VOCdevkit/VOC2007', 'JPEGImages', id_[0] + '.jpg')
            else:
                img_file = os.path.join('COCO', 'train2017',
                                        '{:012}'.format(id_) + '.jpg')
            img = cv2.imread(img_file)
            img_raw = img.copy()[:, :, ::-1].transpose((2, 0, 1))
            # print(img_raw.shape)
            # print(img_raw)
            # print(imgs)
            img, info_img_t = preprocess(img, imgsize, jitter=0)  # info = (h, w, nh, nw, dx, dy)
            img = np.transpose(img / 255., (2, 0, 1))
            img = torch.from_numpy(img).float().unsqueeze(0)
            img = Variable(img.type(torch.cuda.FloatTensor))
            outputs = model(img)
            #outputs.shape : torch.Size([1, 12348, 85])
            outputs = postprocess(outputs, 80, 0.5, 0.5)
            # imgs.shape : torch.Size([1, 3, 608, 608])
            # outputs[0].shape :torch.Size([3, 7])
            # targets.shape :torch.Size([1, 50, 5])
            # print(outputs)
            if outputs[0] is not None:
                bboxes = list()
                classes = list()
                colors = list()
                # print(info_img_t)
                info_img=tuple(info_img)
                # print(info_img)
                for x1, y1, x2, y2, conf, cls_conf, cls_pred in outputs[0]:

                    cls_id = coco_class_ids[int(cls_pred)]
                    # print(int(x1), int(y1), int(x2), int(y2), float(conf), int(cls_pred))
                    # print('\t+ Label: %s, Conf: %.5f' %
                    #       (coco_class_names[cls_id], cls_conf.item()))
                    # print([y1, x1, y2, x2])
                    box = yolobox2label([y1, x1, y2, x2], info_img_t)
                    bboxes.append(box)
                    classes.append(cls_id)
                    colors.append(coco_class_colors[int(cls_pred)])
                vis_bbox(
                    img_raw, bboxes, label=classes, label_names=coco_class_names,
                    instance_colors=colors, linewidth=2)
                plt.savefig('output/'+str(iter_i)+'.jpg')
            model.train()

        # save checkpoint
        if iter_i > 0 and (iter_i % args.checkpoint_interval == 0):
            torch.save({'iter': iter_i,
                        'model_state_dict': model.state_dict(),
                        'optimizer_state_dict': optimizer.state_dict(),
                        },
                       os.path.join(args.checkpoint_dir, "snapshot" + str(iter_i) + ".ckpt"))
    if args.tfboard:
        tblogger.close()