def build_data_loader(): logger.info("build train dataset") # dataset dataset = init_dataset(cfg.TRAIN.DATASET, cfg.TRAIN.TXT) sampler = RandomIdentitySampler(dataset.train, cfg.TRAIN.NUM_IDENTITIES) train_loader = DataLoader(ImageData_train(dataset.train, TrainTransformer()), batch_size=cfg.TRAIN.BATCH_SIZE, num_workers=cfg.TRAIN.NUM_WORKERS, pin_memory=True, sampler=sampler) query_loader = DataLoader(ImageData_val(dataset.probe, TestTransformer()), batch_size=cfg.TRAIN.BATCH_SIZE, num_workers=cfg.TRAIN.NUM_WORKERS, pin_memory=True, shuffle=False) gallery_loader = DataLoader(ImageData_val(dataset.gallery, TestTransformer()), batch_size=cfg.TRAIN.BATCH_SIZE, num_workers=cfg.TRAIN.NUM_WORKERS, pin_memory=True, shuffle=False) return dataset, train_loader, query_loader, gallery_loader
def load_data(dataset, pin_memory): dataloader = {} if opt.loss == 'softmax': trainloader = DataLoader(ImageData(dataset.train, TrainTransform()), shuffle=True, batch_size=opt.train_batch, num_workers=8, pin_memory=pin_memory, drop_last=True) else: trainloader = DataLoader(ImageData(dataset.train, TrainTransform()), sampler=RandomIdentitySampler( dataset.train, opt.train_batch, opt.num_instances), batch_size=opt.train_batch, num_workers=8, pin_memory=pin_memory, drop_last=True) dataloader['train'] = trainloader queryloader = DataLoader(ImageData(dataset.query, TestTransform()), batch_size=opt.test_batch, num_workers=8, pin_memory=pin_memory) dataloader['query'] = queryloader galleryloader = DataLoader(ImageData(dataset.gallery, TestTransform()), batch_size=opt.test_batch, num_workers=8, pin_memory=pin_memory) dataloader['gallery'] = galleryloader queryFliploader = DataLoader(ImageData(dataset.query, TestTransform(True)), batch_size=opt.test_batch, num_workers=8, pin_memory=pin_memory) dataloader['queryFlip'] = queryFliploader galleryFliploader = DataLoader(ImageData(dataset.gallery, TestTransform(True)), batch_size=opt.test_batch, num_workers=8, pin_memory=pin_memory) dataloader['galleryFlip'] = galleryFliploader return dataloader
def train(**kwargs): opt._parse(kwargs) opt.model_name = 'bfe_test' # set random seed and cudnn benchmark torch.manual_seed(opt.seed) os.makedirs(opt.save_dir, exist_ok=True) use_gpu = torch.cuda.is_available() sys.stdout = Logger(osp.join(opt.save_dir, 'log_train.txt')) print('=========user config==========') pprint(opt._state_dict()) print('============end===============') if use_gpu: print('currently using GPU') cudnn.benchmark = True torch.cuda.manual_seed_all(opt.seed) else: print('currently using cpu') print('initializing dataset {}'.format(opt.dataset)) dataset = data_manager.init_dataset(name=opt.dataset, mode=opt.mode) pin_memory = True if use_gpu else False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) trainloader = DataLoader(ImageData(dataset.train, TrainTransform(opt.datatype)), sampler=RandomIdentitySampler( dataset.train, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True) queryloader = DataLoader(ImageData(dataset.query, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryloader = DataLoader(ImageData(dataset.gallery, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) queryFliploader = DataLoader(ImageData(dataset.query, TestTransform(opt.datatype, True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryFliploader = DataLoader(ImageData(dataset.gallery, TestTransform(opt.datatype, True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) print('initializing model ...') model = BFE(dataset.num_train_pids, 1.0, 0.33) optim_policy = model.get_optim_policy() if opt.pretrained_model: state_dict = torch.load(opt.pretrained_model)['state_dict'] # state_dict = {k: v for k, v in state_dict.items() \ # if not ('reduction' in k or 'softmax' in k)} model.load_state_dict(state_dict, False) print('load pretrained model ' + opt.pretrained_model) print('model size: {:.5f}M'.format( sum(p.numel() for p in model.parameters()) / 1e6)) if use_gpu: model = nn.DataParallel(model).cuda() reid_evaluator = ResNetEvaluator(model) if opt.evaluate: reid_evaluator.evaluate(queryloader, galleryloader, queryFliploader, galleryFliploader, re_ranking=opt.re_ranking, savefig=opt.savefig) return # xent_criterion = nn.CrossEntropyLoss() xent_criterion = CrossEntropyLabelSmooth(dataset.num_train_pids) if opt.loss == 'triplet': embedding_criterion = TripletLoss(opt.margin) elif opt.loss == 'lifted': embedding_criterion = LiftedStructureLoss(hard_mining=True) elif opt.loss == 'weight': embedding_criterion = Margin() def criterion(triplet_y, softmax_y, labels): losses = [embedding_criterion(output, labels)[0] for output in triplet_y] + \ [xent_criterion(output, labels) for output in softmax_y] loss = sum(losses) return loss # get optimizer if opt.optim == "sgd": optimizer = torch.optim.SGD(optim_policy, lr=opt.lr, momentum=0.9, weight_decay=opt.weight_decay) else: optimizer = torch.optim.Adam(optim_policy, lr=opt.lr, weight_decay=opt.weight_decay) start_epoch = opt.start_epoch # get trainer and evaluator reid_trainer = cls_tripletTrainer(opt, model, optimizer, criterion, summary_writer) def adjust_lr(optimizer, ep): if ep < 10: lr = opt.lr * 0.1 * (ep / 10.0) # warm_up elif ep < 50: lr = opt.lr * (ep // 5 + 1) elif ep < 200: lr = opt.lr * 10.0 elif ep < 300: lr = opt.lr else: lr = opt.lr * 0.1 for p in optimizer.param_groups: p['lr'] = lr # start training best_rank1 = opt.best_rank best_epoch = 0 for epoch in range(start_epoch, opt.max_epoch): if opt.adjust_lr: adjust_lr(optimizer, epoch + 1) reid_trainer.train(epoch, trainloader) # skip if not save model if opt.eval_step > 0 and (epoch + 1) % opt.eval_step == 0 or ( epoch + 1) == opt.max_epoch: if opt.mode == 'class': rank1 = test(model, queryloader) else: rank1 = reid_evaluator.evaluate(queryloader, galleryloader, queryFliploader, galleryFliploader) is_best = rank1 > best_rank1 if is_best: best_rank1 = rank1 best_epoch = epoch + 1 if use_gpu: state_dict = model.module.state_dict() else: state_dict = model.state_dict() save_checkpoint({ 'state_dict': state_dict, 'epoch': epoch + 1 }, is_best=is_best, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.pth.tar') print('Best rank-1 {:.1%}, achived at epoch {}'.format( best_rank1, best_epoch))
def train(**kwargs): opt._parse(kwargs) # set random seed and cudnn benchmark torch.manual_seed(opt.seed) os.makedirs(opt.save_dir, exist_ok=True) use_gpu = torch.cuda.is_available() sys.stdout = Logger(osp.join(opt.save_dir, 'log_train.txt')) print('=========user config==========') pprint(opt._state_dict()) print('============end===============') if use_gpu: print('currently using GPU') cudnn.benchmark = True torch.cuda.manual_seed_all(opt.seed) else: print('currently using cpu') print('initializing tx_chanllege dataset') dataset = Tx_dataset(file_list='train_list_new.txt').dataset query_dataset = Tx_dataset(set='train_set', file_list='val_query_list.txt').dataset gallery_dataset = Tx_dataset(set='train_set', file_list='val_gallery_list.txt').dataset train_set = ImageDataset(dataset, transform=build_transforms(opt, is_train=True)) pin_memory = True if use_gpu else False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) if opt.sampler_new: trainloader = DataLoader( train_set, sampler=RandomIdentitySampler_new(train_set, opt.train_batch, opt.num_instances), # sampler=RandomIdentitySampler(train_set, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True) else: trainloader = DataLoader( train_set, # sampler=RandomIdentitySampler_new(train_set, opt.train_batch, opt.num_instances), sampler=RandomIdentitySampler(train_set, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True) queryloader = DataLoader(ImageDataset(query_dataset, transform=build_transforms( opt, is_train=False)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryloader = DataLoader(ImageDataset(gallery_dataset, transform=build_transforms( opt, is_train=False)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) queryFliploader = DataLoader(ImageDataset(query_dataset, transform=build_transforms( opt, is_train=False, flip=True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryFliploader = DataLoader(ImageDataset(gallery_dataset, transform=build_transforms( opt, is_train=False, flip=True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) queryCenterloader = DataLoader(ImageDataset(query_dataset, transform=build_transforms( opt, is_train=False, crop='center')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryCenterloader = DataLoader(ImageDataset(gallery_dataset, transform=build_transforms( opt, is_train=False, crop='center')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) queryLtloader = DataLoader(ImageDataset( query_dataset, transform=build_transforms(opt, is_train=False, crop='lt')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryLtloader = DataLoader(ImageDataset(gallery_dataset, transform=build_transforms( opt, is_train=False, crop='lt')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) queryRtloader = DataLoader(ImageDataset( query_dataset, transform=build_transforms(opt, is_train=False, crop='rt')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryRtloader = DataLoader(ImageDataset(gallery_dataset, transform=build_transforms( opt, is_train=False, crop='rt')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) queryRbloader = DataLoader(ImageDataset( query_dataset, transform=build_transforms(opt, is_train=False, crop='rb')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryRbloader = DataLoader(ImageDataset(gallery_dataset, transform=build_transforms( opt, is_train=False, crop='rb')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) queryLbloader = DataLoader(ImageDataset( query_dataset, transform=build_transforms(opt, is_train=False, crop='lb')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryLbloader = DataLoader(ImageDataset(gallery_dataset, transform=build_transforms( opt, is_train=False, crop='lb')), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) print('initializing model ...') model = build_model(opt) optim_policy = model.get_optim_policy() if opt.pretrained_choice == 'self': state_dict = torch.load(opt.pretrained_model)['state_dict'] # state_dict = {k: v for k, v in state_dict.items() \ # if not ('reduction' in k or 'softmax' in k)} model.load_state_dict(state_dict, False) print('load pretrained model ' + opt.pretrained_model) print('model size: {:.5f}M'.format( sum(p.numel() for p in model.parameters()) / 1e6)) if use_gpu: model = nn.DataParallel(model).cuda() reid_evaluator = Evaluator(model, norm=opt.norm, eval_flip=opt.eval_flip, re_ranking=opt.re_ranking) if opt.use_center: criterion = make_loss_with_center(opt) else: criterion = make_loss(opt) # get optimizer if opt.optim == "sgd": optimizer = torch.optim.SGD(optim_policy, lr=opt.lr, momentum=0.9, weight_decay=opt.weight_decay) else: optimizer = torch.optim.Adam(optim_policy, lr=opt.lr, weight_decay=opt.weight_decay) start_epoch = opt.start_epoch # get trainer and evaluator reid_trainer = cls_tripletTrainer(opt, model, optimizer, criterion, summary_writer) # start training best_rank1 = opt.best_rank best_epoch = 0 for epoch in range(start_epoch, opt.max_epoch): if opt.adjust_lr: adjust_lr(optimizer, opt.lr, opt.model_name, epoch + 1) reid_trainer.train(epoch, trainloader) # skip if not save model if opt.eval_step > 0 and (epoch + 1) % opt.eval_step == 0 or ( epoch + 1) == opt.max_epoch: rank1 = reid_evaluator.validation( queryloader, galleryloader, queryFliploader, galleryFliploader, queryCenterloader, galleryCenterloader, queryLtloader, galleryLtloader, queryRtloader, galleryRtloader, queryLbloader, galleryLbloader, queryRbloader, galleryRbloader) print('start re_ranking......') _ = reid_evaluator.validation(queryloader, galleryloader, queryFliploader, galleryFliploader, queryCenterloader, galleryCenterloader, queryLtloader, galleryLtloader, queryRtloader, galleryRtloader, queryLbloader, galleryLbloader, queryRbloader, galleryRbloader, re_ranking=True) is_best = rank1 > best_rank1 if is_best: best_rank1 = rank1 best_epoch = epoch + 1 if use_gpu: state_dict = model.module.state_dict() else: state_dict = model.state_dict() save_checkpoint({ 'state_dict': state_dict, 'epoch': epoch + 1 }, is_best=is_best, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.pth.tar') print('Best rank-1 {:.1%}, achived at epoch {}'.format( best_rank1, best_epoch))
def train(**kwargs): opt._parse(kwargs) # set random seed and cudnn benchmark torch.manual_seed(opt.seed) use_gpu = torch.cuda.is_available() sys.stdout = Logger(osp.join(opt.save_dir, 'log_train.txt')) print('=========user config==========') pprint(opt._state_dict()) print('============end===============') if use_gpu: print('currently using GPU') cudnn.benchmark = True torch.cuda.manual_seed_all(opt.seed) else: print('currently using cpu') print('initializing dataset {}'.format(opt.dataset)) dataset = data_manager.init_dataset(name=opt.dataset) pin_memory = True if use_gpu else False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) if 'triplet' in opt.model_name: trainloader = DataLoader( ImageData(dataset.train, TrainTransform(opt.height, opt.width)), sampler=RandomIdentitySampler(dataset.train, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True) else: trainloader = DataLoader(ImageData( dataset.train, TrainTransform(opt.height, opt.width)), batch_size=opt.train_batch, shuffle=True, num_workers=opt.workers, pin_memory=pin_memory) queryloader = DataLoader(ImageData(dataset.query, TestTransform(opt.height, opt.width)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryloader = DataLoader(ImageData(dataset.gallery, TestTransform(opt.height, opt.width)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) print('initializing model ...') if opt.model_name == 'softmax' or opt.model_name == 'softmax_triplet': model, optim_policy = get_baseline_model(dataset.num_train_pids) elif opt.model_name == 'triplet': model, optim_policy = get_baseline_model(num_classes=None) print('model size: {:.5f}M'.format( sum(p.numel() for p in model.parameters()) / 1e6)) # xent_criterion = nn.CrossEntropyLoss() xent_criterion = CrossEntropyLabelSmooth(dataset.num_train_pids) tri_criterion = TripletLoss(opt.margin) def cls_criterion(cls_scores, targets): cls_loss = xent_criterion(cls_scores, targets) return cls_loss def triplet_criterion(feat, targets): triplet_loss, _, _ = tri_criterion(feat, targets) return triplet_loss def cls_tri_criterion(cls_scores, feat, targets): cls_loss = xent_criterion(cls_scores, targets) triplet_loss, _, _ = tri_criterion(feat, targets) loss = cls_loss + triplet_loss return loss # get optimizer optimizer = torch.optim.Adam(optim_policy, lr=opt.lr, weight_decay=opt.weight_decay) def adjust_lr(optimizer, ep): if ep < 20: lr = 1e-4 * (ep + 1) / 2 elif ep < 80: lr = 1e-3 * opt.num_gpu elif ep < 180: lr = 1e-4 * opt.num_gpu elif ep < 300: lr = 1e-5 * opt.num_gpu elif ep < 320: lr = 1e-5 * 0.1**((ep - 320) / 80) * opt.num_gpu elif ep < 400: lr = 1e-6 elif ep < 480: lr = 1e-4 * opt.num_gpu else: lr = 1e-5 * opt.num_gpu for p in optimizer.param_groups: p['lr'] = lr start_epoch = opt.start_epoch if use_gpu: model = nn.DataParallel(model).cuda() # get trainer and evaluator if opt.model_name == 'softmax': reid_trainer = clsTrainer(opt, model, optimizer, cls_criterion, summary_writer) elif opt.model_name == 'softmax_triplet': reid_trainer = cls_tripletTrainer(opt, model, optimizer, cls_tri_criterion, summary_writer) elif opt.model_name == 'triplet': reid_trainer = tripletTrainer(opt, model, optimizer, triplet_criterion, summary_writer) reid_evaluator = ResNetEvaluator(model) # start training best_rank1 = -np.inf best_epoch = 0 for epoch in range(start_epoch, opt.max_epoch): if opt.step_size > 0: adjust_lr(optimizer, epoch + 1) reid_trainer.train(epoch, trainloader) # skip if not save model if opt.eval_step > 0 and (epoch + 1) % opt.eval_step == 0 or ( epoch + 1) == opt.max_epoch: rank1 = reid_evaluator.evaluate(queryloader, galleryloader) is_best = rank1 > best_rank1 if is_best: best_rank1 = rank1 best_epoch = epoch + 1 if use_gpu: state_dict = model.module.state_dict() else: state_dict = model.state_dict() save_checkpoint({ 'state_dict': state_dict, 'epoch': epoch + 1, }, is_best=is_best, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.pth.tar') print('Best rank-1 {:.1%}, achived at epoch {}'.format( best_rank1, best_epoch))
def train(**kwargs): opt._parse(kwargs) #opt.lr=0.00002 opt.model_name = 'AlignedReid' # set random seed and cudnn benchmark torch.manual_seed(opt.seed) os.makedirs(opt.save_dir, exist_ok=True) use_gpu = torch.cuda.is_available() sys.stdout = Logger(osp.join(opt.save_dir, 'log_train.txt')) print('=========user config==========') pprint(opt._state_dict()) print('============end===============') if use_gpu: print('currently using GPU') cudnn.benchmark = True torch.cuda.manual_seed_all(opt.seed) else: print('currently using cpu') print('initializing dataset {}'.format(opt.dataset)) dataset = data_manager.init_dataset(name=opt.dataset, mode=opt.mode) pin_memory = True if use_gpu else False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) trainloader = DataLoader(ImageData(dataset.train, TrainTransform(opt.datatype)), sampler=RandomIdentitySampler( dataset.train, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True) queryloader = DataLoader(ImageData(dataset.query, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryloader = DataLoader(ImageData(dataset.gallery, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) queryFliploader = queryloader galleryFliploader = galleryloader # queryFliploader = DataLoader( # ImageData(dataset.query, TestTransform(opt.datatype, True)), # batch_size=opt.test_batch, num_workers=opt.workers, # pin_memory=pin_memory # ) # # galleryFliploader = DataLoader( # ImageData(dataset.gallery, TestTransform(opt.datatype, True)), # batch_size=opt.test_batch, num_workers=opt.workers, # pin_memory=pin_memory # ) print('initializing model ...') model = AlignedResNet50(num_classes=dataset.num_train_pids, loss={'softmax', 'metric'}, aligned=True, use_gpu=use_gpu) optim_policy = model.get_optim_policy() if opt.pretrained_model: state_dict = torch.load(opt.pretrained_model)['state_dict'] # state_dict = {k: v for k, v in state_dict.items() \ # if not ('reduction' in k or 'softmax' in k)} model.load_state_dict(state_dict, False) print('load pretrained model ' + opt.pretrained_model) print('model size: {:.5f}M'.format( sum(p.numel() for p in model.parameters()) / 1e6)) if use_gpu: model = nn.DataParallel(model).cuda() reid_evaluator = AlignedEvaluator(model) if opt.evaluate: #rank1 = test(model, queryloader, galleryloader, use_gpu) reid_evaluator.evaluate(queryloader, galleryloader, queryFliploader, galleryFliploader, re_ranking=opt.re_ranking, savefig=opt.savefig, test_distance='global') return # xent_criterion = nn.CrossEntropyLoss() xent_criterion = CrossEntropyLabelSmooth(dataset.num_train_pids, use_gpu=use_gpu) embedding_criterion = TripletLossAlignedReID(margin=opt.margin) # def criterion(triplet_y, softmax_y, labels): # losses = [embedding_criterion(output, labels)[0] for output in triplet_y] + \ # [xent_criterion(output, labels) for output in softmax_y] # loss = sum(losses) # return loss def criterion(outputs, features, local_features, labels): if opt.htri_only: if isinstance(features, tuple): global_loss, local_loss = DeepSupervision( embedding_criterion, features, labels) else: global_loss, local_loss = embedding_criterion( features, labels, local_features) else: if isinstance(outputs, tuple): xent_loss = DeepSupervision(xent_criterion, outputs, labels) else: xent_loss = xent_criterion(outputs, labels) if isinstance(features, tuple): global_loss, local_loss = DeepSupervision( embedding_criterion, features, labels) else: global_loss, local_loss = embedding_criterion( features, labels, local_features) loss = xent_loss + global_loss + local_loss return loss # get optimizer if opt.optim == "sgd": optimizer = torch.optim.SGD(optim_policy, lr=opt.lr, momentum=0.9, weight_decay=opt.weight_decay) else: optimizer = torch.optim.Adam(optim_policy, lr=opt.lr, weight_decay=opt.weight_decay) start_epoch = opt.start_epoch # get trainer and evaluator reid_trainer = AlignedTrainer(opt, model, optimizer, criterion, summary_writer) def adjust_lr(optimizer, ep): if ep < 50: lr = opt.lr * (ep // 5 + 1) elif ep < 200: lr = opt.lr * 10 elif ep < 300: lr = opt.lr else: lr = opt.lr * 0.1 for p in optimizer.param_groups: p['lr'] = lr # start training best_rank1 = opt.best_rank best_epoch = 0 print('start train......') for epoch in range(start_epoch, opt.max_epoch): if opt.adjust_lr: adjust_lr(optimizer, epoch + 1) reid_trainer.train(epoch, trainloader) # skip if not save model if opt.eval_step > 0 and (epoch + 1) % opt.eval_step == 0 or ( epoch + 1) == opt.max_epoch: # just avoid out of memory during eval,and can't save the model if use_gpu: state_dict = model.module.state_dict() else: state_dict = model.state_dict() save_checkpoint({ 'state_dict': state_dict, 'epoch': epoch + 1 }, is_best=0, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.pth.tar') if opt.mode == 'class': rank1 = test(model, queryloader) else: rank1 = reid_evaluator.evaluate(queryloader, galleryloader, queryFliploader, galleryFliploader) #rank1 = test(model, queryloader, galleryloader, use_gpu) is_best = rank1 > best_rank1 if is_best: best_rank1 = rank1 best_epoch = epoch + 1 if use_gpu: state_dict = model.module.state_dict() else: state_dict = model.state_dict() if is_best: save_checkpoint({ 'state_dict': state_dict, 'epoch': epoch + 1 }, is_best=is_best, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.pth.tar') print('Best rank-1 {:.1%}, achived at epoch {}'.format( best_rank1, best_epoch))
def train(**kwargs): opt._parse(kwargs) # set random seed and cudnn benchmark torch.manual_seed(opt.seed) # os.makedirs(opt.save_dir, exist_ok=True) use_gpu = torch.cuda.is_available() sys.stdout = Logger(osp.join(opt.save_dir, 'log_train.txt')) print('=========user config==========') print(opt._state_dict()) print('============end===============') if use_gpu: print('currently using GPU') cudnn.benchmark = True torch.cuda.manual_seed_all(opt.seed) else: print('currently using cpu') print('initializing dataset {}'.format(opt.dataset)) dataset = data_manager.init_dataset(name=opt.dataset, mode=opt.mode) pin_memory = True if use_gpu else False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) trainloader = DataLoader( ImageData(dataset.train, TrainTransform(opt.datatype)), sampler=RandomIdentitySampler(dataset.train, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True ) queryloader = DataLoader( ImageData(dataset.query, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory ) galleryloader = DataLoader( ImageData(dataset.gallery, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory ) queryFliploader = DataLoader( ImageData(dataset.query, TestTransform(opt.datatype, True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory ) galleryFliploader = DataLoader( ImageData(dataset.gallery, TestTransform(opt.datatype, True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory ) print('initializing model ...') if opt.model_name == 'softmax' or opt.model_name == 'softmax_triplet': model = ResNetBuilder(dataset.num_train_pids, 1, True) elif opt.model_name == 'triplet': model = ResNetBuilder(None, 1, True) elif opt.model_name == 'CBDB': if opt.datatype == "person": model = CBDBdataset.num_train_pids, 1.0, 0.33) else: model = CBDB(dataset.num_train_pids, 0.5, 0.5) elif opt.model_name == 'ide': model = IDE(dataset.num_train_pids) elif opt.model_name == 'resnet': model = Resnet(dataset.num_train_pids) optim_policy = model.get_optim_policy() if opt.pretrained_model: state_dict = torch.load(opt.pretrained_model)['state_dict'] #state_dict = {k: v for k, v in state_dict.items() \ # if not ('reduction' in k or 'softmax' in k)} model.load_state_dict(state_dict, False) print('load pretrained model ' + opt.pretrained_model) print('model size: {:.5f}M'.format(sum(p.numel() for p in model.parameters()) / 1e6)) if use_gpu: model = nn.DataParallel(model).cuda() reid_evaluator = ResNetEvaluator(model) if opt.evaluate: reid_evaluator.evaluate(queryloader, galleryloader, queryFliploader, galleryFliploader, re_ranking=opt.re_ranking, savefig=opt.savefig) return
def train(**kwargs): opt._parse(kwargs) #opt.lr=0.00002 opt.model_name='PCB' # set random seed and cudnn benchmark torch.manual_seed(opt.seed) os.makedirs(opt.save_dir, exist_ok=True) use_gpu = torch.cuda.is_available() sys.stdout = Logger(osp.join(opt.save_dir, 'log_train.txt')) print('=========user config==========') pprint(opt._state_dict()) print('============end===============') if use_gpu: print('currently using GPU') cudnn.benchmark = True torch.cuda.manual_seed_all(opt.seed) else: print('currently using cpu') print('initializing dataset {}'.format(opt.dataset)) dataset = data_manager.init_dataset(name=opt.dataset, mode=opt.mode) tgt_dataset = data_manager.init_dataset(name=opt.tgt_dataset,mode=opt.mode) pin_memory = True if use_gpu else False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) trainloader = DataLoader( ImageData(dataset.train, TrainTransform(opt.datatype)), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True ) tgt_trainloader = DataLoader( ImageData(tgt_dataset.train, TrainTransform(opt.datatype)), batch_size=opt.train_batch,num_workers=opt.workers, pin_memory=pin_memory,drop_last=True ) tgt_queryloader = DataLoader( ImageData(tgt_dataset.query, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory ) tgt_galleryloader = DataLoader( ImageData(tgt_dataset.gallery, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory ) tgt_queryFliploader = DataLoader( ImageData(tgt_dataset.query, TestTransform(opt.datatype, True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory ) tgt_galleryFliploader = DataLoader( ImageData(tgt_dataset.gallery, TestTransform(opt.datatype, True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory ) print('initializing model ...') model = PCB(dataset.num_train_pids) optim_policy = model.get_optim_policy() start_epoch = opt.start_epoch if opt.pretrained_model: checkpoint = torch.load(opt.pretrained_model) state_dict = checkpoint['state_dict'] # state_dict = {k: v for k, v in state_dict.items() \ # if not ('reduction' in k or 'softmax' in k)} try: model.load_state_dict(state_dict, False) print('load pretrained model ' + opt.pretrained_model) except: RuntimeError('please keep the same size with source dataset..') else: raise RuntimeError('please load a pre-trained model...') print('model size: {:.5f}M'.format(sum(p.numel() for p in model.parameters()) / 1e6)) if use_gpu: model = nn.DataParallel(model).cuda() reid_evaluator = ResNetEvaluator(model) if opt.evaluate: print('transfer directly....... ') reid_evaluator.evaluate(tgt_queryloader, tgt_galleryloader, tgt_queryFliploader, tgt_galleryFliploader, re_ranking=opt.re_ranking, savefig=opt.savefig) return #xent_criterion = CrossEntropyLabelSmooth(dataset.num_train_pids) embedding_criterion = SelfTraining_TripletLoss(margin=0.5,num_instances=4) # def criterion(triplet_y, softmax_y, labels): # losses = [embedding_criterion(output, labels)[0] for output in triplet_y] + \ # [xent_criterion(output, labels) for output in softmax_y] # loss = sum(losses) # return loss def criterion(triplet_y, softmax_y, labels): #losses = [torch.sum(torch.stack([xent_criterion(logits, labels) for logits in softmax_y]))] losses = [torch.sum(torch.stack([embedding_criterion(output,labels) for output in triplet_y]))] loss = sum(losses) return loss # get optimizer if opt.optim == "sgd": optimizer = torch.optim.SGD(optim_policy, lr=opt.lr, momentum=0.9, weight_decay=opt.weight_decay) else: optimizer = torch.optim.Adam(optim_policy, lr=opt.lr, weight_decay=opt.weight_decay) # get trainer and evaluator reid_trainer = PCBTrainer(opt, model, optimizer, criterion, summary_writer) def adjust_lr(optimizer, ep): if ep < 50: lr = opt.lr * (ep // 5 + 1) elif ep < 200: lr = opt.lr*10 elif ep < 300: lr = opt.lr else: lr = opt.lr*0.1 for p in optimizer.param_groups: p['lr'] = lr # start training best_rank1 = opt.best_rank best_epoch = 0 print('transfer directly.....') reid_evaluator.evaluate(tgt_queryloader, tgt_galleryloader, tgt_queryFliploader, tgt_galleryFliploader, re_ranking=opt.re_ranking, savefig=opt.savefig) for iter_n in range(start_epoch,opt.max_epoch): if opt.lambda_value == 0: source_features = 0 else: # get source datas' feature print('Iteration {}: Extracting Source Dataset Features...'.format(iter_n + 1)) source_features, _ = extract_pcb_features(model, trainloader) # extract training images' features print('Iteration {}: Extracting Target Dataset Features...'.format(iter_n + 1)) target_features, _ = extract_pcb_features(model, tgt_trainloader) # synchronization feature order with dataset.train # calculate distance and rerank result print('Calculating feature distances...') target_features = target_features.numpy() rerank_dist = re_ranking( source_features, target_features, lambda_value=opt.lambda_value) if iter_n == 0: # DBSCAN cluster tri_mat = np.triu(rerank_dist, 1) # tri_mat.dim=2 取上三角 tri_mat = tri_mat[np.nonzero(tri_mat)] # tri_mat.dim=1 tri_mat = np.sort(tri_mat, axis=None) top_num = np.round(opt.rho * tri_mat.size).astype(int) eps = tri_mat[:top_num].mean() # DBSCAN聚类半径 print('eps in cluster: {:.3f}'.format(eps)) cluster = DBSCAN(eps=eps, min_samples=4, metric='precomputed', n_jobs=8) # select & cluster images as training set of this epochs print('Clustering and labeling...') labels = cluster.fit_predict(rerank_dist) del(rerank_dist) del(source_features) del(target_features) try: gc.collect() except: print('cannot collect') num_ids = len(set(labels)) - 1 print('Iteration {} have {} training ids'.format(iter_n + 1, num_ids)) # generate new dataset new_dataset = [] for (fname, _, _), label in zip(tgt_dataset.train, labels): if label == -1: continue # dont need to change codes in trainer.py _parsing_input function and sampler function after add 0 new_dataset.append((fname, label, 0)) print('Iteration {} have {} training images'.format(iter_n + 1, len(new_dataset))) selftrain_loader = DataLoader( ImageData(new_dataset, TrainTransform(opt.datatype)), sampler=RandomIdentitySampler(new_dataset, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True ) # train model with new generated dataset trainer = PCBTrainer(opt, model, optimizer, criterion, summary_writer) reid_evaluator = ResNetEvaluator(model) # Start training for epoch in range(opt.selftrain_iterations): trainer.train(epoch, selftrain_loader) # skip if not save model if opt.eval_step > 0 and (iter_n + 1) % opt.eval_step == 0 or (iter_n + 1) == opt.max_epoch: # just avoid out of memory during eval,and can't save the model if use_gpu: state_dict = model.module.state_dict() else: state_dict = model.state_dict() save_checkpoint({'state_dict': state_dict, 'epoch': iter_n + 1}, is_best=0, save_dir=opt.save_dir, filename='checkpoint_ep' + str(iter_n + 1) + '.pth.tar') if (iter_n + 1) % (opt.eval_step*4) == 0: if opt.mode == 'class': rank1 = test(model, tgt_queryloader) else: rank1 = reid_evaluator.evaluate(tgt_queryloader, tgt_galleryloader, tgt_queryFliploader, tgt_galleryFliploader) is_best = rank1 > best_rank1 if is_best: best_rank1 = rank1 best_epoch = iter_n + 1 if use_gpu: state_dict = model.module.state_dict() else: state_dict = model.state_dict() if is_best: save_checkpoint({'state_dict': state_dict, 'epoch': iter_n + 1}, is_best=is_best, save_dir=opt.save_dir, filename='checkpoint_ep' + str(iter_n + 1) + '.pth.tar') print('Best rank-1 {:.1%}, achived at epoch {}'.format(best_rank1, best_epoch))
from datasets.data_loader import ImageData from datasets.samplers import RandomIdentitySampler from utils.serialization import Logger, save_checkpoint from utils.transforms import TestTransform, TrainTransform use_gpu = True if __name__ == '__main__': dataset = data_manager.init_dataset(name=opt.dataset, mode=opt.mode) pin_memory = True if use_gpu else False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) trainloader = DataLoader(ImageData(dataset.train, TrainTransform(opt.datatype)), sampler=RandomIdentitySampler( dataset.train, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True) model = PlateNet(batch_size=opt.train_batch, n_class=66) optim_policy = model.get_optim_policy() if use_gpu: model = nn.DataParallel(model).cuda() print('dddddddddddd') criterion = nn.CTCLoss() # get optimizer if opt.optim == "sgd":
def train(**kwargs): opt._parse(kwargs) # set random seed and cudnn benchmark sys.stdout = Logger(osp.join(opt.save_dir, 'log_train.txt')) print('=========user config==========') pprint(opt._state_dict()) print('============end===============') print('initializing dataset {}'.format(opt.dataset)) dataset = data_manager.init_dataset(name=opt.dataset) summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) if 'triplet' in opt.model_name: trainloader = DataLoader( ImageData(dataset.train, TrainTransform(opt.height, opt.width)), sampler=RandomIdentitySampler(dataset.train, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, last_batch='discard') else: trainloader = DataLoader( ImageData(dataset.train, TrainTransform(opt.height, opt.width)), batch_size=opt.train_batch, shuffle=True, num_workers=opt.workers, ) queryloader = DataLoader( ImageData(dataset.query, TestTransform(opt.height, opt.width)), batch_size=opt.test_batch, num_workers=opt.workers, ) galleryloader = DataLoader( ImageData(dataset.gallery, TestTransform(opt.height, opt.width)), batch_size=opt.test_batch, num_workers=opt.workers, ) print('initializing model ...') model = get_baseline_model(dataset.num_train_pids, mx.gpu(0), opt.pretrained_model) print('model size: {:.5f}M'.format( sum(p.data().size for p in model.collect_params().values()) / 1e6)) xent_criterion = gluon.loss.SoftmaxCrossEntropyLoss() tri_criterion = TripletLoss(opt.margin) def cls_criterion(cls_scores, feat, targets): cls_loss = xent_criterion(cls_scores, targets) return cls_loss def triplet_criterion(cls_scores, feat, targets): triplet_loss, dist_ap, dist_an = tri_criterion(feat, targets) return triplet_loss def cls_tri_criterion(cls_scores, feat, targets): cls_loss = xent_criterion(cls_scores, targets) triplet_loss, dist_ap, dist_an = tri_criterion(feat, targets) loss = cls_loss + triplet_loss return loss # get optimizer optimizer = gluon.Trainer(model.collect_params(), opt.optim, { 'learning_rate': opt.lr, 'wd': opt.weight_decay }) def adjust_lr(optimizer, ep): if ep < 20: lr = 1e-4 * (ep + 1) / 2 elif ep < 80: lr = 1e-3 * opt.num_gpu elif ep < 180: lr = 1e-4 * opt.num_gpu elif ep < 300: lr = 1e-5 * opt.num_gpu elif ep < 320: lr = 1e-5 * 0.1**((ep - 320) / 80) * opt.num_gpu elif ep < 400: lr = 1e-6 elif ep < 480: lr = 1e-4 * opt.num_gpu else: lr = 1e-5 * opt.num_gpu optimizer.set_learning_rate(lr) start_epoch = opt.start_epoch # get trainer and evaluator use_criterion = None if opt.model_name == 'softmax': use_criterion = cls_criterion elif opt.model_name == 'softmax_triplet': use_criterion = cls_tri_criterion elif opt.model_name == 'triplet': use_criterion = triplet_criterion reid_trainer = reidTrainer(opt, model, optimizer, use_criterion, summary_writer, mx.gpu(0)) reid_evaluator = reidEvaluator(model, mx.gpu(0)) # start training best_rank1 = -np.inf best_epoch = 0 for epoch in range(start_epoch, opt.max_epoch): if opt.step_size > 0: adjust_lr(optimizer, epoch + 1) reid_trainer.train(epoch, trainloader) # skip if not save model if opt.eval_step > 0 and (epoch + 1) % opt.eval_step == 0 or ( epoch + 1) == opt.max_epoch: rank1 = reid_evaluator.evaluate(queryloader, galleryloader) is_best = rank1 > best_rank1 if is_best: best_rank1 = rank1 best_epoch = epoch + 1 state_dict = {'model': model, 'epoch': epoch} save_checkpoint(state_dict, is_best=is_best, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.params') print('Best rank-1 {:.1%}, achived at epoch {}'.format( best_rank1, best_epoch))
def train(**kwargs): #### Part 1 : Initialization opt._parse(kwargs) torch.backends.cudnn.deterministic = True # set random seed and cudnn benchmark #torch.manual_seed(opt.seed) #random.seed(opt.seed) #np.random.seed(opt.seed) use_gpu = torch.cuda.is_available() sys.stdout = Logger(osp.join(opt.save_dir, 'log_train.txt')) print('=========user config==========') pprint(opt._state_dict()) print('============end===============') if use_gpu: print('currently using GPU') cudnn.benchmark = True torch.cuda.manual_seed_all(opt.seed) else: print('currently using cpu') #### Part 2 : Preparing Data print('initializing train dataset {}'.format(opt.trainset)) train_dataset = data_manager.init_dataset(name=opt.trainset) print('initializing test dataset {}'.format(opt.testset)) test_dataset = data_manager.init_dataset(name=opt.testset) pin_memory = True if use_gpu else False pin_memory = False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) collateFn = NormalCollateFn() if opt.sampler == "randomidentity": trainloader = DataLoader( data_manager.init_datafolder( opt.trainset, train_dataset.train, TrainTransform(opt.height, opt.width, random_erase=opt.with_randomerase), if_train=True), sampler=RandomIdentitySampler(train_dataset.train, opt.num_instances), batch_size=opt.train_batch, num_workers=opt.workers, pin_memory=pin_memory, drop_last=True, collate_fn=collateFn, ) elif opt.sampler == "randomidentitycamera": trainloader = DataLoader( data_manager.init_datafolder( opt.trainset, train_dataset.train, TrainTransform(opt.height, opt.width, random_erase=opt.with_randomerase), if_train=True), batch_sampler=RandomIdentityCameraSampler(train_dataset.train, opt.num_instances, opt.train_batch), num_workers=opt.workers, pin_memory=pin_memory, collate_fn=collateFn, ) queryloader = DataLoader(data_manager.init_datafolder(opt.testset, test_dataset.query, TestTransform( opt.height, opt.width), if_train=False), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) galleryloader = DataLoader(data_manager.init_datafolder( opt.testset, test_dataset.gallery, TestTransform(opt.height, opt.width), if_train=False), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) #### Part 3 : Preparing Backbone Network print('initializing model ...') if opt.model_name in ['triplet', 'distance']: model, optim_policy = get_baseline_model(num_classes=None, model='triplet') elif opt.model_name in ["softmax"]: model, optim_policy = get_baseline_model(train_dataset.num_train_pids, model='softmax', drop_prob=opt.drop) else: assert False, "unknown model name" if (not opt.model_path == 'zero') and 'tar' in opt.model_path: print('load pretrain reid model......' + opt.model_path) ckpt = torch.load(opt.model_path) # remove classifer tmp = dict() for k, v in ckpt['state_dict'].items(): if opt.keep_layer: for i in opt.keep_layer: if 'layer' + str(i) in k: #print(k+" skip....") continue if opt.keepfc or ('fc' not in k and 'classifier' not in k): tmp[k] = v ckpt['state_dict'] = tmp model.load_state_dict(ckpt['state_dict'], strict=False) print('model size: {:.5f}M'.format( sum(p.numel() for p in model.parameters()) / 1e6)) #### Part 4: Preparing Loss Functions if opt.margin1 is not None: distance_loss = DistanceLoss(margin=(opt.margin1, opt.margin2)) else: distance_loss = DistanceLoss() tri_loss = TripletLoss(margin=opt.margin) xent_loss = nn.CrossEntropyLoss() vis = dict() vis['tri_acc1'] = AverageMeter() vis['tri_acc2'] = AverageMeter() vis['cls_accuracy'] = AverageMeter() vis['cls_loss'] = AverageMeter() def dist_criterion(feat, targets, cameras, model=None, paths=None, epoch=0): dis_loss, tri_acc1, tri_acc2 = distance_loss(feat, targets, cameras, model, paths, epoch=epoch) vis['tri_acc1'].update(float(tri_acc1)) vis['tri_acc2'].update(float(tri_acc2)) return dis_loss def triplet_criterion(feat, targets): triplet_loss, tri_accuracy, _, _ = tri_loss(feat, targets) vis['tri_acc1'].update(float(tri_accuracy)) return triplet_loss def cls_criterion(cls_scores, targets): cls_loss = xent_loss(cls_scores, targets) _, preds = torch.max(cls_scores.data, 1) corrects = float(torch.sum(preds == targets.data)) vis['cls_accuracy'].update(float(corrects / opt.train_batch)) vis['cls_loss'].update(float(cls_loss)) return cls_loss #### Part 5: Preparing Optimizer and Trainer optimizer, adjust_lr = get_optimizer_strategy(opt.model_name, optim_policy, opt) start_epoch = opt.start_epoch if use_gpu: model = nn.DataParallel(model).cuda() #model=model.cuda() # get trainer and evaluatori if opt.model_name == "distance": reid_trainer = tripletTrainer(opt, model, optimizer, dist_criterion, summary_writer, need_cam=True) elif opt.model_name == 'triplet' or opt.model_name == 'triplet_fc': reid_trainer = tripletTrainer(opt, model, optimizer, triplet_criterion, summary_writer) elif opt.model_name == 'softmax': reid_trainer = clsTrainer(opt, model, optimizer, cls_criterion, summary_writer) else: print("Error: Unknown model name {}".format(opt.model_name)) reid_evaluator = evaluator_manager.init_evaluator(opt.testset, model, flip=True) #### Part 6 : Training best_rank1 = -np.inf best_epoch = 0 for epoch in range(start_epoch, opt.max_epoch): if opt.step_size > 0: current_lr = adjust_lr(optimizer, epoch) reid_trainer.train(epoch, trainloader) for k, v in vis.items(): print("{}:{}".format(k, v.mean)) v.reset() if (epoch + 1) == opt.max_epoch: if use_gpu and opt.num_gpu > 1: state_dict = model.module.state_dict() else: state_dict = model.state_dict() save_checkpoint({ 'state_dict': state_dict, 'epoch': epoch + 1, }, is_best=False, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.pth.tar') # skip if not save model if (opt.eval_step > 0 and (epoch + 1) % opt.eval_step == 0 and epoch >= 0 or (epoch + 1) == opt.max_epoch): #print('Test on '+opt.testset) #rank1 = reid_evaluator.evaluate(queryloader, galleryloader,normalize=opt.with_normalize) print('Test on ' + opt.trainset) if use_gpu and opt.num_gpu > 1: state_dict = model.module.state_dict() else: state_dict = model.state_dict() save_checkpoint({ 'state_dict': state_dict, 'epoch': epoch + 1, }, is_best=False, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.pth.tar') rank1, mAP = reid_evaluator.evaluate(queryloader, galleryloader, normalize=opt.with_normalize) is_best = rank1 > best_rank1 if is_best: best_rank1 = rank1 best_epoch = epoch + 1 save_checkpoint( { 'state_dict': state_dict, 'epoch': epoch + 1, }, is_best=False, save_dir=opt.save_dir, filename='checkpoint_ep' + str(epoch + 1) + '.pth.tar') print('Best rank-1 {:.1%}, achieved at epoch {}'.format( best_rank1, best_epoch))