def init(root): image_paths = pd.read_csv(os.path.join(root, 'images.txt'), sep=' ', names=['img_id', 'filepath']) image_class_labels = pd.read_csv(os.path.join( root, 'image_class_labels.txt'), sep=' ', names=['img_id', 'target']) label_map = get_continuous_class_map(image_class_labels['target']) train_test_split = pd.read_csv(os.path.join(root, 'train_test_split.txt'), sep=' ', names=['img_id', 'is_training_img']) data = image_paths.merge(image_class_labels, on='img_id') all_data = data.merge(train_test_split, on='img_id') all_data['filepath'] = 'images/' + all_data['filepath'] all_data['target'] = all_data['target'].apply(lambda x: label_map[x]) train_data = all_data[all_data['is_training_img'] == 1] test_data = all_data[all_data['is_training_img'] == 0].iloc[ 5001:10551, :] # test_data = all_data[all_data['is_training_img'] == 0] class_num = len(label_map) # Load in the train / test split NABirds.QUERY_DATA = test_data['filepath'].to_numpy() NABirds.QUERY_TARGETS = encode_onehot((test_data['target']).tolist(), class_num) NABirds.TRAIN_DATA = train_data['filepath'].to_numpy() NABirds.TRAIN_TARGETS = encode_onehot((train_data['target']).tolist(), class_num) NABirds.RETRIEVAL_DATA = train_data['filepath'].to_numpy() NABirds.RETRIEVAL_TARGETS = encode_onehot( (train_data['target']).tolist(), class_num)
def init(root): images = pd.read_csv(os.path.join(root, 'images.txt'), sep=' ', names=['img_id', 'filepath']) image_class_labels = pd.read_csv(os.path.join( root, 'image_class_labels.txt'), sep=' ', names=['img_id', 'target']) train_test_split = pd.read_csv(os.path.join(root, 'train_test_split.txt'), sep=' ', names=['img_id', 'is_training_img']) data = images.merge(image_class_labels, on='img_id') all_data = data.merge(train_test_split, on='img_id') all_data['filepath'] = 'images/' + all_data['filepath'] train_data = all_data[all_data['is_training_img'] == 1] test_data = all_data[all_data['is_training_img'] == 0] # Split dataset Cub2011.QUERY_DATA = test_data['filepath'].to_numpy() Cub2011.QUERY_TARGETS = encode_onehot( (test_data['target'] - 1).tolist(), 200) Cub2011.TRAIN_DATA = train_data['filepath'].to_numpy() Cub2011.TRAIN_TARGETS = encode_onehot( (train_data['target'] - 1).tolist(), 200) Cub2011.RETRIEVAL_DATA = train_data['filepath'].to_numpy() Cub2011.RETRIEVAL_TARGETS = encode_onehot( (train_data['target'] - 1).tolist(), 200)
def __init__(self, data, targets, root, dataset): self.data = data self.targets = targets self.root = root self.transform = train_transform() self.dataset = dataset if dataset == 'cifar-10': self.onehot_targets = encode_onehot(self.targets, 10) elif dataset == 'imagenet-tc100': self.onehot_targets = encode_onehot(self.targets, 100) else: self.onehot_targets = self.targets
def run_hcoh(args): """Run HCOH algorithm Parameters args: parser Configuration Returns None """ # Load dataset train_data, train_targets, query_data, query_targets, database_data, database_targets = dataloader.load_data(args) # Preprocess dataset # Normalization train_data = normalization(train_data) query_data = normalization(query_data) database_data = normalization(database_data) # One-hot query_targets = encode_onehot(query_targets, 10) database_targets = encode_onehot(database_targets, 10) # Convert to Tensor train_data = torch.from_numpy(train_data).float().to(args.device) query_data = torch.from_numpy(query_data).float().to(args.device) database_data = torch.from_numpy(database_data).float().to(args.device) train_targets = torch.from_numpy(train_targets).squeeze().to(args.device) query_targets = torch.from_numpy(query_targets).to(args.device) database_targets = torch.from_numpy(database_targets).to(args.device) # HCOH algorithm for code_length in [8, 16, 32, 64, 128]: args.code_length = code_length mAP = 0.0 precision = 0.0 for i in range(10): m, p = HCOH.hcoh( train_data, train_targets, query_data, query_targets, database_data, database_targets, args.code_length, args.lr, args.num_hadamard, args.device, args.topk, ) mAP += m precision += p logger.info('[code_length:{}][map:{:.3f}][precision:{:.3f}]'.format(code_length, mAP / 10, precision / 10))
def evaluate( model, query_dataloader, train_labels, B, opt, ): """评估算法 Parameters model: model 学得的CNN模型 query_dataloader: DataLoader 测试数据 train_labels: Tensor 训练标签 B: ndarray 学到的hash code opt: Parser 参数 Returns meanAP: float mean Average precision """ model.eval() # CNN作为out-of-sampling extension query_code = generate_code(model, query_dataloader, opt).to(opt.device) # query labels if opt.dataset == 'cifar10': query_labels = torch.FloatTensor( encode_onehot(query_dataloader.dataset.targets)).to(opt.device) elif opt.dataset == 'nus-wide': query_labels = torch.FloatTensor(query_dataloader.dataset.tags).to( opt.device) # 计算map meanAP = calc_map( query_code, B, query_labels, train_labels, opt.device, opt.topk, ) return meanAP
def __init__(self, mode='train', transform=None, target_transform=None, ): self.transform = transform self.target_transform = target_transform if mode == 'train': self.data = CIFAR10.TRAIN_IMG self.targets = CIFAR10.TRAIN_TARGET elif mode == 'query': self.data = CIFAR10.QUERY_IMG self.targets = CIFAR10.QUERY_TARGET else: self.data = CIFAR10.RETRIEVAL_IMG self.targets = CIFAR10.RETRIEVAL_TARGET self.onehot_targets = encode_onehot(self.targets, 10)
def __init__(self, root, transform=None, target_transform=None): self.root = root self.transform = transform self.target_transform = target_transform self.imgs = [] self.targets = [] # Assume file alphabet order is the class order if ImagenetDataset.class_to_idx is None: ImagenetDataset.classes, ImagenetDataset.class_to_idx = self._find_classes( root) for i, cl in enumerate(ImagenetDataset.classes): cur_class = os.path.join(self.root, cl) files = os.listdir(cur_class) files = [os.path.join(cur_class, i) for i in files] self.imgs.extend(files) self.targets.extend( [ImagenetDataset.class_to_idx[cl] for i in range(len(files))]) self.targets = torch.tensor(self.targets) self.onehot_targets = torch.from_numpy(encode_onehot( self.targets, 100)).float()
def run_dsdh(opt): """Run DSDH algorithm Parameters opt: parser Configuration Returns None """ # Load data query_dataloader, train_dataloader, database_dataloader = dataloader.load_data( opt) # onehot targets if opt.dataset == 'cifar10': query_targets = torch.FloatTensor( encode_onehot(query_dataloader.dataset.targets)).to(opt.device) train_targets = torch.FloatTensor( encode_onehot(train_dataloader.dataset.targets)).to(opt.device) database_targets = torch.FloatTensor( encode_onehot(database_dataloader.dataset.targets)).to(opt.device) elif opt.dataset == 'nus-wide': query_targets = torch.FloatTensor(query_dataloader.dataset.targets).to( opt.device) train_targets = torch.FloatTensor(train_dataloader.dataset.targets).to( opt.device) database_targets = torch.FloatTensor( database_dataloader.dataset.targets).to(opt.device) cl = [12, 24, 32, 48] for c in cl: opt.code_length = c # DSDH algorithm logger.info(opt) best_model = DSDH.dsdh( train_dataloader, query_dataloader, train_targets, query_targets, opt.code_length, opt.max_iter, opt.dcc_iter, opt.mu, opt.nu, opt.eta, opt.model, opt.multi_gpu, opt.device, opt.lr, opt.evaluate_freq, opt.topk, ) # Evaluate whole dataset model = torch.load(os.path.join('result', best_model)) final_map = evaluate( model, query_dataloader, database_dataloader, query_targets, database_targets, opt.code_length, opt.device, opt.topk, ) logger.info('final_map: {:.4f}'.format(final_map))
default=5000, type=int, help='Compute map of top k (default: 5000)') parser.add_argument('--evaluate-freq', default=1, type=int, help='Frequency of evaluate (default: 1)') return parser.parse_args() if __name__ == '__main__': opt = load_parse() if opt.gpu == -1: opt.device = torch.device("cpu") else: opt.device = torch.device("cuda:%d" % opt.gpu) # Load data query_dataloader, train_dataloader, database_dataloader = load_data(opt) # onehot targets if opt.dataset == 'cifar10': query_targets = torch.FloatTensor( encode_onehot(query_dataloader.dataset.targets)).to(opt.device) train_targets = torch.FloatTensor( encode_onehot(train_dataloader.dataset.targets)).to(opt.device) database_targets = torch.FloatTensor( encode_onehot(database_dataloader.dataset.targets)).to(opt.device) train(opt, query_dataloader, train_dataloader, database_dataloader, query_targets, train_targets, database_targets)
def dpsh( opt, train_dataloader, query_dataloader, database_dataloader, ): """DPSH_PyTorch algorithm Parameters opt: Parser 配置 train_dataloader: DataLoader 训练数据 query_data: DataLoader 查询数据 database_dataloader: DataLoader 整个数据集数据 Returns None """ # 标签onehot处理 if opt.dataset == 'cifar10': train_labels = torch.FloatTensor( encode_onehot(train_dataloader.dataset.targets)).to(opt.device) elif opt.dataset == 'nus-wide': train_labels = torch.FLoatTensor(train_dataloader.dataset.tags).to( opt.device) # 定义网络,optimizer,loss model = modelloader.load_model(opt.model, num_classes=opt.code_length) if opt.multi_gpu: model = torch.nn.DataParallel(model) model.to(opt.device) criterion = dlfh_loss.DLFHLoss(opt.eta) # 不知道为什么,加momentum无法收敛!!! # 不知道为什么,SGD不用zeros初始化U无法收敛!!! optimizer = optim.RMSprop( model.parameters(), lr=opt.lr, weight_decay=10**-5, ) scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.1) # 初始化 N = len(train_dataloader.dataset) B = torch.zeros(N, opt.code_length).to(opt.device) U = torch.zeros(N, opt.code_length).to(opt.device) logger.info('B\'s shape is {}'.format(B.shape)) # 算法开始 best_map = 0.0 last_model = None for epoch in range(opt.epochs): scheduler.step() # CNN total_loss = 0.0 model.train() for data, labels, index in tqdm(train_dataloader): data = data.to(opt.device) labels = labels.to(opt.device) optimizer.zero_grad() S = (labels @ train_labels.t() > 0).float() outputs = model(data) # tensor.data:输出结果不放入计算图中,也就是不参与梯度计算 U[index, :] = outputs.data # tensor.clone():返回跟原数据相同大小类型的tensor B[index, :] = outputs.clone().sign() loss = criterion(S, outputs, U) # loss = criterion(outputs, labels) loss.backward() optimizer.step() total_loss += loss.item() if epoch % opt.evaluate_freq == opt.evaluate_freq - 1: meanAP = evaluate(model, query_dataloader, train_labels, B, opt) # 保存当前最好结果 if best_map < meanAP: if last_model: os.remove(os.path.join('result', last_model)) best_map = meanAP last_model = 'model_{:.4f}.t'.format(best_map) torch.save(model, os.path.join('result', last_model)) logger.info( 'code_length: {}, epoch: {}, lr: {}, loss: {:.4f}, map: {:.4f}' .format(opt.code_length, epoch + 1, scheduler.get_lr(), total_loss, meanAP)) # 加载性能最好模型,对整个数据集产生hash code进行evaluate model = torch.load(os.path.join('result', last_model)) database_code = generate_code(model, database_dataloader, opt).to(opt.device) if opt.dataset == 'cifar10': database_labels = torch.FloatTensor( encode_onehot(database_dataloader.dataset.targets)).to(opt.device) elif opt.dataset == 'nus-wide': database_labels = torch.FloatTensor( database_dataloader.dataset.tags).to(opt.device) final_map = evaluate( model, query_dataloader, database_labels, database_code, opt, ) logger.info('code_length: {}, final_map: {:.4f}'.format( opt.code_length, final_map))