예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
 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
예제 #4
0
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))
예제 #5
0
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
예제 #6
0
    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)
예제 #7
0
    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()
예제 #8
0
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))
예제 #9
0
                        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)
예제 #10
0
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))