Пример #1
0
def get_data(data_dir,
             source,
             target,
             height,
             width,
             batch_size,
             triplet_batch_size,
             num_instances,
             target_batch_size,
             re=0,
             workers=8):

    dataset = DA(data_dir, source, target)

    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])

    num_classes = dataset.num_train_ids

    train_transformer = T.Compose([
        T.RandomSizedRectCrop(height, width),
        T.RandomHorizontalFlip(),
        T.ToTensor(),
        normalizer,
        T.RandomErasing(EPSILON=re),
    ])

    test_transformer = T.Compose([
        T.Resize((height, width), interpolation=3),
        T.ToTensor(),
        normalizer,
    ])

    source_train_loader = DataLoader(Preprocessor(
        dataset.source_train,
        root=osp.join(dataset.source_images_dir, dataset.source_train_path),
        transform=train_transformer),
                                     batch_size=batch_size,
                                     num_workers=workers,
                                     shuffle=True,
                                     pin_memory=True,
                                     drop_last=True)

    source_triplet_train_loader = DataLoader(
        Preprocessor(dataset.source_train,
                     root=osp.join(dataset.source_images_dir,
                                   dataset.source_train_path),
                     transform=train_transformer),
        batch_size=triplet_batch_size,
        num_workers=workers,
        sampler=RandomIdentitySampler(dataset.source_train, num_instances),
        pin_memory=True,
        drop_last=True)

    target_train_loader = DataLoader(CameraPreprocessor(
        dataset.target_train,
        root=dataset.target_images_dir,
        target_path=dataset.target_train_path,
        target_camstyle_path=dataset.target_train_camstyle_path,
        transform=train_transformer,
        num_cam=dataset.target_num_cam),
                                     batch_size=target_batch_size,
                                     num_workers=workers,
                                     shuffle=True,
                                     pin_memory=True,
                                     drop_last=True)

    query_loader = DataLoader(Preprocessor(dataset.query,
                                           root=osp.join(
                                               dataset.target_images_dir,
                                               dataset.query_path),
                                           transform=test_transformer),
                              batch_size=batch_size,
                              num_workers=workers,
                              shuffle=False,
                              pin_memory=True)

    gallery_loader = DataLoader(Preprocessor(dataset.gallery,
                                             root=osp.join(
                                                 dataset.target_images_dir,
                                                 dataset.gallery_path),
                                             transform=test_transformer),
                                batch_size=batch_size,
                                num_workers=workers,
                                shuffle=False,
                                pin_memory=True)

    return dataset, num_classes, source_train_loader, source_triplet_train_loader, target_train_loader, query_loader, gallery_loader
Пример #2
0
def main(args):
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    cudnn.benchmark = True

    # Create data loaders
    assert args.num_instances > 1, "num_instances should be greater than 1"
    assert args.batch_size % args.num_instances == 0, \
        'num_instances should divide batch_size'
    if args.height is None or args.width is None:
        args.height, args.width = (144, 56) if args.arch == 'inception' else \
            (256, 128)

    # get source data
    src_dataset, src_extfeat_loader = \
        get_source_data(args.src_dataset, args.data_dir, args.height,
                        args.width, args.batch_size, args.workers)
    # get target data
    tgt_dataset, num_classes, tgt_extfeat_loader, test_loader = \
        get_data(args.tgt_dataset, args.data_dir, args.height,
                 args.width, args.batch_size, args.workers)

    # Create model
    # Hacking here to let the classifier be the number of source ids
    if args.src_dataset == 'dukemtmc':
        model = models.create(args.arch, num_classes=632, pretrained=False)
    elif args.src_dataset == 'market1501':
        model = models.create(args.arch, num_classes=676, pretrained=False)
    elif args.src_dataset == 'msmt17':
        model = models.create(args.arch, num_classes=1041, pretrained=False)
    elif args.src_dataset == 'cuhk03':
        model = models.create(args.arch, num_classes=1230, pretrained=False)
    else:
        raise RuntimeError(
            'Please specify the number of classes (ids) of the network.')

    # Load from checkpoint
    if args.resume:
        print(
            'Resuming checkpoints from finetuned model on another dataset...\n'
        )
        checkpoint = load_checkpoint(args.resume)
        model.load_state_dict(checkpoint['state_dict'], strict=False)
    else:
        raise RuntimeWarning('Not using a pre-trained model.')
    model = nn.DataParallel(model).cuda()

    evaluator = Evaluator(model, print_freq=args.print_freq)
    evaluator.evaluate(test_loader, tgt_dataset.query, tgt_dataset.gallery)
    # if args.evaluate: return

    # Criterion
    criterion = [
        HoughTripletLoss(args.margin,
                         args.num_instances,
                         isAvg=False,
                         use_semi=False).cuda(),
        HoughTripletLoss(args.margin,
                         args.num_instances,
                         isAvg=False,
                         use_semi=False).cuda()
    ]

    # Optimizer
    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)

    # training stage transformer on input images
    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])
    train_transformer = T.Compose([
        T.Resize((args.height, args.width)),
        T.RandomHorizontalFlip(),
        T.ToTensor(), normalizer,
        T.RandomErasing(probability=0.5, sh=0.2, r1=0.3)
    ])

    # # Start training
    for iter_n in range(args.iteration):
        if args.lambda_value == 0:
            source_features = 0
        else:
            # get source datas' feature
            source_features, _ = extract_features(model,
                                                  src_extfeat_loader,
                                                  print_freq=args.print_freq)
            # synchronization feature order with src_dataset.train
            source_features = torch.cat([
                source_features[f].unsqueeze(0)
                for f, _, _, _ in src_dataset.train
            ], 0)

            # extract training images' features
        print('Iteration {}: Extracting Target Dataset Features...'.format(
            iter_n + 1))
        target_features, _ = extract_features(model,
                                              tgt_extfeat_loader,
                                              print_freq=args.print_freq)
        # synchronization feature order with dataset.train
        target_features = torch.cat([
            target_features[f].unsqueeze(0)
            for f, _, _, _ in tgt_dataset.trainval
        ], 0)
        # calculate distance and rerank result
        print('Calculating feature distances...')
        target_features = target_features.numpy()
        rerank_dist = re_ranking(source_features,
                                 target_features,
                                 lambda_value=args.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(args.rho * tri_mat.size).astype(int)
            eps = tri_mat[:top_num].mean()
            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)
        num_ids = len(set(labels)) - 1
        print('Iteration {} have {} training ids'.format(iter_n + 1, num_ids))
        # generate new dataset
        new_dataset, unknown_dataset = [], []
        # assign label for target ones
        unknownLab = labelNoise(torch.from_numpy(target_features),
                                torch.from_numpy(labels))
        # unknownFeats = target_features[labels==-1,:]
        unCounter, index = 0, 0
        from collections import defaultdict
        realIDs, fakeIDs = defaultdict(list), []
        record_labels = {}
        hough = Hough(8, 40, 230, 2935, 25, args.short_cut)
        for (fname, realPID, cam,
             timestamp), label in zip(tgt_dataset.trainval, labels):
            if label == -1:
                unknown_dataset.append((fname, int(unknownLab[unCounter]), cam,
                                        timestamp))  # unknown data
                fakeIDs.append(int(unknownLab[unCounter]))
                realIDs[realPID].append(index)
                unCounter += 1
                index += 1
                continue
            # dont need to change codes in trainer.py _parsing_input function and sampler function after add 0
            if label not in record_labels:
                record_labels[label] = []
            for index2 in record_labels[label]:
                hough.update(cam, tgt_dataset.trainval[index2][2], timestamp,
                             tgt_dataset.trainval[index2][3])
            record_labels[label].append(index)
            new_dataset.append((fname, label, cam, timestamp))
            fakeIDs.append(label)
            realIDs[realPID].append(index)
            index += 1
        print('Iteration {} have {} training images'.format(
            iter_n + 1, len(new_dataset)))
        precision, recall, fscore = calScores(
            realIDs, np.asarray(fakeIDs))  # fakeIDs does not contain -1
        print('precision:{}, recall:{}, fscore: {}'.format(
            100 * precision, 100 * recall, fscore))

        T_pseu, TP_pseu, T_gt, TP_gt, index = (0, 0, 0, 0, -1)
        for (fname, realPID, cam,
             timestamp), label in zip(tgt_dataset.trainval, labels):
            index += 1

            # calc by gt label
            T_gt = T_gt + len(realIDs[realPID]) - 1
            for index2 in realIDs[realPID]:
                if index2 == index: continue
                if hough.on_peak(cam, tgt_dataset.trainval[index2][2],
                                 timestamp, tgt_dataset.trainval[index2][3]):
                    TP_gt += 1

            # calc by pseudo label
            if label == -1: continue
            T_pseu = T_pseu + len(record_labels[label]) - 1
            for index2 in record_labels[label]:
                if index2 == index: continue
                if hough.on_peak(cam, tgt_dataset.trainval[index2][2],
                                 timestamp, tgt_dataset.trainval[index2][3]):
                    TP_pseu += 1

        print('gt label: T = %d, TP = %d, recall = %f' %
              (T_gt, TP_gt, TP_pseu / T_gt))
        print('pseudo label: T = %d, TP = %d, recall = %f' %
              (T_pseu, TP_pseu, TP_pseu / T_pseu))

        train_loader = DataLoader(Preprocessor(new_dataset,
                                               root=tgt_dataset.images_dir,
                                               transform=train_transformer),
                                  batch_size=args.batch_size,
                                  num_workers=4,
                                  sampler=RandomIdentitySampler(
                                      new_dataset, args.num_instances),
                                  pin_memory=True,
                                  drop_last=True)
        # hard samples
        # noiseImgs = [name[1] for name in unknown_dataset]
        # saveAll(noiseImgs, tgt_dataset.images_dir, 'noiseImg')
        # import ipdb; ipdb.set_trace()
        unLoader = DataLoader(Preprocessor(unknown_dataset,
                                           root=tgt_dataset.images_dir,
                                           transform=train_transformer),
                              batch_size=args.batch_size,
                              num_workers=4,
                              sampler=RandomIdentitySampler(
                                  unknown_dataset, args.num_instances),
                              pin_memory=True,
                              drop_last=True)
        # train model with new generated dataset
        trainer1 = HoughTrainer(model, hough, train_loader, criterion,
                                optimizer)
        trainer2 = HoughTrainer(model, hough, unLoader, criterion, optimizer)

        # Start training
        for epoch in range(args.epochs):
            trainer1.train(epoch)
            trainer2.train(epoch)

        # test only
        rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                        tgt_dataset.gallery)
        # print('co-model:\n')
        # rank_score = evaluatorB.evaluate(test_loader, tgt_dataset.query, tgt_dataset.gallery)

    # Evaluate
    rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                    tgt_dataset.gallery)
    save_checkpoint(
        {
            'state_dict': model.module.state_dict(),
            'epoch': epoch + 1,
            'best_top1': rank_score.market1501[0],
        },
        True,
        fpath=osp.join(args.logs_dir, 'asyCo.pth'))
    return rank_score.map, rank_score.market1501[0]
