def __init__(self,
              margin=0.2,
              nu=0.0,
              weight=None,
              batch_axis=0,
              **kwargs):
     super(MarginLoss, self).__init__()
     self.margin = margin
     self.nu = nu
     self.pdist = PairwiseDistance(2)
     self.weight = weight
class MarginLoss(Function):
    r"""Margin based loss.
    Parameters
    ----------
    margin : float
        Margin between positive and negative pairs.
    nu : float
        Regularization parameter for beta.
    Inputs:
        - anchors: sampled anchor embeddings.
        - positives: sampled positive embeddings.
        - negatives: sampled negative embeddings.
        - beta_in: class-specific betas.
        - a_indices: indices of anchors. Used to get class-specific beta.
    Outputs:
        - Loss.
    """
    def __init__(self,
                 margin=0.2,
                 nu=0.0,
                 weight=None,
                 batch_axis=0,
                 **kwargs):
        super(MarginLoss, self).__init__()
        self.margin = margin
        self.nu = nu
        self.pdist = PairwiseDistance(2)
        self.weight = weight

    def forward(self, anchors, positives, negatives, beta_in, a_indices=None):
        if a_indices is not None:
            #确认beta_in是否需要是variable
            # Jointly train class-specific beta.
            beta = beta_in.index_select(0, a_indices)
            beta_reg_loss = torch.sum(beta) * self.nu
        else:
            # Use a constant beta.
            beta = beta_in
            beta_reg_loss = 0.0

        d_p = self.pdist.forward(anchors, positives)
        d_n = self.pdist.forward(anchors, negatives)
        #         d_ap = F.sqrt(F.sum(F.square(positives - anchors), axis=1) + 1e-8)
        #         d_an = F.sqrt(F.sum(F.square(negatives - anchors), axis=1) + 1e-8)
        pos_loss = torch.clamp(self.margin + d_p - beta, min=0.0)
        neg_loss = torch.clamp(self.margin - d_n + beta, min=0.0)

        pair_cnt = float(
            np.sum((pos_loss.cpu().data.numpy() > 0.0) +
                   (neg_loss.cpu().data.numpy() > 0.0)))
        # Normalize based on the number of pairs.
        loss = (torch.sum(torch.pow(pos_loss, 2) + torch.pow(neg_loss, 2)) +
                beta_reg_loss) / pair_cnt
        if self.weight:
            loss = loss * self.weight
        return loss
Exemplo n.º 3
0
class TripletSoftMarginLoss(Function):
    def __init__(self):
        super(TripletSoftMarginLoss).__init__()
        self.pdist = PairwiseDistance(2)
        self.activion = torch.nn.Softplus()

    def forward(self, anchor, positive, negative):
        d_p = self.pdist.forward(anchor, positive)
        d_n = self.pdist.forward(anchor, negative)

        dist_hinge = torch.clamp(self.activion(d_p) + d_p - d_n, min=0.0)
        loss = torch.mean(dist_hinge)
        return loss
Exemplo n.º 4
0
class TripletMarginLoss(Function):
    """Triplet loss function.
    """
    def __init__(self, margin):
        super(TripletMarginLoss, self).__init__()
        self.margin = margin
        self.pdist = PairwiseDistance(2)  # norm 2

    def forward(self, anchor, positive, negative):
        d_p = self.pdist.forward(anchor, positive)
        d_n = self.pdist.forward(anchor, negative)

        dist_hinge = torch.clamp(self.margin + d_p - d_n, min=0.0)
        loss = torch.mean(dist_hinge)
        return loss
Exemplo n.º 5
0
    def __init__(self, cfg, model, dataloader=None, transform=None):
        """Initializer model

        Arguments:
            cfg {[type]} -- [description]
            model {[type]} -- [description]
            dataloader {[type]} -- [description]
        """
        self.cfg = cfg
        self.model = model
        self.dataloader = dataloader
        self.device = torch.device(
            "cuda" if torch.cuda.is_available() else "cpu")
        self.dataprocess = None
        self.l2_dist = PairwiseDistance()
        self.transform = transform
Exemplo n.º 6
0
 def __init__(self, margin):
     super(TripletMarginLoss, self).__init__()
     self.margin = margin
     self.pdist = PairwiseDistance(2)  # norm 2
Exemplo n.º 7
0
            if (w <= h and w == self.size) or (h <= w and h == self.size):
                return img
            if w < h:
                ow = self.size
                oh = int(self.size * h / w)
                return img.resize((ow, oh), self.interpolation)
            else:
                oh = self.size
                ow = int(self.size * w / h)
                return img.resize((ow, oh), self.interpolation)
        else:
            return img.resize(self.size, self.interpolation)


