def test(**kwargs): opt._parse(kwargs) 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, use_all=opt.use_all) # load data pin_memory = True if use_gpu else False dataloader = load_data(dataset, pin_memory) print('111') print(dataloader['query'].dataset.dataset[0][0]) print('initializing model ...') if opt.loss == 'softmax' or opt.loss == 'softmax_triplet': model = ResNetBuilder(dataset.num_train_pids, opt.last_stride, True) elif opt.loss == 'triplet': model = ResNetBuilder(None, opt.last_stride, True) if opt.pretrained_model: if use_gpu: state_dict = torch.load(opt.pretrained_model)['state_dict'] else: state_dict = torch.load(opt.pretrained_model, map_location='cpu')['state_dict'] 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) reid_evaluator.test(dataloader['query'], dataloader['gallery'], savefig=opt.savefig, i=opt.findid) return
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==========') 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))
def train(**kwargs): opt._parse(kwargs) # set random seed and cudnn benchmark torch.manual_seed(opt.seed) # os.environ['CUDA_VISIBLE_DEVICES'] = '0' 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') pin_memory = True if use_gpu else False summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) # -------------- model and parameter loading ------------------ print('initializing model ...') if opt.model_name == 'bfe': if opt.datatype == "person": model = BFE(751, 1.0, 0.33) else: model = BFE(751, 0.5, 0.5) optim_policy = model.parameters() if opt.pretrained_model: state_dict = torch.load(opt.pretrained_model)['state_dict'] 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() # model.cuda() reid_evaluator = ResNetEvaluator(model) # -------------------------- load end ------------------------- def handleDataset(): print('initializing dataset {}'.format(opt.dataset)) # 之前不需要动 dataset = data_manager.init_dataset(name=opt.dataset, mode=opt.mode) # for query images queryloader = DataLoader( ImageData(dataset.query, TestTransform(opt.datatype)), batch_size=opt.test_batch, num_workers=opt.workers, # test_batch = 1 pin_memory=pin_memory) # for target image galleryloader = DataLoader(ImageData(dataset.target, 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.target, TestTransform(opt.datatype, True)), batch_size=opt.test_batch, num_workers=opt.workers, pin_memory=pin_memory) return queryloader, galleryloader, queryFliploader, galleryFliploader # def deleteDirImage(): def recv_and_send_data(clnt_sock): # 循环接收和发送数据 strSend = 'Please send messages to me... \n' strSend = strSend.encode() clnt_sock.send(strSend) print("send successfully") while True: recv_data = clnt_sock.recv(1024) queryloader, galleryloader, queryFliploader, galleryFliploader = handleDataset( ) cmc = reid_evaluator.evaluate(queryloader, galleryloader, queryFliploader, galleryFliploader, re_ranking=opt.re_ranking, savefig=opt.savefig) # reply 需要换成对应的数据 if recv_data: reply = 'cmc : ' + str(cmc) # cmc is numpy.floate clnt_sock.sendall(reply.encode()) # 删除文件夹数据 # deleteDirImage else: break clnt_sock.close() # ------------------------ start TCP ---------------------------- serv_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print("socket creating...") # bind try: serv_sock.bind(('127.0.0.1', 8801)) except socket.error: print("Bind failed ") sys.exit() print("socket bind successfully") # listen serv_sock.listen(10) print("socket start listening") # accept while True: clnt_sock, clnt_addr = serv_sock.accept() print("Connected to IP:port —— ", clnt_addr[0], ' : ', str(clnt_addr[1])) # core part start_new_thread(recv_and_send_data, (clnt_sock, )) # 元组形式 # close serv_sock.close()
def train(**kwargs): opt._parse(kwargs) 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, use_all=opt.use_all) summary_writer = SummaryWriter(osp.join(opt.save_dir, 'tensorboard_log')) # load data pin_memory = True if use_gpu else False dataloader = load_data(dataset, pin_memory) print('initializing model ...') if opt.loss == 'softmax' or opt.loss == 'softmax_triplet': model = ResNetBuilder(dataset.num_train_pids, opt.last_stride, True) elif opt.loss == 'triplet': model = ResNetBuilder(None, opt.last_stride, True) if opt.pretrained_model: if use_gpu: state_dict = torch.load(opt.pretrained_model)['state_dict'] else: state_dict = torch.load(opt.pretrained_model, map_location='cpu')['state_dict'] 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)) optim_policy = model.get_optim_policy() if use_gpu: model = nn.DataParallel(model).cuda() reid_evaluator = ResNetEvaluator(model) if opt.evaluate: reid_evaluator.evaluate(dataloader['query'], dataloader['gallery'], dataloader['queryFlip'], dataloader['galleryFlip'], savefig=opt.savefig) return criterion = get_loss() # optimizer if opt.optim == "sgd": optimizer = torch.optim.SGD(optim_policy, lr=opt.lr, momentum=0.9, weight_decay=5e-4) else: optimizer = torch.optim.Adam(optim_policy, lr=opt.lr, weight_decay=5e-4) scheduler = WarmupMultiStepLR(optimizer, [40, 70], 0.1, 0.01, 10, 'linear') start_epoch = opt.start_epoch # get trainer and evaluator reid_trainer = Trainer(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): scheduler.step() reid_trainer.train(epoch, dataloader['train']) # 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(dataloader['query'], dataloader['gallery'], dataloader['queryFlip'], dataloader['galleryFlip']) is_best = rank1 > best_rank1 if is_best: best_rank1 = rank1 best_epoch = epoch + 1 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))