def get_data(name,
             split_id,
             data_dir,
             height,
             width,
             batch_size,
             num_instances,
             workers,
             combine_trainval,
             eval_rerank=False):
    ## Datasets
    if name == 'cuhk03labeled':
        dataset_name = 'cuhk03'
        dataset = data_manager.init_imgreid_dataset(
            root=data_dir,
            name=dataset_name,
            split_id=split_id,
            cuhk03_labeled=True,
            cuhk03_classic_split=False,
        )
        dataset.images_dir = osp.join(data_dir, '/CUHK03_New/images_labeled/')
    elif name == 'cuhk03detected':
        dataset_name = 'cuhk03'
        dataset = data_manager.init_imgreid_dataset(
            root=data_dir,
            name=dataset_name,
            split_id=split_id,
            cuhk03_labeled=False,
            cuhk03_classic_split=False,
        )
        dataset.images_dir = osp.join(data_dir, '/CUHK03_New/images_detected/')
    ## Num. of training IDs
    num_classes = dataset.num_train_pids

    train_transformer = T.Compose([
        T.Random2DTranslation(height, width),
        T.RandomHorizontalFlip(),
        T.ToTensor(),
    ])

    test_transformer = T.Compose([
        T.RectScale(height, width),
        T.ToTensor(),
    ])

    train_loader = DataLoader(Preprocessor(dataset.train,
                                           root=dataset.images_dir,
                                           transform=train_transformer),
                              batch_size=batch_size,
                              num_workers=workers,
                              sampler=RandomIdentitySampler(
                                  dataset.train, num_instances),
                              pin_memory=True,
                              drop_last=True)

    query_loader = DataLoader(Preprocessor(dataset.query,
                                           root=dataset.images_dir,
                                           transform=test_transformer),
                              batch_size=batch_size,
                              num_workers=workers,
                              shuffle=False,
                              pin_memory=True)

    gallery_loader = DataLoader(Preprocessor(dataset.gallery,
                                             root=dataset.images_dir,
                                             transform=test_transformer),
                                batch_size=batch_size,
                                num_workers=workers,
                                shuffle=False,
                                pin_memory=True)

    return dataset, num_classes, train_loader, query_loader, gallery_loader
Пример #4
0
def get_data(name, split_id, data_dir, height, width, batch_size,
             num_instances, workers, combine_trainval, flip_prob, padding,
             re_prob):
    root = osp.join(data_dir, name)
    print(root)
    dataset = datasets.create(name, root, split_id=split_id)

    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])

    trainvallabel = dataset.trainvallabel
    train_set = dataset.trainval if combine_trainval else dataset.train
    num_classes = (dataset.num_trainval_ids
                   if combine_trainval else dataset.num_train_ids)

    train_transformer = T.Compose([
        T.Resize((height, width)),
        T.RandomHorizontalFlip(),
        T.Pad(padding),
        T.RandomCrop((height, width)),
        T.ToTensor(), normalizer,
        RandomErasing(probability=re_prob, mean=[0.485, 0.456, 0.406])
    ])

    # train_transformer = T.Compose([
    #     T.RandomSizedRectCrop(height, width),
    #     T.RandomHorizontalFlip(),
    #     T.ToTensor(),
    #     normalizer,
    # ])

    test_transformer = T.Compose([
        T.Resize((height, width)),
        T.ToTensor(),
        normalizer,
    ])

    val_loader = DataLoader(Preprocessor(dataset.val,
                                         root=dataset.images_dir,
                                         transform=test_transformer),
                            batch_size=32,
                            num_workers=workers,
                            shuffle=False,
                            pin_memory=True)

    query_loader = DataLoader(Preprocessor(list(set(dataset.query)),
                                           root=dataset.images_dir,
                                           transform=test_transformer),
                              batch_size=32,
                              num_workers=workers,
                              sampler=CamSampler(list(set(dataset.query)),
                                                 [2, 5]),
                              shuffle=False,
                              pin_memory=True)

    gallery_loader = DataLoader(Preprocessor(list(set(dataset.gallery)),
                                             root=dataset.images_dir,
                                             transform=test_transformer),
                                batch_size=32,
                                num_workers=workers,
                                sampler=CamSampler(list(set(dataset.gallery)),
                                                   [0, 1, 3, 4], 4),
                                shuffle=False,
                                pin_memory=True)

    train_loader = DataLoader(Preprocessor(train_set,
                                           root=dataset.images_dir,
                                           transform=train_transformer),
                              batch_size=batch_size,
                              num_workers=workers,
                              sampler=RandomIdentitySampler(
                                  train_set, num_instances),
                              pin_memory=True,
                              drop_last=True)

    query_loader_rgb = DataLoader(Preprocessor(list(set(dataset.query)),
                                               root=dataset.images_dir,
                                               transform=test_transformer),
                                  batch_size=32,
                                  num_workers=workers,
                                  sampler=CamSampler(list(set(dataset.query)),
                                                     [0, 1, 3, 4]),
                                  shuffle=False,
                                  pin_memory=True)

    gallery_loader_rgb = DataLoader(Preprocessor(list(set(dataset.gallery)),
                                                 root=dataset.images_dir,
                                                 transform=test_transformer),
                                    batch_size=32,
                                    num_workers=workers,
                                    sampler=CamSampler(
                                        list(set(dataset.gallery)),
                                        [0, 1, 3, 4], 4),
                                    shuffle=False,
                                    pin_memory=True)

    query_loader_ir = DataLoader(Preprocessor(list(set(dataset.query)),
                                              root=dataset.images_dir,
                                              transform=test_transformer),
                                 batch_size=32,
                                 num_workers=workers,
                                 sampler=CamSampler(list(set(dataset.query)),
                                                    [2, 5]),
                                 shuffle=False,
                                 pin_memory=True)

    gallery_loader_ir = DataLoader(Preprocessor(list(set(dataset.gallery)),
                                                root=dataset.images_dir,
                                                transform=test_transformer),
                                   batch_size=32,
                                   num_workers=workers,
                                   sampler=CamSampler(
                                       list(set(dataset.gallery)), [2, 5], 2),
                                   shuffle=False,
                                   pin_memory=True)

    return dataset, num_classes, train_loader, trainvallabel, val_loader, query_loader, gallery_loader, query_loader_rgb, gallery_loader_rgb, query_loader_ir, gallery_loader_ir
Пример #5
0
def get_data(name, data_dir, height, width, ratio, batch_size, workers,
             num_instances):
    root = osp.join(data_dir, name)
    root = data_dir
    dataset = datasets.create(name, root)

    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])

    num_classes = dataset.num_train_ids

    train_transformer = T.Compose([
        #        T.RandomSizedRectCrop(height, width),
        #        T.RectScale(height, width),
        T.ContVerticalCrop(height, width, ratio),
        T.RandomHorizontalFlip(),
        T.ToTensor(),
        normalizer,
    ])

    test_transformer = T.Compose([
        T.RectScale(height, width),
        T.ToTensor(),
        normalizer,
    ])

    query_transformer = T.Compose([
        T.ContVerticalCropDiscret(height, width, ratio),
        T.ToTensor(),
        normalizer,
    ])

    train_loader = DataLoader(
        Preprocessor(dataset.train,
                     root=osp.join(dataset.images_dir, dataset.train_path),
                     transform=train_transformer),
        batch_size=batch_size,
        num_workers=workers,
        sampler=RandomIdentitySampler(dataset.train, num_instances),
        pin_memory=True,
        drop_last=True)

    query_loader = DataLoader(Preprocessor(dataset.query,
                                           root=osp.join(
                                               dataset.images_dir,
                                               dataset.query_path),
                                           transform=query_transformer),
                              batch_size=batch_size,
                              num_workers=workers,
                              shuffle=False,
                              pin_memory=True)

    gallery_loader = DataLoader(Preprocessor(dataset.gallery,
                                             root=osp.join(
                                                 dataset.images_dir,
                                                 dataset.gallery_path),
                                             transform=test_transformer),
                                batch_size=batch_size,
                                num_workers=workers,
                                shuffle=False,
                                pin_memory=True)

    return dataset, num_classes, train_loader, query_loader, gallery_loader