kwargs = {'num_workers': 2, 'pin_memory': True}
l2_dist = PairwiseDistance(2)

transform = transforms.Compose([
    Scale(96),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])

train_dir = TripletFaceDataset(dir=args.dataroot,
                               n_triplets=args.n_triplets,
                               transform=transform)
train_loader = torch.utils.data.DataLoader(train_dir,
                                           batch_size=args.batch_size,
                                           shuffle=False,
                                           **kwargs)
Exemplo n.º 8
0
def train_epoch_some(train_loader, model, loss_fn, optimizer, cuda,
                     log_interval, metrics):
    for metric in metrics:
        metric.reset()

    model.train()
    losses = []
    total_loss = 0
    pbar = tqdm(enumerate(train_loader))
    labels, distances = [], []
    l2_dist = PairwiseDistance(2)

    for batch_idx, (data_a, data_p, data_n, label_p, label_n) in pbar:

        data_a, data_p, data_n = data_a.cuda(), data_p.cuda(), data_n.cuda()
        data_a, data_p, data_n = Variable(data_a), Variable(data_p), \
                                 Variable(data_n)

        # compute output
        out_a, out_p, out_n = model(data_a), model(data_p), model(data_n)

        # Choose the hard negatives
        d_p = l2_dist.forward(out_a, out_p)
        d_n = l2_dist.forward(out_a, out_n)
        all = (d_n - d_p < args.margin).cpu().data.numpy().flatten()
        hard_triplets = np.where(all == 1)
        if len(hard_triplets[0]) == 0:
            continue
        out_selected_a = Variable(
            torch.from_numpy(out_a.cpu().data.numpy()[hard_triplets]).cuda())
        out_selected_p = Variable(
            torch.from_numpy(out_p.cpu().data.numpy()[hard_triplets]).cuda())
        out_selected_n = Variable(
            torch.from_numpy(out_n.cpu().data.numpy()[hard_triplets]).cuda())

        selected_data_a = Variable(
            torch.from_numpy(data_a.cpu().data.numpy()[hard_triplets]).cuda())
        selected_data_p = Variable(
            torch.from_numpy(data_p.cpu().data.numpy()[hard_triplets]).cuda())
        selected_data_n = Variable(
            torch.from_numpy(data_n.cpu().data.numpy()[hard_triplets]).cuda())

        selected_label_p = torch.from_numpy(
            label_p.cpu().numpy()[hard_triplets])
        selected_label_n = torch.from_numpy(
            label_n.cpu().numpy()[hard_triplets])
        triplet_loss = loss_fn.forward(out_selected_a, out_selected_p,
                                       out_selected_n)

        cls_a = model.forward_classifier(selected_data_a)
        cls_p = model.forward_classifier(selected_data_p)
        cls_n = model.forward_classifier(selected_data_n)

        cls_a = model.forward_classifier(selected_data_a)
        cls_p = model.forward_classifier(selected_data_p)
        cls_n = model.forward_classifier(selected_data_n)

        criterion = nn.CrossEntropyLoss()
        predicted_labels = torch.cat([cls_a, cls_p, cls_n])
        true_labels = torch.cat([
            Variable(selected_label_p.cuda()),
            Variable(selected_label_p.cuda()),
            Variable(selected_label_n.cuda())
        ])

        cross_entropy_loss = criterion(predicted_labels.cuda(),
                                       true_labels.cuda())

        loss = cross_entropy_loss + triplet_loss
        # compute gradient and update weights
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        # update the optimizer learning rate
        adjust_learning_rate(optimizer)
