def main(): global args, best_prec1 args = parser.parse_args() args.distributed = args.world_size > 1 if args.distributed: dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url, world_size=args.world_size) # create model if args.pretrained: print("=> using pre-trained model '{}'".format(args.arch)) model = models.__dict__[args.arch](pretrained=True) else: print("=> creating model '{}'".format(args.arch)) model = models.__dict__[args.arch](low_dim=args.low_dim) if not args.distributed: if args.arch.startswith('alexnet') or args.arch.startswith('vgg'): model.features = torch.nn.DataParallel(model.features) model.cuda() else: model = torch.nn.DataParallel(model).cuda() else: model.cuda() model = torch.nn.parallel.DistributedDataParallel(model) # Data loading code traindir = os.path.join(args.data, 'train') valdir = os.path.join(args.data, 'val') normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) train_dataset = datasets.ImageFolderInstance( traindir, transforms.Compose([ transforms.RandomResizedCrop(224, scale=(0.2,1.)), transforms.RandomGrayscale(p=0.2), transforms.ColorJitter(0.4, 0.4, 0.4, 0.4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), normalize, ])) if args.distributed: train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset) else: train_sampler = None train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None), num_workers=args.workers, pin_memory=True, sampler=train_sampler) val_loader = torch.utils.data.DataLoader( datasets.ImageFolderInstance(valdir, transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), normalize, ])), batch_size=args.batch_size, shuffle=False, num_workers=args.workers, pin_memory=True) # define lemniscate and loss function (criterion) ndata = train_dataset.__len__() if args.nce_k > 0: lemniscate = NCEAverage(args.low_dim, ndata, args.nce_k, args.nce_t, args.nce_m).cuda() criterion = NCECriterion(ndata).cuda() else: lemniscate = LinearAverage(args.low_dim, ndata, args.nce_t, args.nce_m).cuda() criterion = nn.CrossEntropyLoss().cuda() optimizer = torch.optim.SGD(model.parameters(), args.lr, momentum=args.momentum, weight_decay=args.weight_decay) # optionally resume from a checkpoint if args.resume: if os.path.isfile(args.resume): print("=> loading checkpoint '{}'".format(args.resume)) checkpoint = torch.load(args.resume) args.start_epoch = checkpoint['epoch'] best_prec1 = checkpoint['best_prec1'] model.load_state_dict(checkpoint['state_dict']) lemniscate = checkpoint['lemniscate'] optimizer.load_state_dict(checkpoint['optimizer']) print("=> loaded checkpoint '{}' (epoch {})" .format(args.resume, checkpoint['epoch'])) else: print("=> no checkpoint found at '{}'".format(args.resume)) cudnn.benchmark = True if args.evaluate: kNN(0, model, lemniscate, train_loader, val_loader, 200, args.nce_t) return for epoch in range(args.start_epoch, args.epochs): if args.distributed: train_sampler.set_epoch(epoch) adjust_learning_rate(optimizer, epoch) # train for one epoch train(train_loader, model, lemniscate, criterion, optimizer, epoch) # evaluate on validation set prec1 = NN(epoch, model, lemniscate, train_loader, val_loader) # remember best prec@1 and save checkpoint is_best = prec1 > best_prec1 best_prec1 = max(prec1, best_prec1) save_checkpoint({ 'epoch': epoch + 1, 'arch': args.arch, 'state_dict': model.state_dict(), 'lemniscate': lemniscate, 'best_prec1': best_prec1, 'optimizer' : optimizer.state_dict(), }, is_best) # evaluate KNN after last epoch kNN(0, model, lemniscate, train_loader, val_loader, 200, args.nce_t)
and callable(models.__dict__[name])) model = models.__dict__['resnet18'](low_dim=128) checkpoint = torch.load('lemniscate_resnet18.pth.tar') model = torch.nn.DataParallel(model).cuda() model.load_state_dict(checkpoint['state_dict']) model.eval() #load query data set from root/datas/val1 traindir = os.path.join('datas', 'val1') normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) train_dataset = datasets.ImageFolderInstance( traindir, transforms.Compose([ transforms.Resize((224,224)), transforms.ToTensor(), normalize, ])) train_loader = torch.utils.data.DataLoader( train_dataset) # compute the cosin similarity with perfect_500k dataset for each feature vector in query data set for i, (input, _, index) in enumerate(train_loader): #test_index=the image ID of query image test_index=train_dataset.imgs[i][0].split('/')[3].split('.')[0] print test_index # measure data loading time index = index.cuda(async=True) input_var = torch.autograd.Variable(input)
def main(args): # _size = 32 _size = 224 # fix random seeds torch.manual_seed(args.seed) torch.cuda.manual_seed_all(args.seed) np.random.seed(args.seed) best_prec1 = 0 # load model print('==> Building model..') # net = models.__dict__['ResNet18'](low_dim=args.low_dim) net = models.__dict__['alexnet'](out=args.low_dim) net = torch.nn.DataParallel(net, device_ids=range(torch.cuda.device_count())) checkpoint = torch.load(args.model) net.load_state_dict(checkpoint['net']) # model = load_model(args.model) model = net model.cuda() cudnn.benchmark = True # freeze the features layers for param in model.parameters(): #features. param.requires_grad = False # define loss function (criterion) and optimizer criterion = nn.CrossEntropyLoss().cuda() # data loading code # traindir = os.path.join(args.data, 'train') # valdir = os.path.join(args.data, 'val') normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) transform_train = transforms.Compose([ transforms.Resize(size=_size), transforms.RandomResizedCrop(size=_size, scale=(0.2, 1.)), transforms.ColorJitter(0.4, 0.4, 0.4, 0.4), transforms.RandomGrayscale(p=0.2), transforms.RandomHorizontalFlip(), transforms.ToTensor(), normalize, ]) if args.tencrops: transform_test = transforms.Compose([ transforms.Resize(size=_size), transforms.Lambda(lambda crops: torch.stack([normalize(transforms.ToTensor()(crop)) for crop in crops])), ]) else: transform_test = transforms.Compose([ transforms.Resize(size=_size), transforms.CenterCrop(_size), transforms.ToTensor(), normalize, ]) trainset = cifar_datasets.ImageFolderInstance('/data2/zyf/ImageNet/ILSVRC2012-100/train', transform=transform_train, two_crop=True) trainloader = torch.utils.data.DataLoader(trainset, batch_size=args.batch_size, shuffle=True, num_workers=8) testset = cifar_datasets.ImageFolderInstance('/data2/zyf/ImageNet/ILSVRC2012-100/val', transform=transform_test) testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=8) # logistic regression reglog = AlexnetRegLog(args.conv, len(trainset.classes)).cuda() optimizer = torch.optim.SGD( filter(lambda x: x.requires_grad, reglog.parameters()), args.lr, momentum=args.momentum, weight_decay=10 ** args.weight_decay ) for epoch in range(args.epochs): end = time.time() # train for one epoch train(trainloader, model, reglog, criterion, optimizer, epoch, forward_alexnet) # evaluate on validation set prec1, prec5, loss = validate(testloader, model, reglog, criterion, forward_alexnet) writer.add_scalar('acc', prec1, epoch) # loss_log.log(loss) # prec1_log.log(prec1) # prec5_log.log(prec5) # remember best prec@1 and save checkpoint is_best = prec1 > best_prec1 best_prec1 = max(prec1, best_prec1) if is_best: filename = 'pcf200_model_best.pth.tar' print('best acc: ' + str(prec1)) else: filename = 'pcf200_checkpoint.pth.tar' torch.save({ 'epoch': epoch + 1, 'arch': 'net', 'state_dict': model.state_dict(), 'prec5': prec5, 'best_prec1': best_prec1, 'optimizer': optimizer.state_dict(), }, os.path.join(args.exp, filename))
def main(): global args, best_prec1 args = parser.parse_args() # Initialize distributed processing args.distributed = args.world_size > 1 if args.distributed: dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url, world_size=args.world_size) # create model if args.pretrained: print("=> using pre-trained model '{}'".format(args.arch)) model = models.__dict__[args.arch](pretrained=True, low_dim=args.low_dim) else: print("=> creating model '{}'".format(args.arch)) model = models.__dict__[args.arch](low_dim=args.low_dim) if not args.distributed: if args.arch.startswith('alexnet') or args.arch.startswith('vgg'): model.features = torch.nn.DataParallel(model.features) model.cuda() else: model = torch.nn.DataParallel(model).cuda() else: model.cuda() model = torch.nn.parallel.DistributedDataParallel(model) # Data loading code traindir = os.path.join(args.data, 'train') valdir = os.path.join(args.data, 'val') normalize = transforms.Normalize( mean=[0.485, 0.456, 0.406], # ImageNet stats std=[0.229, 0.224, 0.225]) # normalize = transforms.Normalize(mean=[0.234, 0.191, 0.159], # xView stats # std=[0.173, 0.143, 0.127]) print("Creating datasets") cj = args.color_jit train_dataset = datasets.ImageFolderInstance( traindir, transforms.Compose([ transforms.Resize((224, 224)), # transforms.Grayscale(3), # transforms.ColorJitter(cj, cj, cj, cj), #transforms.ColorJitter(0.4, 0.4, 0.4, 0.4), transforms.RandomHorizontalFlip(), transforms.RandomVerticalFlip(), transforms.RandomRotation(45), transforms.ToTensor(), normalize, ])) if args.distributed: train_sampler = torch.utils.data.distributed.DistributedSampler( train_dataset) elif args.balanced_sampling: print("Using balanced sampling") # Here's where we compute the weights for WeightedRandomSampler class_counts = {v: 0 for v in train_dataset.class_to_idx.values()} for path, ndx in train_dataset.samples: class_counts[ndx] += 1 total = float(np.sum([v for v in class_counts.values()])) class_probs = [ class_counts[ndx] / total for ndx in range(len(class_counts)) ] # make a list of class probabilities corresponding to the entries in train_dataset.samples reciprocal_weights = [ class_probs[idx] for i, (_, idx) in enumerate(train_dataset.samples) ] # weights are the reciprocal of the above weights = (1 / torch.Tensor(reciprocal_weights)) train_sampler = torch.utils.data.sampler.WeightedRandomSampler( weights, len(train_dataset), replacement=True) else: #if args.red_data is < 1, then the training is done with a subsamle of the total data. Otherwise it's the total data. data_size = len(train_dataset) sub_index = np.random.randint(0, data_size, round(args.red_data * data_size)) sub_index.sort() train_sampler = torch.utils.data.sampler.SubsetRandomSampler(sub_index) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None), num_workers=args.workers, pin_memory=True, sampler=train_sampler) print("Training on", len(train_dataset.imgs), "images. Training batch size:", args.batch_size) if len(train_dataset.imgs) % args.batch_size != 0: print( "Warning: batch size doesn't divide the # of training images so ", len(train_dataset.imgs) % args.batch_size, "images will be skipped per epoch.") print("If you don't want to skip images, use a batch size in:", get_factors(len(train_dataset.imgs))) val_dataset = datasets.ImageFolderInstance( valdir, transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), normalize, ])) val_bs = [ factor for factor in get_factors(len(val_dataset)) if factor < 500 ][-1] val_bs = 100 val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=val_bs, shuffle=False, num_workers=args.workers, pin_memory=True) print("Validating on", len(val_dataset), "images. Validation batch size:", val_bs) # define lemniscate and loss function (criterion) ndata = train_dataset.__len__() if args.nce_k > 0: lemniscate = NCEAverage(args.low_dim, ndata, args.nce_k, args.nce_t, args.nce_m) criterion = NCECriterion(ndata).cuda() else: lemniscate = LinearAverage(args.low_dim, ndata, args.nce_t, args.nce_m).cuda() criterion = nn.CrossEntropyLoss().cuda() optimizer = torch.optim.SGD(model.parameters(), args.lr, momentum=args.momentum, weight_decay=args.weight_decay) # optionally resume from a checkpoint if args.resume: if os.path.isfile(args.resume): print("=> loading checkpoint '{}'".format(args.resume)) checkpoint = torch.load(args.resume) model.load_state_dict(checkpoint['state_dict']) optimizer = FP16_Optimizer(optimizer, static_loss_scale=args.static_loss, verbose=False) optimizer.load_state_dict(checkpoint['optimizer']) args.start_epoch = checkpoint['epoch'] # best_prec1 = checkpoint['best_prec1'] lemniscate = checkpoint['lemniscate'] if args.select_load: pred = checkpoint['prediction'] print("=> loaded checkpoint '{}' (epoch {}, best_prec1 )".format( args.resume, checkpoint['epoch'])) #, checkpoint['best_prec1'])) else: print("=> no checkpoint found at '{}'".format(args.resume)) # optionally fine-tune a model trained on a different dataset elif args.fine_tune: print("=> loading checkpoint '{}'".format(args.fine_tune)) checkpoint = torch.load(args.fine_tune) model.load_state_dict(checkpoint['state_dict']) optimizer.load_state_dict(checkpoint['optimizer']) optimizer = FP16_Optimizer(optimizer, static_loss_scale=args.static_loss, verbose=False) print("=> loaded checkpoint '{}' (epoch {})".format( args.fine_tune, checkpoint['epoch'])) else: optimizer = FP16_Optimizer(optimizer, static_loss_scale=args.static_loss, verbose=False) # Optionally recompute memory. If fine-tuning, then we must recompute memory if args.recompute_memory or args.fine_tune: # Aaron - Experiments show that iterating over torch.utils.data.DataLoader will skip the last few # unless the batch size evenly divides size of the data set. This shouldn't be the case # according to documentation, there's even a flag for drop_last, but it's not working # compute a good batch size for re-computing memory memory_bs = [ factor for factor in get_factors(len(train_loader.dataset)) if factor < 500 ][-1] print("Recomputing memory using", train_dataset.root, "with a batch size of", memory_bs) transform_bak = train_loader.dataset.transform train_loader.dataset.transform = val_loader.dataset.transform temploader = torch.utils.data.DataLoader( train_loader.dataset, batch_size=memory_bs, shuffle=False, num_workers=train_loader.num_workers, pin_memory=True) lemniscate.memory = torch.zeros(len(train_loader.dataset), args.low_dim).cuda() model.eval() with torch.no_grad(): for batch_idx, (inputs, targets, indexes) in enumerate(tqdm.tqdm(temploader)): batchSize = inputs.size(0) features = model(inputs) lemniscate.memory[batch_idx * batchSize:batch_idx * batchSize + batchSize, :] = features.data train_loader.dataset.transform = transform_bak model.train() cudnn.benchmark = True if args.evaluate: kNN(model, lemniscate, train_loader, val_loader, args.K, args.nce_t) return begin_train_time = datetime.datetime.now() # my_knn(model, lemniscate, train_loader, val_loader, args.K, args.nce_t, train_dataset, val_dataset) if args.tsne: labels = idx_to_name(train_dataset, args.graph_labels) tsne(lemniscate, args.tsne, labels) if args.pca: labels = idx_to_name(train_dataset, args.graph_labels) pca(lemniscate, labels) if args.view_knn: my_knn(model, lemniscate, train_loader, val_loader, args.K, args.nce_t, train_dataset, val_dataset) if args.kmeans: kmeans, yi = kmean(lemniscate, args.kmeans, 500, args.K, train_dataset) D, I = kmeans.index.search(lemniscate.memory.data.cpu().numpy(), 1) cent_group = {} data_cent = {} for n, i in enumerate(I): if i[0] not in cent_group.keys(): cent_group[i[0]] = [] cent_group[i[0]].append(n) data_cent[n] = i[0] train_sampler = torch.utils.data.sampler.SubsetRandomSampler( cent_group[0]) train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None), num_workers=args.workers, pin_memory=True, sampler=train_sampler) # lemniscate = NCEAverage(args.low_dim, ndata, args.nce_k, args.nce_t, args.nce_m) # criterion = NCECriterion(ndata).cuda() # lemniscate = NCEAverage(args.low_dim, ndata, args.nce_k, args.nce_t, args.nce_m) if args.tsne_grid: tsne_grid(val_loader, model) if args.h_cluster: for size in range(2, 3): # size = 20 kmeans, topk = kmean(lemniscate, size, 500, 10, train_dataset) respred = torch.tensor([]).cuda() lab, idx = [[] for i in range(2)] num = 0 ''' for p,index,label in pred: respred = torch.cat((respred,p)) if num == 0: lab = label else: lab += label idx.append(index) num+=1 ''' h_cluster(lemniscate, train_dataset, kmeans, topk, size) #, respred, lab, idx) # axis_explore(lemniscate, train_dataset) # kmeans_opt(lemniscate, 5) if args.select: if not args.select_load: pred = [] if args.select_size: size = int(args.select_size * ndata) else: size = round(ndata / 100.0) sub_sample = np.random.randint(0, ndata, size=size) train_sampler = torch.utils.data.sampler.SubsetRandomSampler( sub_sample) train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None), num_workers=args.workers, pin_memory=True, sampler=train_sampler) pred = div_train(train_loader, model, 0, pred) pred_features = [] pred_labels = [] pred_idx = [] for inst in pred: feat, idx, lab = list(inst) pred_features.append(feat) pred_labels.append(lab) pred_idx.append(idx.data.cpu()) if args.select_save: save_checkpoint( { 'epoch': args.start_epoch, 'arch': args.arch, 'state_dict': model.state_dict(), 'prediction': pred, 'lemniscate': lemniscate, 'optimizer': optimizer.state_dict(), }, 'select.pth.tar') min_idx = selection(pred_features, pred_idx, train_dataset, args.select_num, args.select_thresh) train_sampler = torch.utils.data.sampler.SubsetRandomSampler(min_idx) train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None), num_workers=args.workers, pin_memory=True, sampler=train_sampler) lemniscate = NCEAverage(args.low_dim, ndata, 20, args.nce_t, args.nce_m) optimizer = torch.optim.SGD(model.parameters(), 0.1, momentum=0.1, weight_decay=0.00001) optimizer = FP16_Optimizer(optimizer, static_loss_scale=args.static_loss, verbose=False) for epoch in range(50): if args.distributed: train_sampler.set_epoch(epoch) adjust_learning_rate(optimizer, epoch) if epoch % 1 == 0: save_checkpoint({ 'epoch': epoch + 1, 'arch': args.arch, 'state_dict': model.state_dict(), 'lemniscate': lemniscate, 'optimizer': optimizer.state_dict(), }) train(train_loader, model, lemniscate, criterion, optimizer, epoch) train_sampler = torch.utils.data.sampler.SubsetRandomSampler(sub_index) train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None), num_workers=args.workers, pin_memory=True, sampler=train_sampler) lemniscate = NCEAverage(args.low_dim, ndata, args.nce_k, args.nce_t, args.nce_m) optimizer = torch.optim.SGD(model.parameters(), args.lr, momentum=args.momentum, weight_decay=args.weight_decay) optimizer = FP16_Optimizer(optimizer, static_loss_scale=args.static_loss, verbose=False) if args.kmeans_opt: kmeans_opt(lemniscate, 500) for epoch in range(args.start_epoch, args.epochs): if args.distributed: train_sampler.set_epoch(epoch) adjust_learning_rate(optimizer, epoch) if epoch % 1 == 0: # evaluate on validation set #prec1 = NN(epoch, model, lemniscate, train_loader, train_loader) # was evaluating on train # prec1 = kNN(model, lemniscate, train_loader, val_loader, args.K, args.nce_t) # prec1 really should be renamed to prec5 as kNN now returns top5 score, but # it won't be backward's compatible as earlier models were saved with "best_prec1" # remember best prec@1 and save checkpoint # is_best = prec1 > best_prec1 # best_prec1 = max(prec1, best_prec1) save_checkpoint({ 'epoch': epoch + 1, 'arch': args.arch, 'state_dict': model.state_dict(), 'lemniscate': lemniscate, # 'best_prec1': best_prec1, 'optimizer': optimizer.state_dict(), }) # , is_best) # train for one epoch train(train_loader, model, lemniscate, criterion, optimizer, epoch) # kmeans,cent = kmeans() # group_train(train_loader, model, lemniscate, criterion, optimizer, epoch, kmeans, cent) # print elapsed time end_train_time = datetime.datetime.now() d = end_train_time - begin_train_time print( "Trained for %d epochs. Elapsed time: %s days, %.2dh: %.2dm: %.2ds" % (len(range(args.start_epoch, args.epochs)), d.days, d.seconds // 3600, (d.seconds // 60) % 60, d.seconds % 60))
def main(args): # Data print('==> Preparing data..') _resize = 256 _size = 224 transform_train = transforms.Compose([ transforms.Resize(size=_resize), transforms.RandomResizedCrop(size=_size, scale=(0.2, 1.)), transforms.ColorJitter(0.4, 0.4, 0.4, 0.4), transforms.RandomGrayscale(p=0.2), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)), ]) transform_test = transforms.Compose([ transforms.Resize(size=_resize), transforms.CenterCrop(_size), ### transforms.ToTensor(), transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)), ]) trainset = datasets.ImageFolderInstance('/data2/zyf/ImageNet/ILSVRC2012-100/train', transform=transform_train, two_crop=True) trainloader = torch.utils.data.DataLoader(trainset, batch_size=args.batch_size, shuffle=True, num_workers=16) testset = datasets.ImageFolderInstance('/data2/zyf/ImageNet/ILSVRC2012-100/val', transform=transform_test) testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=16) classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck') ndata = trainset.__len__() print('trainset length: ' + str(ndata)) print('==> Building model..') # net = models.__dict__['ResNet18'](low_dim=args.low_dim) # net = models.__dict__['resnet18'](low_dim=args.low_dim) net = models.__dict__['alexnet'](out=args.low_dim) # net2 = models.__dict__['appendnet'](low_dim=args.low_dim) device = 'cuda' if torch.cuda.is_available() else 'cpu' if device == 'cuda': net = torch.nn.DataParallel(net, device_ids=range(torch.cuda.device_count())) # net2 = torch.nn.DataParallel(net2, device_ids=range(torch.cuda.device_count())) cudnn.benchmark = True # define loss function: inner product loss within each mini-batch # criterion = BatchCriterion(args.batch_m, args.batch_t, args.batch_size, ndata) criterion = ICRcriterion() # define loss function: inner product loss within each mini-batch uel_criterion = BatchCriterion(args.batch_m, args.batch_t, args.batch_size, ndata) net.to(device) # net2.to(device) criterion.to(device) uel_criterion.to(device) best_acc = 0 # best test accuracy start_epoch = 0 # start from epoch 0 or last checkpoint epoch cluster_ratio = args.cluster_ratio if args.test_only or len(args.resume) > 0: cluster_ratio = args.cluster_ratio # Load checkpoint. model_path = 'checkpoint/' + args.resume print('==> Resuming from checkpoint..') assert os.path.isdir(args.model_dir), 'Error: no checkpoint directory found!' checkpoint = torch.load(model_path) net.load_state_dict(checkpoint['net']) best_acc = checkpoint['acc'] start_epoch = checkpoint['epoch'] # define leminiscate if args.test_only and len(args.resume) > 0: trainFeatures, feature_index = compute_feature(trainloader, net, len(trainset), args) lemniscate = LinearAverage(torch.tensor(trainFeatures), args.low_dim, ndata, args.nce_t, args.nce_m) else: lemniscate = LinearAverage(torch.tensor([]), args.low_dim, ndata, args.nce_t, args.nce_m) lemniscate.to(device) # define optimizer optimizer = torch.optim.SGD(net.parameters(), lr=args.lr, momentum=0.9, weight_decay=5e-4) # optimizer2 = torch.optim.SGD(net2.parameters(), lr=args.lr, momentum=0.9, weight_decay=5e-4) # test acc if args.test_only: acc = kNN(0, net, trainloader, testloader, 200, args.batch_t, ndata, low_dim=args.low_dim) exit(0) if len(args.resume) > 0: best_acc = best_acc start_epoch = start_epoch + 1 else: best_acc = 0 # best test accuracy start_epoch = 0 # start from epoch 0 or last checkpoint epoch icr2 = ICRDiscovery(ndata) # init_cluster_num = 20000 for round in range(5): for epoch in range(start_epoch, 200): #### get Features # trainFeatures are trainloader features and shuffle=True, so feature_index is match data trainFeatures, feature_index = compute_feature(trainloader, net, len(trainset), args) if round == 0: y = -1 * math.log10(ndata-5) / 200 * epoch + math.log10(ndata-5) cluster_num = int(math.pow(10, y)) if cluster_num <= args.nmb_cluster: cluster_num = args.nmb_cluster print('cluster number: ' + str(cluster_num)) ###clustering algorithm to use # faiss cluster deepcluster = clustering.__dict__[args.clustering](int(cluster_num)) #### Features to clustering clustering_loss = deepcluster.cluster(trainFeatures, feature_index, verbose=args.verbose) L = np.array(deepcluster.images_lists) image_dict = deepcluster.images_dict print('create ICR ...') # icr = ICRDiscovery(ndata) # if args.test_only and len(args.resume) > 0: # icr = cluster_assign(icr, L, trainFeatures, feature_index, trainset, # cluster_ratio + epoch*((1-cluster_ratio)/250)) icrtime = time.time() # icr = cluster_assign(epoch, L, trainFeatures, feature_index, 1, 1) if epoch < args.warm_epoch: icr = cluster_assign(epoch, L, trainFeatures, feature_index, args.cluster_ratio, 1) else: icr = PreScore(epoch, L, image_dict, trainFeatures, feature_index, trainset, args.high_ratio, args.cluster_ratio, args.alpha, args.beta) print('calculate ICR time is: {}'.format(time.time() - icrtime)) writer.add_scalar('icr_time', (time.time() - icrtime), epoch + round * 200) else: cluster_num = args.nmb_cluster print('cluster number: ' + str(cluster_num)) ###clustering algorithm to use # faiss cluster deepcluster = clustering.__dict__[args.clustering](int(cluster_num)) #### Features to clustering clustering_loss = deepcluster.cluster(trainFeatures, feature_index, verbose=args.verbose) L = np.array(deepcluster.images_lists) image_dict = deepcluster.images_dict print('create ICR ...') # icr = ICRDiscovery(ndata) # if args.test_only and len(args.resume) > 0: # icr = cluster_assign(icr, L, trainFeatures, feature_index, trainset, # cluster_ratio + epoch*((1-cluster_ratio)/250)) icrtime = time.time() # icr = cluster_assign(epoch, L, trainFeatures, feature_index, 1, 1) icr = PreScore(epoch, L, image_dict, trainFeatures, feature_index, trainset, args.high_ratio, args.cluster_ratio, args.alpha, args.beta) print('calculate ICR time is: {}'.format(time.time() - icrtime)) writer.add_scalar('icr_time', (time.time() - icrtime), epoch + round * 200) # else: # icr = cluster_assign(icr, L, trainFeatures, feature_index, trainset, 0.2 + epoch*0.004) # print(icr.neighbours) icr2 = train(epoch, net, optimizer, lemniscate, criterion, uel_criterion, trainloader, icr, icr2, args.stage_update, args.lr, device, round) print('----------Evaluation---------') start = time.time() acc = kNN(0, net, trainloader, testloader, 200, args.batch_t, ndata, low_dim=args.low_dim) print("Evaluation Time: '{}'s".format(time.time() - start)) writer.add_scalar('nn_acc', acc, epoch + round * 200) if acc > best_acc: print('Saving..') state = { 'net': net.state_dict(), 'acc': acc, 'epoch': epoch, } if not os.path.isdir(args.model_dir): os.mkdir(args.model_dir) torch.save(state, './checkpoint/ckpt_best_round_{}.t7'.format(round)) if epoch < 200: torch.save(state, './checkpoint/ckpt_200_best_round_{}.t7'.format(round)) if epoch < 300: torch.save(state, './checkpoint/ckpt_300_best_round_{}.t7'.format(round)) best_acc = acc state = { 'net': net.state_dict(), 'acc': acc, 'epoch': epoch, } if epoch < 200: torch.save(state, './checkpoint/ckpt_200_last_round_{}.t7'.format(round)) else: torch.save(state, './checkpoint/ckpt_last_round_{}.t7'.format(round)) if epoch < 300: torch.save(state, './checkpoint/ckpt_300_last_round_{}.t7'.format(round)) print('[Round]: {} [Epoch]: {} \t accuracy: {}% \t (best acc: {}%)'.format(round, epoch, acc, best_acc))
def main(): global args, best_prec1 args = parser.parse_args() print(args) # create model if args.pretrained: print("=> using pre-trained model '{}'".format(args.arch)) model = models.__dict__[args.arch](pretrained=True) else: print("=> creating model '{}'".format(args.arch)) model = models.__dict__[args.arch](low_dim=args.low_dim) if args.arch.startswith('alexnet') or args.arch.startswith('vgg'): model.features = torch.nn.DataParallel(model.features) model.cuda() else: model = torch.nn.DataParallel(model).cuda() # Data loading code traindir = os.path.join(args.data, 'train') valdir = os.path.join(args.data, 'val') normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) train_dataset = datasets.ImageFolderInstance( traindir, transforms.Compose([ transforms.RandomResizedCrop(224, scale=(0.2, 1.)), transforms.RandomGrayscale(p=0.2), transforms.ColorJitter(0.4, 0.4, 0.4, 0.4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), normalize, ])) train_labels = torch.tensor(train_dataset.targets).long().cuda() train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=args.batch_size, shuffle=True, num_workers=args.workers, pin_memory=True, sampler=None) val_loader = torch.utils.data.DataLoader(datasets.ImageFolderInstance( valdir, transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), normalize, ])), batch_size=args.batch_size, shuffle=False, num_workers=args.workers, pin_memory=True) # define lemniscate and loss function (criterion) ndata = train_dataset.__len__() lemniscate = LinearAverage(args.low_dim, ndata, args.nce_t, args.nce_m).cuda() rlb = ReliableSearch(ndata, args.low_dim, args.threshold_1, args.threshold_2, args.batch_size).cuda() criterion = ReliableCrossEntropyLoss().cuda() optimizer = torch.optim.SGD(model.parameters(), args.lr, momentum=args.momentum, weight_decay=args.weight_decay) # optionally resume from a checkpoint if args.resume: if os.path.isfile(args.resume): print("=> loading checkpoint '{}'".format(args.resume)) checkpoint = torch.load(args.resume) args.start_epoch = 0 best_prec1 = checkpoint['best_prec1'] model.load_state_dict(checkpoint['state_dict']) lemniscate = checkpoint['lemniscate'] optimizer.load_state_dict(checkpoint['optimizer']) print("=> loaded checkpoint '{}' (epoch {})".format( args.resume, checkpoint['epoch'])) else: print("=> no checkpoint found at '{}'".format(args.resume)) cudnn.benchmark = True if args.evaluate: kNN(0, model, lemniscate, train_loader, val_loader, 200, args.nce_t) return for rnd in range(args.start_round, args.rounds): if rnd > 0: memory = recompute_memory(model, lemniscate, train_loader, val_loader, args.batch_size, args.workers) num_reliable_1, consistency_1, num_reliable_2, consistency_2 = rlb.update( memory, train_labels) print( 'Round [%02d/%02d]\tReliable1: %.12f\tReliable2: %.12f\tConsistency1: %.12f\tConsistency2: %.12f' % (rnd, args.rounds, num_reliable_1, num_reliable_2, consistency_1, consistency_2)) for epoch in range(args.start_epoch, args.epochs): adjust_learning_rate(optimizer, epoch) # train for one epoch train(train_loader, model, lemniscate, rlb, criterion, optimizer, epoch) # evaluate on validation set prec1 = NN(epoch, model, lemniscate, train_loader, val_loader) # remember best prec@1 and save checkpoint is_best = prec1 > best_prec1 best_prec1 = max(prec1, best_prec1) save_checkpoint( { 'epoch': epoch + 1, 'arch': args.arch, 'state_dict': model.state_dict(), 'lemniscate': lemniscate, 'best_prec1': best_prec1, 'optimizer': optimizer.state_dict(), #}, is_best, filename='ckpts/%02d-%04d-checkpoint.pth.tar'%(rnd+1, epoch + 1)) }, is_best) save_checkpoint( { 'epoch': epoch + 1, 'arch': args.arch, 'state_dict': model.state_dict(), 'lemniscate': lemniscate, 'best_prec1': best_prec1, 'optimizer': optimizer.state_dict(), }, is_best=False, filename='ckpts/%02d-checkpoint.pth.tar' % (rnd + 1)) # evaluate KNN after last epoch top1, top5 = kNN(0, model, lemniscate, train_loader, val_loader, 200, args.nce_t) print('Round [%02d/%02d]\tTop1: %.2f\tTop5: %.2f' % (rnd + 1, args.rounds, top1, top5))