Пример #6
0
def get_data(data_dir, height, width, batch_size, num_instances, re=0, workers=8):

    dataset = DA(data_dir)
    test_dataset = TotalData(data_dir)



    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])

    num_classes = dataset.num_source_ids

    train_transformer = T.Compose([
        T.Resize((256, 128), interpolation=3),
        T.Pad(10),
        T.RandomCrop((256,128)),
        T.RandomHorizontalFlip(0.5),
        T.RandomRotation(5), 
        T.ColorJitter(brightness=(0.5, 2.0), saturation=(0.5, 2.0), hue=(-0.1, 0.1)),
        T.ToTensor(),
        normalizer,
        # T.RandomErasing(EPSILON=re),
    ])

    test_transformer = T.Compose([
        T.Resize((256, 128), interpolation=3),
        T.ToTensor(),
        normalizer,
    ])
    
    # Train
    source_train_loader = DataLoader(
        Preprocessor(dataset.source_train,
                     transform=train_transformer),
        batch_size=batch_size, num_workers=workers,
        # shuffle=True, pin_memory=True, drop_last=True)
        sampler=RandomIdentitySampler(dataset.source_train, batch_size, num_instances),
        pin_memory=True, drop_last=True) 

    # Test
    grid_query_loader = DataLoader(
        Preprocessor(test_dataset.grid_query,
                     root=osp.join(test_dataset.grid_images_dir, test_dataset.query_path), transform=test_transformer),
        batch_size=64, num_workers=4,
        shuffle=False, pin_memory=True)
    grid_gallery_loader = DataLoader(
        Preprocessor(test_dataset.grid_gallery,
                     root=osp.join(test_dataset.grid_images_dir, test_dataset.gallery_path), transform=test_transformer),
        batch_size=64, num_workers=4,
        shuffle=False, pin_memory=True)
    prid_query_loader = DataLoader(
        Preprocessor(test_dataset.prid_query,
                     root=osp.join(test_dataset.prid_images_dir, test_dataset.query_path), transform=test_transformer),
        batch_size=64, num_workers=4,
        shuffle=False, pin_memory=True)
    prid_gallery_loader = DataLoader(
        Preprocessor(test_dataset.prid_gallery,
                     root=osp.join(test_dataset.prid_images_dir, test_dataset.gallery_path), transform=test_transformer),
        batch_size=64, num_workers=4,
        shuffle=False, pin_memory=True)
    viper_query_loader = DataLoader(
        Preprocessor(test_dataset.viper_query,
                     root=osp.join(test_dataset.viper_images_dir, test_dataset.query_path), transform=test_transformer),
        batch_size=64, num_workers=4,
        shuffle=False, pin_memory=True)
    viper_gallery_loader = DataLoader(
        Preprocessor(test_dataset.viper_gallery,
                     root=osp.join(test_dataset.viper_images_dir, test_dataset.gallery_path), transform=test_transformer),
        batch_size=64, num_workers=4,
        shuffle=False, pin_memory=True)
    ilid_query_loader = DataLoader(
        Preprocessor(test_dataset.ilid_query,
                     root=osp.join(test_dataset.ilid_images_dir, "images"), transform=test_transformer),
        batch_size=64, num_workers=4,
        shuffle=False, pin_memory=True)
    ilid_gallery_loader = DataLoader(
        Preprocessor(test_dataset.ilid_gallery,
                     root=osp.join(test_dataset.ilid_images_dir, "images"), transform=test_transformer),
        batch_size=64, num_workers=4,
        shuffle=False, pin_memory=True)


    return dataset, test_dataset, num_classes, source_train_loader, grid_query_loader, grid_gallery_loader,prid_query_loader, prid_gallery_loader,viper_query_loader, viper_gallery_loader, ilid_query_loader, ilid_gallery_loader
def main(args):
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    cudnn.benchmark = True

    # Create data loaders
    assert args.num_instances > 1, "num_instances should be greater than 1"
    assert args.batch_size % args.num_instances == 0, \
        'num_instances should divide batch_size'
    if args.height is None or args.width is None:
        args.height, args.width = (144, 56) if args.arch == 'inception' else \
            (256, 128)

    # get source data
    src_dataset, src_extfeat_loader = \
        get_source_data(args.src_dataset, args.data_dir, args.height,
                        args.width, args.batch_size, args.workers)
    # get target data
    tgt_dataset, num_classes, tgt_extfeat_loader, test_loader = \
        get_data(args.tgt_dataset, args.data_dir, args.height,
                 args.width, args.batch_size, args.workers)

    # Create model
    # Hacking here to let the classifier be the number of source ids
    if args.src_dataset == 'dukemtmc':
        model = models.create(args.arch, num_classes=632, pretrained=False)
        coModel = models.create(args.arch, num_classes=632, pretrained=False)
    elif args.src_dataset == 'market1501':
        model = models.create(args.arch, num_classes=676, pretrained=False)
        coModel = models.create(args.arch, num_classes=676, pretrained=False)
    elif args.src_dataset == 'msmt17':
        model = models.create(args.arch, num_classes=1041, pretrained=False)
        coModel = models.create(args.arch, num_classes=1041, pretrained=False)
    elif args.src_dataset == 'cuhk03':
        model = models.create(args.arch, num_classes=1230, pretrained=False)
        coModel = models.create(args.arch, num_classes=1230, pretrained=False)
    else:
        raise RuntimeError(
            'Please specify the number of classes (ids) of the network.')

    # Load from checkpoint
    if args.resume:
        print(
            'Resuming checkpoints from finetuned model on another dataset...\n'
        )
        checkpoint = load_checkpoint(args.resume)
        model.load_state_dict(checkpoint['state_dict'], strict=False)
        coModel.load_state_dict(checkpoint['state_dict'], strict=False)
    else:
        raise RuntimeWarning('Not using a pre-trained model.')
    model = nn.DataParallel(model).cuda()
    coModel = nn.DataParallel(coModel).cuda()

    # Criterion
    criterion = [
        TripletLoss(args.margin,
                    args.num_instances,
                    isAvg=False,
                    use_semi=False).cuda(),
        TripletLoss(args.margin,
                    args.num_instances,
                    isAvg=False,
                    use_semi=False).cuda()
    ]
    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)
    coOptimizer = torch.optim.Adam(coModel.parameters(), lr=args.lr)

    optims = [optimizer, coOptimizer]

    # training stage transformer on input images
    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])
    train_transformer = T.Compose([
        T.Resize((args.height, args.width)),
        T.RandomHorizontalFlip(),
        T.ToTensor(), normalizer,
        T.RandomErasing(probability=0.5, sh=0.2, r1=0.3)
    ])

    # # Start training
    for iter_n in range(args.iteration):
        if args.lambda_value == 0:
            source_features = 0
        else:
            # get source datas' feature
            source_features, _ = extract_features(model,
                                                  src_extfeat_loader,
                                                  print_freq=args.print_freq,
                                                  numStripe=None)
            # synchronization feature order with src_dataset.train
            source_features = torch.cat([
                source_features[f].unsqueeze(0)
                for f, _, _ in src_dataset.train
            ], 0)

            # extract training images' features
        print('Iteration {}: Extracting Target Dataset Features...'.format(
            iter_n + 1))
        target_features, _ = extract_features(model,
                                              tgt_extfeat_loader,
                                              print_freq=args.print_freq,
                                              numStripe=None)
        # synchronization feature order with dataset.train
        target_features = torch.cat([
            target_features[f].unsqueeze(0) for f, _, _ in tgt_dataset.trainval
        ], 0)
        # calculate distance and rerank result
        print('Calculating feature distances...')
        target_features = target_features.numpy()
        rerank_dist = re_ranking(source_features,
                                 target_features,
                                 lambda_value=args.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(args.rho * tri_mat.size).astype(int)
            eps = tri_mat[:top_num].mean()
            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)
        num_ids = len(set(labels)) - 1
        print('Iteration {} have {} training ids'.format(iter_n + 1, num_ids))
        # generate new dataset
        new_dataset = []
        # assign label for target ones
        newLab = labelNoise(torch.from_numpy(target_features),
                            torch.from_numpy(labels))
        # unknownFeats = target_features[labels==-1,:]
        counter = 0
        from collections import defaultdict
        realIDs, fakeIDs = defaultdict(list), []
        for (fname, realID, cam), label in zip(tgt_dataset.trainval, newLab):
            # dont need to change codes in trainer.py _parsing_input function and sampler function after add 0
            new_dataset.append((fname, label, cam))
            realIDs[realID].append(counter)
            fakeIDs.append(label)
            counter += 1
        precision, recall, fscore = calScores(realIDs, np.asarray(fakeIDs))
        print('Iteration {} have {} training images'.format(
            iter_n + 1, len(new_dataset)))
        print(
            f'precision:{precision * 100}, recall:{100 * recall}, fscore:{100 * fscore}'
        )
        train_loader = DataLoader(Preprocessor(new_dataset,
                                               root=tgt_dataset.images_dir,
                                               transform=train_transformer),
                                  batch_size=args.batch_size,
                                  num_workers=4,
                                  sampler=RandomIdentitySampler(
                                      new_dataset, args.num_instances),
                                  pin_memory=True,
                                  drop_last=True)
        trainer = CoTeaching(model, coModel, train_loader, criterion, optims)

        # Start training
        for epoch in range(args.epochs):
            trainer.train(epoch,
                          remRate=0.2 + (0.8 / args.iteration) *
                          (1 + iter_n))  # to at most 80%
        # test only
        evaluator = Evaluator(model, print_freq=args.print_freq)
        rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                        tgt_dataset.gallery)

    # Evaluate
    rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                    tgt_dataset.gallery)
    save_checkpoint(
        {
            'state_dict': model.module.state_dict(),
            'epoch': epoch + 1,
            'best_top1': rank_score.market1501[0],
        },
        True,
        fpath=osp.join(args.logs_dir, 'adapted.pth.tar'))
    return rank_score.map, rank_score.market1501[0]