Exemplo n.º 9
0
def experimenter(data_name='cora',
                 train_ratio=0.03,
                 cuda=True,
                 random_seed=42,
                 hidden=16,
                 dropout_ratio=0.5,
                 learning_rate=0.01,
                 weight_decay=5e-4,
                 num_epochs=65,
                 early_stopping=30,
                 task='classification',
                 public_splitting=False):
    # helper function to run epxeriment
    if data_name in ['cora', 'citeseer', 'pubmed']:
        print("Loading Classification Datasets")
        Tmat, eadj, edge_name, edge_feature_dict, adj, features, edge_features, labels, idx_train, idx_val, idx_test = tqdm(
            load_data(data_name=data_name,
                      train_ratio=train_ratio,
                      public_splitting=public_splitting))
        model = GCN(nfeat_v=features.shape[1],
                    nfeat_e=edge_features.shape[1],
                    nhid=hidden,
                    nclass=labels.max().item() + 1,
                    dropout=dropout_ratio)

        ssl_agent_n = PairwiseDistance(adj,
                                       features,
                                       nhid=args.hidden,
                                       cuda=cuda,
                                       node=True)
        ssl_agent_e = PairwiseDistance(eadj,
                                       edge_features,
                                       nhid=args.hidden,
                                       cuda=cuda,
                                       node=False)

    else:
        ValueError("The input data is not supported! ")
    print(">" * 100)
    print("Loaded and preprocessed the graph data! ")
    print(">" * 100)
    optimizer = optim.Adam(model.parameters(),
                           lr=learning_rate,
                           weight_decay=weight_decay)

    np.random.seed(random_seed)
    torch.manual_seed(random_seed)

    if cuda:
        torch.cuda.manual_seed(random_seed)
        torch.set_default_tensor_type('torch.cuda.FloatTensor')

    if cuda:
        model.cuda()
        Tmat = Tmat.cuda()
        eadj = eadj.cuda()
        adj = adj.cuda()
        features = features.cuda()
        edge_features = edge_features.cuda()
        labels = labels.cuda()
        idx_train = idx_train.cuda()
        idx_val = idx_val.cuda()
        idx_test = idx_test.cuda()
        # pooling = pooling.cuda()
        # node_count = node_count.cuda()

    if task == "classification":
        criteria = F.nll_loss
        acc_measure = accuracy
    elif task == "regression":
        criteria = torch.nn.L1Loss
        acc_measure = RMSELoss
    # ---------------------------------------
    # training function
    # ---------------------------------------
    # count_time = 0

    def train(epoch):
        t = time.time()
        model.train()
        optimizer.zero_grad()
        output, n_feature, e_feature = model(features, edge_features, eadj,
                                             adj, Tmat, task)

        loss_n = ssl_agent_n.classification_loss(n_feature)
        loss_e = ssl_agent_e.classification_loss(e_feature)
        loss_train = criteria(output[idx_train], labels[idx_train])
        loss_train = loss_train + 0.1 * loss_n + 0.1 * loss_e
        acc_train = acc_measure(output[idx_train], labels[idx_train])

        loss_train.backward()
        optimizer.step()

        if not args.fastmode:
            # Evaluate validation set performance separately,
            # deactivates dropout during validation run.
            model.eval()
            output, _, _ = model(features, edge_features, eadj, adj, Tmat,
                                 task)

        loss_val = criteria(output[idx_val], labels[idx_val])
        acc_val = acc_measure(output[idx_val], labels[idx_val])
        print('Epoch: {:04d}'.format(epoch + 1),
              'loss_train: {:.4f}'.format(loss_train.item()),
              'acc_train: {:.4f}'.format(acc_train.item()),
              'loss_val: {:.4f}'.format(loss_val.item()),
              'acc_val: {:.4f}'.format(acc_val.item()),
              'time: {:.4f}s'.format(time.time() - t))
        return loss_val.item()

    # -------------------------------------------
    # testing function
    # -------------------------------------------
    def test():
        model.eval()
        output, _, _ = model(features, edge_features, eadj, adj, Tmat, task)
        loss_test = criteria(output[idx_test], labels[idx_test])
        acc_test = acc_measure(output[idx_test], labels[idx_test])
        print("Test set results:", "loss= {:.4f}".format(loss_test.item()),
              "accuracy= {:.4f}".format(acc_test.item()))
        return acc_test.item()

    def pretrain(epoch):
        t = time.time()
        model.train()
        optimizer.zero_grad()
        output, node_f, edge_f = model(features, edge_features, eadj, adj,
                                       Tmat, task)

        loss_n = ssl_agent_n.classification_loss(node_f)
        loss_e = ssl_agent_e.classification_loss(edge_f)
        # loss_train = criteria(output[idx_train], labels[idx_train])
        loss_train = loss_n + loss_e
        acc_train = acc_measure(output[idx_train], labels[idx_train])

        loss_train.backward()
        optimizer.step()

        if not args.fastmode:
            # Evaluate validation set performance separately,
            # deactivates dropout during validation run.
            model.eval()
            output, _, _ = model(features, edge_features, eadj, adj, Tmat,
                                 task)

        loss_val = criteria(output[idx_val], labels[idx_val])
        acc_val = acc_measure(output[idx_val], labels[idx_val])
        print('Epoch: {:04d}'.format(epoch + 1),
              'loss_train: {:.4f}'.format(loss_train.item()),
              'acc_train: {:.4f}'.format(acc_train.item()),
              'loss_val: {:.4f}'.format(loss_val.item()),
              'acc_val: {:.4f}'.format(acc_val.item()),
              'time: {:.4f}s'.format(time.time() - t))
        return loss_val.item()

    # Train model
    t_total = time.time()
    val_watch = []
    pre_val_watch = []
    input_idx_train = idx_train
    # for epoch in range(50):
    #     pre_val_watch.append(pretrain(epoch))
    #     test()
    #     if epoch > early_stopping and pre_val_watch[-1] > np.mean(pre_val_watch[-(early_stopping + 1):-1]):
    #         print("Early stopping...")
    #         break
    for epoch in range(num_epochs):
        # val_adj, val_fea = ssl_agent.transform_data()

        val_watch.append(train(epoch))
        test()
        if epoch > early_stopping and val_watch[-1] > np.mean(
                val_watch[-(early_stopping + 1):-1]):
            print("Early stopping...")
            break
    print("Optimization Finished!")
    print("Total time elapsed: {:.4f}s".format(time.time() - t_total))
    print("Printing the weights : ")

    return test()