Пример #8
0
def main(args):
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    cudnn.benchmark = True

    # Create data loaders
    assert args.num_instances > 1, "num_instances should be greater than 1"
    assert args.batch_size % args.num_instances == 0, \
        'num_instances should divide batch_size'
    if args.height is None or args.width is None:
        args.height, args.width = (144, 56) if args.arch == 'inception' else \
                                  (256, 128)

    # get source data
    src_dataset, src_extfeat_loader = \
        get_source_data(args.src_dataset, args.data_dir, args.height,
                        args.width, args.batch_size, args.workers)
    # get target data
    tgt_dataset, num_classes, tgt_extfeat_loader, test_loader = \
        get_data(args.tgt_dataset, args.data_dir, args.height,
                 args.width, args.batch_size, args.workers)

    # Create model
    # Hacking here to let the classifier be the number of source ids
    if args.src_dataset == 'dukemtmc':
        model = models.create(args.arch, num_classes=632, pretrained=False)
    elif args.src_dataset == 'market1501':
        model = models.create(args.arch, num_classes=676, pretrained=False)
    else:
        raise RuntimeError(
            'Please specify the number of classes (ids) of the network.')

    # Load from checkpoint
    if args.resume:
        print(
            'Resuming checkpoints from finetuned model on another dataset...\n'
        )
        checkpoint = load_checkpoint(args.resume)
        model.load_state_dict(checkpoint['state_dict'], strict=False)
    else:
        raise RuntimeWarning('Not using a pre-trained model.')
    model = nn.DataParallel(model).cuda()

    # evaluator.evaluate(test_loader, tgt_dataset.query, tgt_dataset.gallery)
    # if args.evaluate: return

    # Criterion
    criterion = [
        TripletLoss(args.margin, args.num_instances, isAvg=True,
                    use_semi=True).cuda(),
        TripletLoss(args.margin, args.num_instances, isAvg=True,
                    use_semi=True).cuda(), None, None
    ]

    # Optimizer
    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)

    # training stage transformer on input images
    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])
    train_transformer = T.Compose([
        T.Resize((args.height, args.width)),
        T.RandomHorizontalFlip(),
        T.ToTensor(), normalizer,
        T.RandomErasing(probability=0.5, sh=0.2, r1=0.3)
    ])

    evaluator = Evaluator(model, print_freq=args.print_freq)
    evaluator.evaluate(test_loader, tgt_dataset.query, tgt_dataset.gallery)

    # # Start training
    for iter_n in range(args.iteration):
        if args.lambda_value == 0:
            source_features = 0
        else:
            # get source datas' feature
            source_features, _ = extract_features(model,
                                                  src_extfeat_loader,
                                                  print_freq=args.print_freq)
            # synchronization feature order with src_dataset.train
            source_features = torch.cat([
                source_features[f].unsqueeze(0)
                for f, _, _, _ in src_dataset.train
            ], 0)

        # extract training images' features
        print('Iteration {}: Extracting Target Dataset Features...'.format(
            iter_n + 1))
        target_features, tarNames = extract_features(
            model, tgt_extfeat_loader, print_freq=args.print_freq)
        # synchronization feature order with dataset.train
        target_features = torch.cat([
            target_features[f].unsqueeze(0)
            for f, _, _, _ in tgt_dataset.trainval
        ], 0)
        # target_real_label = np.asarray([tarNames[f].unsqueeze(0) for f, _, _, _ in tgt_dataset.trainval])

        # calculate distance and rerank result
        # method 1
        target_features = target_features.numpy()
        rerank_dist = re_ranking(source_features,
                                 target_features,
                                 lambda_value=args.lambda_value)

        # method 2
        # distmat_qq = calDis(source_features, source_features)
        # distmat_qg = calDis(source_features, target_features)
        # distmat_gg = calDis(target_features, target_features)
        # rerank_dist = re_ranking2(distmat_qg.numpy(), distmat_qq.numpy(), distmat_gg.numpy())

        cluster = HDBSCAN(metric='precomputed', min_samples=10)
        # select & cluster images as training set of this epochs
        clusterRes = cluster.fit(rerank_dist)
        labels, label_num = clusterRes.labels_, clusterRes.labels_.max() + 1
        centers = np.zeros((label_num, target_features.shape[1]))
        nums = [0] * target_features.shape[1]
        print('clusters num =', label_num)

        # generate new dataset
        new_dataset = []
        index = -1
        for (fname, _, cam, timestamp), label in zip(tgt_dataset.trainval,
                                                     labels):
            index += 1
            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, cam, timestamp))
            centers[label] += target_features[index]
            nums[label] += 1
        print('Iteration {} have {} training images'.format(
            iter_n + 1, len(new_dataset)))

        train_loader = DataLoader(Preprocessor(new_dataset,
                                               root=tgt_dataset.images_dir,
                                               transform=train_transformer),
                                  batch_size=args.batch_size,
                                  num_workers=4,
                                  sampler=RandomIdentitySampler(
                                      new_dataset, args.num_instances),
                                  pin_memory=True,
                                  drop_last=True)

        for i in range(label_num):
            centers[i] /= nums[i]
        criterion[3] = ClassificationLoss(normalize(centers, axis=1)).cuda()

        classOptimizer = torch.optim.Adam(
            [{
                'params': model.parameters()
            }, {
                'params': criterion[3].classifier.parameters(),
                'lr': 1e-3
            }],
            lr=args.lr)

        class_trainer = ClassificationTrainer(model, train_loader, criterion,
                                              classOptimizer)

        for epoch in range(args.epochs):
            class_trainer.train(epoch)

        rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                        tgt_dataset.gallery)

    # Evaluate
    rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                    tgt_dataset.gallery)
    save_checkpoint(
        {
            'state_dict': model.module.state_dict(),
            'epoch': epoch + 1,
            'best_top1': rank_score.market1501[0],
        },
        True,
        fpath=osp.join(args.logs_dir, 'adapted.pth.tar'))
    return (rank_score.map, rank_score.market1501[0])
def main(args):
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    cudnn.benchmark = True

    # Create data loaders
    assert args.num_instances > 1, "num_instances should be greater than 1"
    assert args.batch_size % args.num_instances == 0, \
        'num_instances should divide batch_size'
    if args.height is None or args.width is None:
        args.height, args.width = (144, 56) if args.arch == 'inception' else \
                                  (256, 128)

    # get source data
    src_dataset, src_extfeat_loader = \
        get_source_data(args.src_dataset, args.data_dir, args.height,
                        args.width, args.batch_size, args.workers)
    # get target data
    tgt_dataset, num_classes, tgt_extfeat_loader, test_loader = \
        get_data(args.tgt_dataset, args.data_dir, args.height,
                 args.width, args.batch_size, args.workers)

    # Create model
    # Hacking here to let the classifier be the number of source ids
    if args.src_dataset == 'dukemtmc':
        model = models.create(args.arch, num_classes=632, pretrained=False)
    elif args.src_dataset == 'market1501':
        model = models.create(args.arch, num_classes=676, pretrained=False)
    else:
        raise RuntimeError(
            'Please specify the number of classes (ids) of the network.')

    # Load from checkpoint
    if args.resume:
        print(
            'Resuming checkpoints from finetuned model on another dataset...\n'
        )
        checkpoint = load_checkpoint(args.resume)
        model.load_state_dict(checkpoint['state_dict'], strict=False)
    else:
        raise RuntimeWarning('Not using a pre-trained model.')
    model = nn.DataParallel(model).cuda()

    # Distance metric
    # metric = DistanceMetric(algorithm=args.dist_metric)

    # Evaluator
    evaluator = Evaluator(model, print_freq=args.print_freq)
    print(
        "Test with the original model trained on source domain (direct transfer):"
    )
    rank_score_best = evaluator.evaluate(test_loader, tgt_dataset.query,
                                         tgt_dataset.gallery)
    best_map = rank_score_best.map  #market1501[0]-->rank-1

    if args.evaluate:
        return

    # Criterion
    criterion = [
        TripletLoss(args.margin, args.num_instances).cuda(),
        TripletLoss(args.margin, args.num_instances).cuda(),
        AccumulatedLoss(args.margin, args.num_instances).cuda(),
    ]

    # Optimizer
    optimizer = torch.optim.SGD(
        model.parameters(),
        lr=args.lr,
        momentum=0.9,
    )

    # training stage transformer on input images
    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])
    train_transformer = T.Compose([
        T.Resize((args.height, args.width)),
        T.RandomHorizontalFlip(),
        T.ToTensor(), normalizer,
        T.RandomErasing(probability=0.5, sh=0.2, r1=0.3)
    ])

    # Start training
    for iter_n in range(args.iteration):
        if args.lambda_value == 0:
            source_features = 0  #this value controls the usage of source data
        else:
            # get source datas' feature
            source_features, _ = extract_features(model,
                                                  src_extfeat_loader,
                                                  print_freq=args.print_freq)
            # synchronization feature order with src_dataset.train
            source_features = torch.cat([
                source_features[f].unsqueeze(0)
                for f, _, _ in src_dataset.train
            ], 0)

        # extract training images' features
        print('Iteration {}: Extracting Target Dataset Features...'.format(
            iter_n + 1))
        target_features, _ = extract_features(model,
                                              tgt_extfeat_loader,
                                              print_freq=args.print_freq)
        # synchronization feature order with dataset.train
        target_features = torch.cat([
            target_features[f].unsqueeze(0) for f, _, _ in tgt_dataset.trainval
        ], 0)
        # calculate distance and rerank result
        print('Calculating feature distances...')
        target_features = target_features.numpy()
        rerank_dist = re_ranking(source_features,
                                 target_features,
                                 lambda_value=args.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(args.rho * tri_mat.size).astype(int)
            eps = tri_mat[:top_num].mean()
            print('eps in cluster: {:.3f}'.format(eps))
            cluster = DBSCAN(eps=eps,
                             min_samples=4,
                             metric='precomputed',
                             n_jobs=8)

            # HDBSCAN cluster
            import hdbscan
            cluster_hdbscan = hdbscan.HDBSCAN(min_cluster_size=10,
                                              min_samples=4,
                                              metric='precomputed')

        # select & cluster images as training set of this epochs
        print('Clustering and labeling...')
        if args.use_hdbscan_clustering:
            print(
                'Use the better chlustering algorithm HDBSCAN for clustering')
            labels = cluster_hdbscan.fit_predict(rerank_dist)
        else:
            print('Use DBSCAN for clustering')
            labels = cluster.fit_predict(rerank_dist)
        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.trainval, 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)))

        train_loader = DataLoader(Preprocessor(new_dataset,
                                               root=tgt_dataset.images_dir,
                                               transform=train_transformer),
                                  batch_size=args.batch_size,
                                  num_workers=4,
                                  sampler=RandomIdentitySampler(
                                      new_dataset, args.num_instances),
                                  pin_memory=True,
                                  drop_last=True)

        # train model with new generated dataset
        trainer = Trainer(model, criterion, print_freq=args.print_freq)
        evaluator = Evaluator(model, print_freq=args.print_freq)
        # Start training
        for epoch in range(args.epochs):
            trainer.train(epoch, train_loader, optimizer)

        # Evaluate
        rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                        tgt_dataset.gallery)

        #Save the best ckpt:
        rank1 = rank_score.market1501[0]
        mAP = rank_score.map
        is_best_mAP = mAP > best_map
        best_map = max(mAP, best_map)
        save_checkpoint(
            {
                'state_dict': model.module.state_dict(),
                'epoch': iter_n + 1,
                'best_mAP': best_map,
                # 'num_ids': num_ids,
            },
            is_best_mAP,
            fpath=osp.join(args.logs_dir, 'checkpoint.pth.tar'))

        print(
            '\n * Finished epoch {:3d}  top1: {:5.1%}  mAP: {:5.1%}  best_mAP: {:5.1%}{}\n'
            .format(iter_n + 1, rank1, mAP, best_map,
                    ' *' if is_best_mAP else ''))

    return (rank_score.map, rank_score.market1501[0])
Пример #10
0
def get_data(data_dir, source, target, height, width, batch_size, re=0, workers=8):

    dataset = DA(data_dir, source, target)
    dataset_2 = DA(data_dir, target, source)

    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])

    num_classes = dataset.num_train_ids

    train_transformer = T.Compose([
        T.Resize((height, width), interpolation=3),
             T.RandomHorizontalFlip(p=0.5),
             T.Pad(10),
             T.RandomCrop((height, width)),
             T.ToTensor(),
        normalizer,
       # T.RandomErasing(EPSILON=re),
        T.RandomErasing(probability=0.4, mean=[0.485, 0.456, 0.406])
    ])

    train_transformer_2 = T.Compose([
        T.Resize((height, width), interpolation=3),
             T.RandomHorizontalFlip(p=0.5),
             T.Pad(10),
             T.RandomCrop((height, width)),
             T.ToTensor(),
        normalizer,
       # T.RandomErasing(EPSILON=re),
        T.RandomErasing(probability=0.4, mean=[0.485, 0.456, 0.406])
    ])

    test_transformer = T.Compose([
        T.Resize((height, width), interpolation=3),
        T.ToTensor(),
        normalizer,
    ])

    '''
    num_instances=4

    rmgs_flag = num_instances > 0
    if rmgs_flag:
        sampler = RandomIdentitySampler(dataset.target_train, num_instances)
    else:
        sampler = None
    '''
    source_train_loader = DataLoader(
        Preprocessor(dataset.source_train, root=osp.join(dataset.source_images_dir, dataset.source_train_path),
                     transform=train_transformer),
        batch_size=batch_size, num_workers=workers,
        shuffle=True, pin_memory=True, drop_last=True)

    num_instances=0

    rmgs_flag = num_instances > 0
    if rmgs_flag:
        sampler = RandomIdentitySampler(dataset.target_train, num_instances)
    else:
        sampler = None



    target_train_loader = DataLoader(
        UnsupervisedCamStylePreprocessor(dataset.target_train,
                                         root=osp.join(dataset.target_images_dir, dataset.target_train_path),
                                         camstyle_root=osp.join(dataset.target_images_dir,
                                                                dataset.target_train_camstyle_path),
                                         num_cam=dataset.target_num_cam, transform=train_transformer),
        batch_size=batch_size, num_workers=workers,
        shuffle=True, pin_memory=True, drop_last=True)

    query_loader = DataLoader(
        Preprocessor(dataset.query,
                     root=osp.join(dataset.target_images_dir, dataset.query_path), transform=test_transformer),
        batch_size=batch_size, num_workers=workers,
        shuffle=False, pin_memory=True)

    query_loader_2 = DataLoader(
        Preprocessor(dataset_2.query,
                     root=osp.join(dataset_2.target_images_dir, dataset_2.query_path), transform=test_transformer),
        batch_size=batch_size, num_workers=workers,
        shuffle=False, pin_memory=True)

    gallery_loader = DataLoader(
        Preprocessor(dataset.gallery,
                     root=osp.join(dataset.target_images_dir, dataset.gallery_path), transform=test_transformer),
        batch_size=batch_size, num_workers=workers,
        shuffle=False, pin_memory=True)

    gallery_loader_2 = DataLoader(
        Preprocessor(dataset_2.gallery,
                     root=osp.join(dataset_2.target_images_dir, dataset_2.gallery_path), transform=test_transformer),
        batch_size=batch_size, num_workers=workers,
        shuffle=False, pin_memory=True)

    return dataset,dataset_2, num_classes, source_train_loader, target_train_loader, query_loader, gallery_loader, query_loader_2, gallery_loader_2
Пример #11
0
def main(args):
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    cudnn.benchmark = True

    # Create data loaders
    assert args.num_instances > 1, "num_instances should be greater than 1"
    assert args.batch_size % args.num_instances == 0, \
        'num_instances should divide batch_size'
    if args.height is None or args.width is None:
        args.height, args.width = (144, 56) if args.arch == 'inception' else \
                                  (256, 128)

    # get source data
    src_dataset, src_extfeat_loader = \
        get_source_data(args.src_dataset, args.data_dir, args.height,
                        args.width, args.batch_size, args.workers)
    # get target data
    tgt_dataset, num_classes, tgt_extfeat_loader, test_loader = \
        get_data(args.tgt_dataset, args.data_dir, args.height,
                 args.width, args.batch_size, args.workers)

    # Create model
    # Hacking here to let the classifier be the number of source ids
    if args.src_dataset == 'dukemtmc':
        model = models.create(args.arch, num_classes=632, pretrained=False)
    elif args.src_dataset == 'market1501':
        model = models.create(args.arch, num_classes=676, pretrained=False)
    else:
        raise RuntimeError(
            'Please specify the number of classes (ids) of the network.')

    # Load from checkpoint
    if args.resume:
        print(
            'Resuming checkpoints from finetuned model on another dataset...\n'
        )
        checkpoint = load_checkpoint(args.resume)
        model.load_state_dict(checkpoint['state_dict'], strict=False)
    else:
        raise RuntimeWarning('Not using a pre-trained model.')
    model = nn.DataParallel(model).cuda()

    # evaluator.evaluate(test_loader, tgt_dataset.query, tgt_dataset.gallery)
    # if args.evaluate: return

    # Criterion
    criterion = [
        TripletLoss(args.margin, args.num_instances, isAvg=True,
                    use_semi=True).cuda(),
        TripletLoss(args.margin, args.num_instances, isAvg=True,
                    use_semi=True).cuda(),
    ]

    # Optimizer
    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)

    # training stage transformer on input images
    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])
    train_transformer = T.Compose([
        T.Resize((args.height, args.width)),
        T.RandomHorizontalFlip(),
        T.ToTensor(), normalizer,
        T.RandomErasing(probability=0.5, sh=0.2, r1=0.3)
    ])

    # # Start training
    for iter_n in range(args.iteration):
        if args.lambda_value == 0:
            source_features = 0
        else:
            # get source datas' feature
            source_features, _ = extract_features(model,
                                                  src_extfeat_loader,
                                                  print_freq=args.print_freq)
            # synchronization feature order with src_dataset.train
            source_features = torch.cat([
                source_features[f].unsqueeze(0)
                for f, _, _ in src_dataset.train
            ], 0)

        # extract training images' features
        print('Iteration {}: Extracting Target Dataset Features...'.format(
            iter_n + 1))
        target_features, tarNames = extract_features(
            model, tgt_extfeat_loader, print_freq=args.print_freq)
        # synchronization feature order with dataset.train
        target_features = torch.cat([
            target_features[f].unsqueeze(0) for f, _, _ in tgt_dataset.trainval
        ], 0)
        target_real_label = np.asarray(
            [tarNames[f].unsqueeze(0) for f, _, _ in tgt_dataset.trainval])
        numTarID = len(set(target_real_label))
        # calculate distance and rerank result
        print('Calculating feature distances...')
        target_features = target_features.numpy()
        cluster = KMeans(n_clusters=numTarID, n_jobs=8, n_init=1)

        # select & cluster images as training set of this epochs
        print('Clustering and labeling...')
        clusterRes = cluster.fit(target_features)
        labels, centers = clusterRes.labels_, clusterRes.cluster_centers_
        # labels = splitLowconfi(target_features,labels,centers)
        # num_ids = len(set(labels))
        # print('Iteration {} have {} training ids'.format(iter_n+1, num_ids))
        # generate new dataset
        new_dataset = []
        for (fname, _, cam), label in zip(tgt_dataset.trainval, 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, cam))
        print('Iteration {} have {} training images'.format(
            iter_n + 1, len(new_dataset)))
        train_loader = DataLoader(Preprocessor(new_dataset,
                                               root=tgt_dataset.images_dir,
                                               transform=train_transformer),
                                  batch_size=args.batch_size,
                                  num_workers=4,
                                  sampler=RandomIdentitySampler(
                                      new_dataset, args.num_instances),
                                  pin_memory=True,
                                  drop_last=True)

        # train model with new generated dataset
        trainer = Trainer(model, criterion)

        evaluator = Evaluator(model, print_freq=args.print_freq)

        # Start training
        for epoch in range(args.epochs):
            # trainer.train(epoch, remRate=0.2+(0.6/args.iteration)*(1+iter_n)) # to at most 80%
            trainer.train(epoch, train_loader, optimizer)
        # test only
        rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                        tgt_dataset.gallery)
        #print('co-model:\n')
        #rank_score = evaluatorB.evaluate(test_loader, tgt_dataset.query, tgt_dataset.gallery)

    # Evaluate
    rank_score = evaluator.evaluate(test_loader, tgt_dataset.query,
                                    tgt_dataset.gallery)
    save_checkpoint(
        {
            'state_dict': model.module.state_dict(),
            'epoch': epoch + 1,
            'best_top1': rank_score.market1501[0],
        },
        True,
        fpath=osp.join(args.logs_dir, 'adapted.pth.tar'))
    return (rank_score.map, rank_score.market1501[0])