Exemplo n.º 10
0
def select_three_sample(model, args, epoch, writer):
    model.eval()
    num_each_class = [500, 500, 500, 500, 500, 500, 500, 50, 50, 50]
    # num_each_class = [500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500]
    transform = transforms.Compose([
        transforms.Resize(32),
        transforms.ToTensor(),
        transforms.Normalize(mean=np.array([0.485, 0.456, 0.406]),
                             std=np.array([0.229, 0.224, 0.225])),
    ])
    train_set = torchvision.datasets.ImageFolder(root=args.train_set,
                                                 transform=transform)
    train_loader = torch.utils.data.DataLoader(train_set,
                                               batch_size=args.test_batch_size,
                                               shuffle=False)

    NearestCentroid, KNeighbors, features, label, labels = [], [], [], [], []
    for i, (data, target) in enumerate(train_loader):
        data, target = data.cuda(), target.cuda()
        data, target = Variable(data), Variable(target)
        output = model(data)
        features.extend(output.data)
        KNeighbors.extend(output.data.cpu().numpy())
        labels.extend(target.data.cpu().numpy())

    count = 0
    l2_dist = PairwiseDistance(2)
    destination = os.path.join(args.check_path, 'epoch' + str(epoch))
    if not os.path.exists(destination):
        os.mkdir(destination)
    for i in range(len(num_each_class)):
        num_sample = features[count:count + num_each_class[i]]
        m = torch.tensor(np.zeros(args.embedding_size)).float().cuda()
        for x in num_sample:
            m += x
        m /= num_each_class[i]

        sample1 = min(num_sample, key=lambda x: l2_dist.forward_val(x, m))
        sample2 = max(num_sample,
                      key=lambda x: l2_dist.forward_val(x, sample1))
        sample3 = max(num_sample,
                      key=lambda x: l2_dist.forward_val(x, sample2))
        NearestCentroid.append(sample1.cpu().numpy())
        label.append(i)

        sample1_loc, sample2_loc, sample3_loc = -1, -1, -1
        for j in range(num_sample.__len__()):
            if (num_sample[j] == sample1).all():
                sample1_loc = j
            if (num_sample[j] == sample2).all():
                sample2_loc = j
            if (num_sample[j] == sample3).all():
                sample3_loc = j

        frame = pd.read_csv(args.train_set_csv)
        destination_class = os.path.join(
            destination, str(frame['name'][count + sample1_loc]))
        if not os.path.exists(destination_class):
            os.mkdir(destination_class)
        sample1_source = os.path.join(
            args.train_set, str(frame['name'][count + sample1_loc]),
            str(frame['id'][count + sample1_loc]) + '.png')
        sample2_source = os.path.join(
            args.train_set, str(frame['name'][count + sample2_loc]),
            str(frame['id'][count + sample2_loc]) + '.png')
        sample3_source = os.path.join(
            args.train_set, str(frame['name'][count + sample3_loc]),
            str(frame['id'][count + sample3_loc]) + '.png')
        shutil.copy(sample1_source, destination_class + '/sample1.png')
        shutil.copy(sample2_source, destination_class + '/sample2.png')
        shutil.copy(sample3_source, destination_class + '/sample3.png')
        count += num_each_class[i]

    clf = neighbors.NearestCentroid()
    clf.fit(NearestCentroid, label)

    return features, labels, clf, destination