Пример #12
0
def get_data(name, data_dir, height, width, batch_size, num_bn_sample,
             num_instances, workers):
    # Datasets
    if name == 'market1501':
        dataset_name = 'market1501'
        dataset = data_manager.init_imgreid_dataset(root=data_dir,
                                                    name=dataset_name)
        dataset.images_dir = ''
        train_transformer = T.Compose([
            T.Random2DTranslation(height, width),
            T.RandomHorizontalFlip(),
            T.ToTensor(),
        ])

        test_transformer = T.Compose([
            T.RectScale(height, width),
            T.ToTensor(),
        ])
        train_loader = DataLoader(Preprocessor(dataset.train,
                                               root=dataset.images_dir,
                                               transform=train_transformer),
                                  batch_size=batch_size,
                                  num_workers=workers,
                                  sampler=RandomIdentitySampler(
                                      dataset.train, num_instances),
                                  pin_memory=True,
                                  drop_last=True)

    elif name == 'market_sct' or name == 'market_sct_tran' or name == 'duke_sct' or name == 'duke_sct_tran':
        dataset_name = name
        dataset = data_manager.init_imgreid_dataset(
            root=data_dir, name=dataset_name, num_bn_sample=num_bn_sample)
        dataset.images_dir = ''
        # dataset_name = name
        pin_memory = True
        collateFn = NormalCollateFn()
        train_loader = DataLoader(
            data_manager.init_datafolder(
                dataset_name,
                dataset.train,
                TrainTransform(height, width),
            ),
            batch_sampler=RandomIdentityCameraSampler(dataset.train,
                                                      num_instances,
                                                      batch_size),
            num_workers=workers,
            pin_memory=pin_memory,
            collate_fn=collateFn,
        )
        # train_loader = DataLoader(
        #     data_manager.init_datafolder(dataset_name, dataset.train,
        #                                  TrainTransform(height, width),
        #                                  ),
        #     batch_sampler=RandomIdentityUniqueCameraSampler(dataset.train, num_instances, batch_size),
        #     num_workers=workers,
        #     pin_memory=pin_memory, collate_fn=collateFn,
        # )

    # Num. of training IDs
    num_classes = dataset.num_train_pids
    return dataset, num_classes, train_loader
def get_data(name, split_id, data_dir, height, width, batch_size,
             num_instances, workers, combine_trainval):
    root = osp.join(data_dir, name)

    dataset = datasets.create(name, root, split_id=split_id)

    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])

    train_set = dataset.trainval if combine_trainval else dataset.train
    num_classes = (dataset.num_trainval_ids
                   if combine_trainval else dataset.num_train_ids)

    train_transformer = T.Compose([
        T.RandomSizedRectCrop(height, width),
        T.RandomHorizontalFlip(),
        T.ToTensor(),
        normalizer,
    ])

    test_transformer = T.Compose([
        T.RectScale(height, width),
        T.ToTensor(),
        normalizer,
    ])

    train_loader = DataLoader(Preprocessor(train_set,
                                           root=dataset.images_dir,
                                           transform=train_transformer),
                              batch_size=batch_size,
                              num_workers=workers,
                              sampler=RandomIdentitySampler(
                                  train_set, num_instances),
                              pin_memory=True,
                              drop_last=True)

    train_loader_head = DataLoader(Preprocessor(
        train_set,
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_head",
        transform=train_transformer),
                                   batch_size=batch_size,
                                   num_workers=workers,
                                   sampler=RandomIdentitySampler(
                                       train_set, num_instances),
                                   pin_memory=True,
                                   drop_last=True)
    train_loader_upper = DataLoader(Preprocessor(
        train_set,
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_upper",
        transform=train_transformer),
                                    batch_size=batch_size,
                                    num_workers=workers,
                                    sampler=RandomIdentitySampler(
                                        train_set, num_instances),
                                    pin_memory=True,
                                    drop_last=True)
    train_loader_lower = DataLoader(Preprocessor(
        train_set,
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_lower",
        transform=train_transformer),
                                    batch_size=batch_size,
                                    num_workers=workers,
                                    sampler=RandomIdentitySampler(
                                        train_set, num_instances),
                                    pin_memory=True,
                                    drop_last=True)

    val_loader = DataLoader(Preprocessor(dataset.val,
                                         root=dataset.images_dir,
                                         transform=test_transformer),
                            batch_size=batch_size,
                            num_workers=workers,
                            shuffle=False,
                            pin_memory=True)
    val_loader_head = DataLoader(Preprocessor(
        dataset.val,
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_head",
        transform=test_transformer),
                                 batch_size=batch_size,
                                 num_workers=workers,
                                 shuffle=False,
                                 pin_memory=True)
    val_loader_upper = DataLoader(Preprocessor(
        dataset.val,
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_upper",
        transform=test_transformer),
                                  batch_size=batch_size,
                                  num_workers=workers,
                                  shuffle=False,
                                  pin_memory=True)
    val_loader_lower = DataLoader(Preprocessor(
        dataset.val,
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_lower",
        transform=test_transformer),
                                  batch_size=batch_size,
                                  num_workers=workers,
                                  shuffle=False,
                                  pin_memory=True)

    test_loader = DataLoader(Preprocessor(
        list(set(dataset.query) | set(dataset.gallery)),
        root=dataset.images_dir,
        transform=test_transformer),
                             batch_size=batch_size,
                             num_workers=workers,
                             shuffle=False,
                             pin_memory=True)

    test_loader_head = DataLoader(Preprocessor(
        list(set(dataset.query) | set(dataset.gallery)),
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_head",
        transform=test_transformer),
                                  batch_size=batch_size,
                                  num_workers=workers,
                                  shuffle=False,
                                  pin_memory=True)
    test_loader_upper = DataLoader(Preprocessor(
        list(set(dataset.query) | set(dataset.gallery)),
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_upper",
        transform=test_transformer),
                                   batch_size=batch_size,
                                   num_workers=workers,
                                   shuffle=False,
                                   pin_memory=True)
    test_loader_lower = DataLoader(Preprocessor(
        list(set(dataset.query) | set(dataset.gallery)),
        root="/home/bfs/zty/reid_market/examples/data/cuhk03/images_lower",
        transform=test_transformer),
                                   batch_size=batch_size,
                                   num_workers=workers,
                                   shuffle=False,
                                   pin_memory=True)

    return dataset, num_classes, train_loader, train_loader_head, train_loader_upper, train_loader_lower,\
    val_loader, val_loader_head, val_loader_upper, val_loader_lower, test_loader, test_loader_head, \
    test_loader_upper, test_loader_lower
Пример #14
0
def get_data(dataset_name,
             split_id,
             data_dir,
             batch_size,
             seq_len,
             seq_srd,
             workers,
             num_instances,
             combine_trainval=True):

    root = osp.join(data_dir, dataset_name)

    dataset = get_sequence(dataset_name,
                           root,
                           split_id=split_id,
                           seq_len=seq_len,
                           seq_srd=seq_srd,
                           num_val=1,
                           download=True)

    train_set = dataset.trainval if combine_trainval else dataset.train
    num_classes = (dataset.num_trainval_ids
                   if combine_trainval else dataset.num_train_ids)

    normalizer = seqtransforms.Normalize(mean=[0.485, 0.456, 0.406],
                                         std=[0.229, 0.224, 0.225])

    train_processor = SeqPreprocessor(train_set,
                                      dataset,
                                      transform=seqtransforms.Compose([
                                          seqtransforms.RandomSizedRectCrop(
                                              256, 128),
                                          seqtransforms.RandomHorizontalFlip(),
                                          seqtransforms.ToTensor(), normalizer
                                      ]))

    val_processor = SeqPreprocessor(dataset.val,
                                    dataset,
                                    transform=seqtransforms.Compose([
                                        seqtransforms.RectScale(256, 128),
                                        seqtransforms.ToTensor(), normalizer
                                    ]))

    test_processor = SeqPreprocessor(
        list(set(dataset.query) | set(dataset.gallery)),
        dataset,
        transform=seqtransforms.Compose([
            seqtransforms.RectScale(256, 128),
            seqtransforms.ToTensor(), normalizer
        ]))

    if num_instances > 0:
        train_loader = DataLoader(train_processor,
                                  batch_size=batch_size,
                                  num_workers=workers,
                                  sampler=RandomIdentitySampler(
                                      train_set, num_instances),
                                  pin_memory=True)
    else:
        train_loader = DataLoader(train_processor,
                                  batch_size=batch_size,
                                  num_workers=workers,
                                  shuffle=True,
                                  pin_memory=True)

    val_loader = DataLoader(val_processor,
                            batch_size=batch_size,
                            num_workers=workers,
                            shuffle=False,
                            pin_memory=True)

    test_loader = DataLoader(test_processor,
                             batch_size=batch_size,
                             num_workers=workers,
                             shuffle=False,
                             pin_memory=True)

    return dataset, num_classes, train_loader, val_loader, test_loader
Пример #15
0
def get_data(name, split_id, data_dir, height, width, batch_size,
             num_instances, workers, combine_trainval, make_data):
    root = osp.join(data_dir, name)
    if make_data:
        from_dir1, from_dir2, num_eval, test, single = make_data

        if test == 'test':
            build_test = True
            test = '_test'
        elif test == 'train':
            build_test = False
            test = 'train'
        else:
            build_test = None
            test = ''

        to_dir = '{}{}{}{}{}'.format(from_dir1, from_dir2, num_eval, test,
                                     single)
        if single == 'single':
            single = True
        elif single == 'many':
            single = False
        else:
            print('must be either single or many')

        root = osp.join(data_dir, 'select')

        dataset = datasets.create(name,
                                  root,
                                  from_dir1=from_dir1,
                                  from_dir2=from_dir2,
                                  to_dir=to_dir,
                                  num_eval=int(num_eval),
                                  make_test=build_test,
                                  single=single,
                                  split_id=split_id)
        data_path = osp.join(root, 'datasets', to_dir)
    else:
        dataset = datasets.create(name, root, split_id=split_id)
        data_path = osp.join(root, 'datasets', name)

    normalizer = T.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])

    train_set = dataset.trainval if combine_trainval else dataset.train
    num_classes = (dataset.num_trainval_ids
                   if combine_trainval else dataset.num_train_ids)

    train_transformer = T.Compose([
        T.RectCrop(height, width),
        # T.RectCrop(height / 2, width / 2),  # effectively blurring
        # T.RectScale(int(height/2), int(width/2)),
        # T.RectScale(height, width),
        T.RandomSizedRectCrop(height, width, 0.4),
        T.RandomHorizontalFlip(),
        T.ToTensor(),
        normalizer,
    ])

    test_transformer = T.Compose([
        T.RectCrop(height, width),
        # T.RectScale(int(height / 2), int(width / 2
        T.RectScale(height, width),
        T.ToTensor(),
        normalizer,
    ])

    train_loader = DataLoader(Preprocessor(train_set,
                                           root=dataset.images_dir,
                                           transform=train_transformer),
                              batch_size=batch_size,
                              num_workers=workers,
                              sampler=RandomIdentitySampler(
                                  train_set, num_instances),
                              pin_memory=True,
                              drop_last=True)

    val_loader = DataLoader(
        Preprocessor(
            dataset.val, root=dataset.images_dir,
            transform=test_transformer),  # todo originally test_transformer
        batch_size=batch_size,
        num_workers=workers,
        shuffle=False,
        pin_memory=True)

    test_loader = DataLoader(Preprocessor(
        list(set(dataset.query) | set(dataset.gallery)),
        root=dataset.images_dir,
        transform=test_transformer),
                             batch_size=batch_size,
                             num_workers=workers,
                             shuffle=False,
                             pin_memory=True)

    return dataset, num_classes, train_loader, val_loader, test_loader, data_path
Пример #16
0
def main(args):
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    cudnn.benchmark = True

    # Redirect print to both console and log file
    sys.stdout = Logger(osp.join(args.logs_dir, 'log.txt'))
    print(args)
    shutil.copy(sys.argv[0], osp.join(args.logs_dir,
                                      osp.basename(sys.argv[0])))

    # Create data loaders
    if args.height is None or args.width is None:
        args.height, args.width = (256, 128)
    dataset, num_classes, train_loader, val_loader, test_loader = \
        get_data(args.dataset, args.split, args.data_dir, args.height,
                 args.width, args.batch_size * 8, args.workers,
                 )

    # Create model
    model = models.create("ft_net_inter",
                          num_classes=num_classes,
                          stride=args.stride)

    # Load from checkpoint
    start_epoch = 0
    best_top1 = 0
    top1 = 0
    is_best = False
    if args.checkpoint is not None:
        if args.evaluate:
            checkpoint = load_checkpoint(args.checkpoint)
            param_dict = model.state_dict()
            for k, v in checkpoint['state_dict'].items():
                if 'model' in k:
                    param_dict[k] = v
            model.load_state_dict(param_dict)
        else:
            model.model.load_param(args.checkpoint)
    model = model.cuda()

    # Distance metric
    metric = None

    # Evaluator
    evaluator = Evaluator(model, use_cpu=args.use_cpu)
    if args.evaluate:
        print("Test:")
        evaluator.evaluate(test_loader, dataset.query, dataset.gallery, metric)
        return

    train_transformer = [
        T.Resize((args.height, args.width), interpolation=3),
        T.RandomHorizontalFlip(),
        T.Pad(10),
        T.RandomCrop((args.height, args.width)),
        T.ToTensor(),
        T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
        T.RandomErasing(probability=0.5),
    ]
    train_transformer = T.Compose(train_transformer)
    for cluster_epoch in range(args.cluster_epochs):
        # -------------------------Stage 1 intra camera training--------------------------
        # Cluster and generate new dataset and model
        cluster_result = get_intra_cam_cluster_result(model, train_loader,
                                                      args.class_number_stage1,
                                                      args.linkage)
        cluster_datasets = [
            datasets.create("cluster", osp.join(args.data_dir, args.dataset),
                            cluster_result[cam_id], cam_id)
            for cam_id in cluster_result.keys()
        ]

        cluster_dataloaders = [
            DataLoader(Preprocessor(dataset.train_set,
                                    root=dataset.images_dir,
                                    transform=train_transformer),
                       batch_size=args.batch_size,
                       num_workers=args.workers,
                       shuffle=True,
                       pin_memory=False,
                       drop_last=True) for dataset in cluster_datasets
        ]
        param_dict = model.model.state_dict()
        model = models.create("ft_net_intra",
                              num_classes=[
                                  args.class_number_stage1
                                  for cam_id in cluster_result.keys()
                              ],
                              stride=args.stride)

        model_param_dict = model.model.state_dict()
        for k, v in model_param_dict.items():
            if k in param_dict.keys():
                model_param_dict[k] = param_dict[k]
        model.model.load_state_dict(model_param_dict)

        model = model.cuda()
        criterion = nn.CrossEntropyLoss().cuda()

        # Optimizer
        param_groups = make_params(model, args.lr, args.weight_decay)
        optimizer = torch.optim.SGD(param_groups, momentum=0.9)
        # Trainer
        trainer = IntraCameraTrainer(model,
                                     criterion,
                                     warm_up_epoch=args.warm_up)
        print("start training")
        # Start training
        for epoch in range(0, args.epochs_stage1):
            trainer.train(
                cluster_epoch,
                epoch,
                cluster_dataloaders,
                optimizer,
                print_freq=args.print_freq,
            )
        # -------------------------------------------Stage 2 inter camera training-----------------------------------
        mix_rate = get_mix_rate(args.mix_rate,
                                cluster_epoch,
                                args.cluster_epochs,
                                power=args.decay_factor)

        cluster_result = get_inter_cam_cluster_result(model,
                                                      train_loader,
                                                      args.class_number_stage2,
                                                      args.linkage,
                                                      mix_rate,
                                                      use_cpu=args.use_cpu)

        cluster_dataset = datasets.create(
            "cluster", osp.join(args.data_dir, args.dataset), cluster_result,
            0)

        cluster_dataloaders = DataLoader(
            Preprocessor(cluster_dataset.train_set,
                         root=cluster_dataset.images_dir,
                         transform=train_transformer),
            batch_size=args.batch_size_stage2,
            num_workers=args.workers,
            sampler=RandomIdentitySampler(cluster_dataset.train_set,
                                          args.batch_size_stage2,
                                          args.instances),
            pin_memory=False,
            drop_last=True)

        param_dict = model.model.state_dict()
        model = models.create("ft_net_inter",
                              num_classes=args.class_number_stage2,
                              stride=args.stride)
        model.model.load_state_dict(param_dict)

        model = model.cuda()
        # Criterion
        criterion_entropy = nn.CrossEntropyLoss().cuda()
        criterion_triple = TripletLoss(margin=args.margin).cuda()

        # Optimizer
        param_groups = make_params(model,
                                   args.lr * args.batch_size_stage2 / 32,
                                   args.weight_decay)

        optimizer = torch.optim.SGD(param_groups, momentum=0.9)
        # Trainer
        trainer = InterCameraTrainer(
            model,
            criterion_entropy,
            criterion_triple,
            warm_up_epoch=args.warm_up,
        )

        print("start training")
        # Start training
        for epoch in range(0, args.epochs_stage2):
            trainer.train(cluster_epoch,
                          epoch,
                          cluster_dataloaders,
                          optimizer,
                          print_freq=args.print_freq)
        if (cluster_epoch + 1) % 5 == 0:

            evaluator = Evaluator(model, use_cpu=args.use_cpu)
            top1, mAP = evaluator.evaluate(test_loader,
                                           dataset.query,
                                           dataset.gallery,
                                           metric,
                                           return_mAP=True)

            is_best = top1 > best_top1
            best_top1 = max(top1, best_top1)

            save_checkpoint(
                {
                    'state_dict': model.state_dict(),
                    'epoch': cluster_epoch + 1,
                    'best_top1': best_top1,
                    'cluster_epoch': cluster_epoch + 1,
                },
                is_best,
                fpath=osp.join(args.logs_dir, 'checkpoint.pth.tar'))
        if cluster_epoch == (args.cluster_epochs - 1):
            save_checkpoint(
                {
                    'state_dict': model.state_dict(),
                    'epoch': cluster_epoch + 1,
                    'best_top1': best_top1,
                    'cluster_epoch': cluster_epoch + 1,
                },
                False,
                fpath=osp.join(args.logs_dir, 'latest.pth.tar'))

        print('\n * cluster_epoch: {:3d} top1: {:5.1%}  best: {:5.1%}{}\n'.
              format(cluster_epoch, top1, best_top1, ' *' if is_best else ''))

    # Final test
    print('Test with best model:')
    checkpoint = load_checkpoint(osp.join(args.logs_dir, 'model_best.pth.tar'))
    model.load_state_dict(checkpoint['state_dict'])
    best_rank1, mAP = evaluator.evaluate(test_loader,
                                         dataset.query,
                                         dataset.gallery,
                                         metric,
                                         return_mAP=True)