Exemplo n.º 11
0
args.cuda = not args.no_cuda and torch.cuda.is_available()
np.random.seed(args.seed)

if not os.path.exists(args.log_dir):
    os.makedirs(args.log_dir)

if args.cuda:
    cudnn.benchmark = True

LOG_DIR = args.log_dir + '/run-optim_{}-lr{}-wd{}-embeddings{}-center{}-MSCeleb'.format(args.optimizer, args.lr, args.wd,args.embedding_size,args.center_loss_weight)

# create logger
logger = Logger(LOG_DIR)

kwargs = {'num_workers': 2, 'pin_memory': True} if args.cuda else {}
l2_dist = PairwiseDistance(2)

transform = transforms.Compose([
                         transforms.Scale(96),
                         transforms.RandomHorizontalFlip(),
                         transforms.ToTensor(),
                         transforms.Normalize(mean = [ 0.5, 0.5, 0.5 ],
                                               std = [ 0.5, 0.5, 0.5 ])
                     ])

train_dir = ImageFolder(args.dataroot,transform=transform)
testacc_dir = ImageFolder(args.testdataroot,transform=transform)
train_loader = torch.utils.data.DataLoader(train_dir,
    batch_size=args.batch_size, shuffle=True, **kwargs)

testaccuracy_loader = torch.utils.data.DataLoader(testacc_dir,
Exemplo n.º 12
0
def main():
    parser = argparse.ArgumentParser(
        description='Classifiar using triplet loss.')
    parser.add_argument('--CVDs',
                        type=str,
                        default='0,1,2,3',
                        metavar='CUDA_VISIBLE_DEVICES',
                        help='CUDA_VISIBLE_DEVICES')
    parser.add_argument(
        '--train-set',
        type=str,
        default='/home/zili/memory/FaceRecognition-master/data/mnist/train',
        metavar='dir',
        help='path of train set.')
    parser.add_argument(
        '--test-set',
        type=str,
        default='/home/zili/memory/FaceRecognition-master/data/mnist/test',
        metavar='dir',
        help='path of test set.')
    parser.add_argument(
        '--train-set-csv',
        type=str,
        default='/home/zili/memory/FaceRecognition-master/data/mnist/train.csv',
        metavar='file',
        help='path of train set.csv.')
    parser.add_argument(
        '--test-set-csv',
        type=str,
        default='/home/zili/memory/FaceRecognition-master/data/mnist/test.csv',
        metavar='file',
        help='path of test set.csv.')
    parser.add_argument('--num-triplet',
                        type=int,
                        default=10000,
                        metavar='N',
                        help='number of triplet in dataset (default: 32)')
    parser.add_argument('--train-batch-size',
                        type=int,
                        default=256,
                        metavar='N',
                        help='input batch size for training (default: 32)')
    parser.add_argument('--test-batch-size',
                        type=int,
                        default=512,
                        metavar='N',
                        help='input batch size for testing (default: 64)')
    parser.add_argument('--epochs',
                        type=int,
                        default=100,
                        metavar='N',
                        help='number of epochs to train (default: 100)')
    parser.add_argument('--embedding-size',
                        type=int,
                        default=256,
                        metavar='N',
                        help='embedding size of model (default: 256)')
    parser.add_argument('--lr',
                        type=float,
                        default=0.05,
                        metavar='LR',
                        help='learning rate (default: 0.01)')
    parser.add_argument('--margin',
                        type=float,
                        default=1.0,
                        metavar='margin',
                        help='loss margin (default: 1.0)')
    parser.add_argument('--kneighbor',
                        type=int,
                        default=20,
                        metavar='N',
                        help='how many neighbor in testing')
    parser.add_argument('--num-classes',
                        type=int,
                        default=10,
                        metavar='N',
                        help='classes number of dataset')
    parser.add_argument('--momentum',
                        type=float,
                        default=0.8,
                        metavar='M',
                        help='SGD momentum (default: 0.9)')
    parser.add_argument('--seed',
                        type=int,
                        default=1,
                        metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument(
        '--log-interval',
        type=int,
        default=4,
        metavar='N',
        help='how many batches to wait before logging training status')
    parser.add_argument('--model-name',
                        type=str,
                        default='resnet34',
                        metavar='M',
                        help='model name (default: resnet34)')
    parser.add_argument('--dropout-p',
                        type=float,
                        default=0.2,
                        metavar='D',
                        help='Dropout probability (default: 0.2)')
    parser.add_argument('--check-path',
                        type=str,
                        default='checkpoints3',
                        metavar='C',
                        help='Checkpoint path')
    parser.add_argument(
        '--is-semihard',
        type=bool,
        default=True,
        metavar='R',
        help='whether the dataset is selected in semi-hard way.')
    parser.add_argument('--is-pretrained',
                        type=bool,
                        default=False,
                        metavar='R',
                        help='whether model is pretrained.')

    args = parser.parse_args()
    os.environ["CUDA_VISIBLE_DEVICES"] = args.CVDs

    output1 = 'main' + str(datetime.datetime.now())
    f = open(args.check_path + os.path.sep + output1 + '.txt', 'w+')

    l2_dist = PairwiseDistance(2)
    writer = SummaryWriter()

    print('Loading model...')

    model = FaceModel(embedding_size=args.embedding_size,
                      num_classes=args.num_classes,
                      pretrained=args.is_pretrained)
    f.write("            model: {}".format(model.model) + '\r\n')

    if torch.cuda.is_available():
        model = torch.nn.DataParallel(model).cuda()
        cudnn.benchmark = True

    optimizer = optim.SGD(model.parameters(),
                          lr=args.lr,
                          momentum=args.momentum,
                          weight_decay=1e-5)

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

    print('start training...')
    features, labels, clf = feature(model, args)

    for epoch in range(args.epochs):
        if epoch % 5 == 0:
            file_operation(f, args, optimizer)

        if (epoch + 1) % 2 == 0:
            args.lr = args.lr / 3
            update_lr(optimizer, args.lr)

        generate_csv(args)
        train(epoch, model, optimizer, args, f, writer, features)
        features, labels, clf = feature(model, args)
        validate(epoch, model, clf, args, f, writer)

        f.write('\r\n')
    torch.save(model, args.check_path + os.path.sep + output1 + '.pkl')
Exemplo n.º 13
0
    def generate_triplets(df, ps, num_triplets, features, preserved_features,
                          margin):
        def make_dictionary_for_face_class(df):
            '''
              - face_classes = {'class0': [class0_id0, ...], 'class1': [class1_id0, ...], ...}
            '''
            face_classes = dict()
            for idx, label in enumerate(df['class']):
                if label not in face_classes:
                    face_classes[label] = []
                face_classes[label].append(df.iloc[idx, 0])
            return face_classes

        triplets = []
        classes = ps['class'].unique()
        face_classes = make_dictionary_for_face_class(df)
        preserved_image = make_dictionary_for_face_class(ps)
        i = 0
        now_time = datetime.datetime.now()
        while i < num_triplets + 1:
            '''
              - all three image is selected from new train set
            '''

            pos_class = np.random.choice([7, 8, 9])
            neg_class = np.random.choice([7, 8, 9])
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice([7, 8, 9])
            while pos_class == neg_class:
                neg_class = np.random.choice([7, 8, 9])

            pos_name = df.loc[df['class'] == pos_class, 'name'].values[0]
            neg_name = df.loc[df['class'] == neg_class, 'name'].values[0]

            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(face_classes[pos_class]))
                ipos = np.random.randint(0, len(face_classes[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0, len(face_classes[pos_class]))
            ineg = np.random.randint(0, len(face_classes[neg_class]))

            triplets.append([
                face_classes[pos_class][ianc], face_classes[pos_class][ipos],
                face_classes[neg_class][ineg], pos_class, neg_class, pos_name,
                neg_name, 1, 1, 1
            ])
            i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets + 1:
            '''
                - all three images are selected from preserved images
            '''
            pos_class = np.random.choice(classes)
            neg_class = np.random.choice(classes)
            while len(preserved_image[pos_class]) < 2:
                pos_class = np.random.choice(classes)
            while pos_class == neg_class:
                neg_class = np.random.choice(classes)

            pos_name = ps.loc[ps['class'] == pos_class, 'name'].values[0]
            neg_name = ps.loc[ps['class'] == neg_class, 'name'].values[0]

            if len(preserved_image[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(preserved_image[pos_class]))
                ipos = np.random.randint(0, len(preserved_image[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0,
                                             len(preserved_image[pos_class]))
            ineg = np.random.randint(0, len(preserved_image[neg_class]))

            triplets.append([
                preserved_image[pos_class][ianc],
                preserved_image[pos_class][ipos],
                preserved_image[neg_class][ineg], pos_class, neg_class,
                pos_name, neg_name, 2, 2, 2
            ])
            i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets + 1:
            '''
                -a and p are from preserved images
                -n is from new train set
            '''
            pos_class = np.random.choice(classes)
            neg_class = np.random.choice([7, 8, 9])
            while len(preserved_image[pos_class]) < 2:
                pos_class = np.random.choice(classes)
            while pos_class == neg_class:
                neg_class = np.random.choice([7, 8, 9])

            pos_name = ps.loc[ps['class'] == pos_class, 'name'].values[0]
            neg_name = df.loc[df['class'] == neg_class, 'name'].values[0]

            if len(preserved_image[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(preserved_image[pos_class]))
                ipos = np.random.randint(0, len(preserved_image[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0,
                                             len(preserved_image[pos_class]))
            ineg = np.random.randint(0, len(face_classes[neg_class]))

            a_position = pos_class * 3 + ianc
            p_position = pos_class * 3 + ipos
            n_position = \
                df.loc[df['class'] == neg_class, 'id'].ix[df['id'] == face_classes[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(preserved_features[a_position],
                                     preserved_features[p_position])
            dn = l2_dist.forward_val(preserved_features[a_position],
                                     features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    preserved_image[pos_class][ianc],
                    preserved_image[pos_class][ipos],
                    face_classes[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name, 2, 2, 1
                ])
                i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets + 1:
            '''
                -a is from preserved images
                -p and n are from new train set
            '''

            pos_class = np.random.choice([7, 8, 9])
            neg_class = np.random.choice([7, 8, 9])
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice([7, 8, 9])
            while pos_class == neg_class:
                neg_class = np.random.choice([7, 8, 9])

            pos_name = ps.loc[ps['class'] == pos_class, 'name'].values[0]
            neg_name = df.loc[df['class'] == neg_class, 'name'].values[0]

            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(preserved_image[pos_class]))
                ipos = np.random.randint(0, len(face_classes[pos_class]))
            ineg = np.random.randint(0, len(face_classes[neg_class]))

            a_position = \
                ps.loc[ps['class'] == pos_class, 'id'].ix[ps['id'] == preserved_image[pos_class][ianc]].index.values[0]
            p_position = \
                df.loc[df['class'] == pos_class, 'id'].ix[df['id'] == face_classes[pos_class][ipos]].index.values[0]
            n_position = \
                df.loc[df['class'] == neg_class, 'id'].ix[df['id'] == face_classes[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(preserved_features[a_position],
                                     features[p_position])
            dn = l2_dist.forward_val(preserved_features[a_position],
                                     features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    preserved_image[pos_class][ianc],
                    face_classes[pos_class][ipos],
                    face_classes[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name, 2, 1, 1
                ])
                i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets:
            '''
                -a and p are from new train set
                -n is from pre 
            '''

            pos_class = np.random.choice([7, 8, 9])
            neg_class = np.random.choice(classes)
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice([7, 8, 9])
            while pos_class == neg_class:
                neg_class = np.random.choice(classes)

            pos_name = df.loc[df['class'] == pos_class, 'name'].values[0]
            neg_name = ps.loc[ps['class'] == neg_class, 'name'].values[0]

            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(face_classes[pos_class]))
                ipos = np.random.randint(0, len(face_classes[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0, len(face_classes[pos_class]))
            ineg = np.random.randint(0, len(preserved_image[neg_class]))

            a_position = \
                df.loc[df['class'] == pos_class, 'id'].ix[df['id'] == face_classes[pos_class][ianc]].index.values[0]
            p_position = \
                df.loc[df['class'] == pos_class, 'id'].ix[df['id'] == face_classes[pos_class][ipos]].index.values[0]
            n_position = \
                ps.loc[ps['class'] == neg_class, 'id'].ix[ps['id'] == preserved_image[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(features[a_position],
                                     features[p_position])
            dn = l2_dist.forward_val(features[a_position],
                                     preserved_features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    face_classes[pos_class][ianc],
                    face_classes[pos_class][ipos],
                    preserved_image[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name, 1, 1, 2
                ])
                i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets:
            '''
                -a is from new train set
                -p and n is from pre 
            '''

            pos_class = np.random.choice([7, 8, 9])
            neg_class = np.random.choice(classes)
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice([7, 8, 9])
            while pos_class == neg_class:
                neg_class = np.random.choice(classes)

            pos_name = df.loc[df['class'] == pos_class, 'name'].values[0]
            neg_name = ps.loc[ps['class'] == neg_class, 'name'].values[0]

            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(face_classes[pos_class]))
                ipos = np.random.randint(0, len(preserved_image[pos_class]))
            ineg = np.random.randint(0, len(preserved_image[neg_class]))

            a_position = \
                df.loc[df['class'] == pos_class, 'id'].ix[df['id'] == face_classes[pos_class][ianc]].index.values[0]
            p_position = \
                ps.loc[ps['class'] == pos_class, 'id'].ix[ps['id'] == preserved_image[pos_class][ipos]].index.values[0]
            n_position = \
                ps.loc[ps['class'] == neg_class, 'id'].ix[ps['id'] == preserved_image[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(features[a_position],
                                     preserved_features[p_position])
            dn = l2_dist.forward_val(features[a_position],
                                     preserved_features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    face_classes[pos_class][ianc],
                    preserved_image[pos_class][ipos],
                    preserved_image[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name, 1, 2, 2
                ])
                i += 1
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        return triplets
Exemplo n.º 14
0
 def __init__(self):
     super(TripletSoftMarginLoss).__init__()
     self.pdist = PairwiseDistance(2)
     self.activion = torch.nn.Softplus()
Exemplo n.º 15
0
            if (w <= h and w == self.size) or (h <= w and h == self.size):
                return img
            if w < h:
                ow = self.size
                oh = int(self.size * h / w)
                return img.resize((ow, oh), self.interpolation)
            else:
                oh = self.size
                ow = int(self.size * w / h)
                return img.resize((ow, oh), self.interpolation)
        else:
            return img.resize(self.size, self.interpolation)


kwargs = {'num_workers': 2, 'pin_memory': True} if args.cuda else {}
l2_dist = PairwiseDistance(2) ##计算两个向量之间的标准差

transform = transforms.Compose([
                         Scale(96),
                         transforms.ToTensor(),
                         transforms.Normalize(mean = [ 0.5, 0.5, 0.5 ],
                                               std = [ 0.5, 0.5, 0.5 ])
                     ])
##args.n_triplets表示会产生多少个训练对,每个训练对有三个图片
train_dir = TripletFaceDataset(dir=args.dataroot,n_triplets=args.n_triplets,transform=transform)
train_loader = torch.utils.data.DataLoader(train_dir,
    batch_size=args.batch_size, shuffle=False, **kwargs)

test_loader = torch.utils.data.DataLoader(
    LFWDataset(dir=args.lfw_dir,pairs_path=args.lfw_pairs_path,
                     transform=transform),
Exemplo n.º 16
0
    def generate_triplets(df, num_triplets, features, margin):
        def make_dictionary_for_face_class(df):
            '''
              - face_classes = {'class0': [class0_id0, ...], 'class1': [class1_id0, ...], ...}
            '''
            face_classes = dict()
            for idx, label in enumerate(df['class']):
                if label not in face_classes:
                    face_classes[label] = []
                face_classes[label].append(df.iloc[idx, 0])
            return face_classes

        triplets = []
        classes = df['class'].unique()
        face_classes = make_dictionary_for_face_class(df)
        i = 0
        while i < num_triplets:
            '''
              - randomly choose anchor, positive and negative images for triplet loss
              - anchor and positive images in pos_class
              - negative image in neg_class
              - at least, two images needed for anchor and positive images in pos_class
              - negative image should have different class as anchor and positive images by definition
            '''

            pos_class = np.random.choice(classes)
            neg_class = np.random.choice(classes)
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice(classes)
            while pos_class == neg_class:
                neg_class = np.random.choice(classes)

            pos_name = df.loc[df['class'] == pos_class, 'name'].values[0]
            neg_name = df.loc[df['class'] == neg_class, 'name'].values[0]
            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(face_classes[pos_class]))
                ipos = np.random.randint(0, len(face_classes[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0, len(face_classes[pos_class]))
            ineg = np.random.randint(0, len(face_classes[neg_class]))

            a_position = df.loc[df['class'] == pos_class, 'id'].ix[
                df['id'] == face_classes[pos_class][ianc]].index.values[0]
            p_position = df.loc[df['class'] == pos_class, 'id'].ix[
                df['id'] == face_classes[pos_class][ipos]].index.values[0]
            n_position = df.loc[df['class'] == neg_class, 'id'].ix[
                df['id'] == face_classes[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(features[a_position],
                                     features[p_position])
            dn = l2_dist.forward_val(features[a_position],
                                     features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    face_classes[pos_class][ianc],
                    face_classes[pos_class][ipos],
                    face_classes[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name
                ])
                i += 1

        return triplets