Пример #17
0
def main(args):
    np.random.seed(args.seed) # With the seed reset (every time), the same set of numbers will appear every time.
    torch.manual_seed(args.seed) # Sets the seed for generating random numbers.
    cudnn.benchmark = True # This flag allows you to enable the inbuilt cudnn auto-tuner to find the best algorithm to use for your hardware. It enables benchmark mode in cudnn.

    # Redirect print to both console and log file
    sys.stdout = Logger(osp.join(args.logs_dir, 'log.txt'))
    print(args)
    shutil.copy(sys.argv[0], osp.join(args.logs_dir,
                                      osp.basename(sys.argv[0])))

    # Create data loaders
    if args.height is None or args.width is None:
        args.height, args.width = (256, 128)
    dataset, num_classes, train_loader, val_loader, test_loader = \
        get_data(args.dataset, args.split, args.data_dir, args.height,
                 args.width, args.batch_size * 8, args.workers, #https://deeplizard.com/learn/video/kWVgvsejXsE#:~:text=The%20num_workers%20attribute%20tells%20the,sequentially%20inside%20the%20main%20process.
                 )

    # Create model
    model = models.create("ft_net_inter",
                          num_classes=num_classes, stride=args.stride)

    # Load from checkpoint
    start_epoch = 0
    best_top1 = 0
    top1 = 0
    is_best = False
    if args.checkpoint is not None:
        if args.evaluate:
            checkpoint = load_checkpoint(args.checkpoint)
            param_dict = model.state_dict() # A state_dict is simply a Python dictionary object that maps each layer to its parameter tensor.
            for k, v in checkpoint['state_dict'].items():
                if 'model' in k:
                    param_dict[k] = v
            model.load_state_dict(param_dict)
        else:
            model.model.load_param(args.checkpoint)
    model = model.cuda()

    # Distance metric
    metric = None

    # Evaluator
    evaluator = Evaluator(model, use_cpu=args.use_cpu)
    if args.evaluate:
        print("Test:")
        evaluator.evaluate(test_loader, dataset.query, dataset.gallery, metric)
        return

    train_transformer = [
        T.Resize((args.height, args.width), interpolation=3),
        T.RandomHorizontalFlip(),
        T.Pad(10),
        T.RandomCrop((args.height, args.width)),
        T.ToTensor(),
        T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
        T.RandomErasing(probability=0.5),
    ]
    train_transformer = T.Compose(train_transformer)
    for cluster_epoch in range(args.cluster_epochs):
        # -------------------------Stage 1 intra camera training--------------------------
        # Cluster and generate new dataset and model
        # Divides the training set into (subsets) and according to that each camera id is there for each image
        # then it forms clustering on each subset according to the pair wise similarity
        # then assigning images with in each cluster with identical label 
        # then cross entropy loss is used 
        cluster_result = get_intra_cam_cluster_result(model, train_loader,
                                                      args.class_number_stage1,
                                                      args.linkage)
        cluster_datasets = [
            datasets.create("cluster", osp.join(args.data_dir, args.dataset),
                            cluster_result[cam_id], cam_id)
            for cam_id in cluster_result.keys()
        ]

        cluster_dataloaders = [
            DataLoader(Preprocessor(dataset.train_set,
                                    root=dataset.images_dir,
                                    transform=train_transformer),
                       batch_size=args.batch_size,
                       num_workers=args.workers,
                       shuffle=True,
                       pin_memory=False,
                       drop_last=True) for dataset in cluster_datasets
        ]
        param_dict = model.model.state_dict()
        model = models.create("ft_net_intra",
                              num_classes=[
                                  args.class_number_stage1
                                  for cam_id in cluster_result.keys()
                              ],
                              stride=args.stride)

        model_param_dict = model.model.state_dict()
        for k, v in model_param_dict.items():
            if k in param_dict.keys():
                model_param_dict[k] = param_dict[k]
        model.model.load_state_dict(model_param_dict)

        model = model.cuda()
        criterion = nn.CrossEntropyLoss().cuda()

        # Optimizer
        param_groups = make_params(model, args.lr, args.weight_decay)
        optimizer = torch.optim.SGD(param_groups, momentum=0.9)
        # Trainer
        trainer = IntraCameraTrainer(
            model, criterion, warm_up_epoch=args.warm_up)
        print("start training")
        # Start training
        for epoch in range(0, args.epochs_stage1):
            trainer.train(cluster_epoch,
                          epoch,
                          cluster_dataloaders,
                          optimizer,
                          print_freq=args.print_freq,
                          )
        # -------------------------------------------Stage 2 inter camera training-----------------------------------
        mix_rate = get_mix_rate(
            args.mix_rate, cluster_epoch, args.cluster_epochs, power=args.decay_factor)

        cluster_result = get_inter_cam_cluster_result(
            model,
            train_loader,
            args.class_number_stage2,
            args.linkage,
            mix_rate,
            use_cpu=args.use_cpu)

        cluster_dataset = datasets.create(
            "cluster", osp.join(args.data_dir, args.dataset), cluster_result,
            0)

        cluster_dataloaders = DataLoader(
            Preprocessor(cluster_dataset.train_set,
                         root=cluster_dataset.images_dir,
                         transform=train_transformer),
            batch_size=args.batch_size_stage2,
            num_workers=args.workers,
            sampler=RandomIdentitySampler(cluster_dataset.train_set,
                                          args.batch_size_stage2,
                                          args.instances),
            pin_memory=False,
            drop_last=True)

        param_dict = model.model.state_dict()
        model = models.create("ft_net_inter",
                              num_classes=args.class_number_stage2,
                              stride=args.stride)
        model.model.load_state_dict(param_dict)

        model = model.cuda()
        # Criterion
        criterion_entropy = nn.CrossEntropyLoss().cuda()
        criterion_triple = TripletLoss(margin=args.margin).cuda()

        # Optimizer
        param_groups = make_params(model,
                                   args.lr * args.batch_size_stage2 / 32,
                                   args.weight_decay)

        optimizer = torch.optim.SGD(param_groups, momentum=0.9)
        # Trainer
        trainer = InterCameraTrainer(model,
                                     criterion_entropy,
                                     criterion_triple,
                                     warm_up_epoch=args.warm_up,
                                     )

        print("start training")
        # Start training
        for epoch in range(0, args.epochs_stage2):
            trainer.train(cluster_epoch,
                          epoch,
                          cluster_dataloaders,
                          optimizer,
                          print_freq=args.print_freq)
        if (cluster_epoch + 1) % 5 == 0: # in 4th, 9th, 14th epochs, see in the output

            evaluator = Evaluator(model, use_cpu=args.use_cpu)
            top1, mAP = evaluator.evaluate(
                test_loader, dataset.query, dataset.gallery, metric, return_mAP=True)

            is_best = top1 > best_top1
            best_top1 = max(top1, best_top1)

            save_checkpoint(
                {
                    'state_dict': model.state_dict(),
                    'epoch': cluster_epoch + 1,
                    'best_top1': best_top1,
                    'cluster_epoch': cluster_epoch + 1,
                },
                is_best,
                fpath=osp.join(args.logs_dir, 'checkpoint.pth.tar'))
        if cluster_epoch == (args.cluster_epochs - 1):
            save_checkpoint(
                {
                    'state_dict': model.state_dict(),
                    'epoch': cluster_epoch + 1,
                    'best_top1': best_top1,
                    'cluster_epoch': cluster_epoch + 1,
                },
                False,
                fpath=osp.join(args.logs_dir, 'latest.pth.tar'))

        print('\n * cluster_epoch: {:3d} top1: {:5.1%}  best: {:5.1%}{}\n'.
              format(cluster_epoch, top1, best_top1, ' *' if is_best else ''))

    # Final test
    print('Test with best model:')
    checkpoint = load_checkpoint(osp.join(args.logs_dir, 'model_best.pth.tar'))
    model.load_state_dict(checkpoint['state_dict'])
    best_rank1, mAP = evaluator.evaluate(
        test_loader, dataset.query, dataset.gallery, metric, return_mAP=True)