Пример #1
0
 def __init__(self, **kwargs):
     super().__init__()
     self.margin = kwargs['margin']
     """ Computes triplet loss using all triplets """
     self.miner = miners.TripletMarginMiner(margin=1.0,
                                            type_of_triplets="all")
     self.loss = losses.TripletMarginLoss(margin=self.margin)
Пример #2
0
    def __init__(self, **kwargs):
        super().__init__()
        assert kwargs['train_type'] == 'metric_learning', "Triplet Margin Loss can only be used with metric learning."
        self.margin = kwargs['margin']

        """ Computes triplet loss using all triplets that violate the margin """
        self.miner = miners.TripletMarginMiner(margin=self.margin, type_of_triplets="all")
        self.loss = losses.TripletMarginLoss(margin=self.margin)
 def __init__(self, margin=0.1, **kwargs):
     super(TripletLoss, self).__init__()
     self.margin = margin
     self.miner = miners.TripletMarginMiner(margin,
                                            type_of_triplets='semihard')
     self.loss_func = losses.TripletMarginLoss(margin=self.margin)
Пример #4
0
def train(data, epochs, triplet_alpha, miner, alpha_pow, alpha_mul):
    device = torch.device("cpu")

    distance = distances.CosineSimilarity()
    if miner == 'batch-hard':
        mining_func = miners.BatchHardMiner(distance=distance)
    elif miner == 'hard':
        mining_func = miners.TripletMarginMiner(margin=triplet_alpha,
                                                distance=distance,
                                                type_of_triplets="hard")
    elif miner == 'semihard':
        mining_func = miners.TripletMarginMiner(margin=triplet_alpha,
                                                distance=distance,
                                                type_of_triplets="semihard")
    elif miner == 'all':
        mining_func = miners.TripletMarginMiner(margin=triplet_alpha,
                                                distance=distance,
                                                type_of_triplets="all")

    loss_func = losses.TripletMarginLoss(margin=triplet_alpha,
                                         distance=distance)

    n_templ = 18

    p_pow = torch.FloatTensor(n_templ, 1, 1).uniform_(1, 1)
    p_pow = torch.tensor(p_pow, device=device, requires_grad=True)

    p_mul = torch.FloatTensor(n_templ, 1, 1).uniform_(1, 1)
    p_mul = torch.tensor(p_mul, device=device, requires_grad=True)

    opt_mul = optim.SGD([p_mul], lr=alpha_mul)
    opt_pow = optim.SGD([p_pow], lr=alpha_pow)

    __tensors_mul = []
    __tensors_pow = []
    __loss = []

    name = "{}_{}_{}_{}".format(triplet_alpha, miner, alpha_pow, alpha_mul)
    os.mkdir('/home/y.kozhevnikov/rust/{}'.format(name))

    for epoch in range(epochs):
        epoch_losses = []
        for word in tqdm(data):
            opt_mul.zero_grad()
            opt_pow.zero_grad()
            golds, vectors = data[word]
            golds = torch.tensor(golds)
            vectors = vectors.to(device)
            vectors = unite(vectors, p_mul, p_pow)

            indices_tuple = mining_func(vectors, golds)

            loss = loss_func(vectors, golds, indices_tuple)

            epoch_losses.append(loss.item())
            loss.backward()

            opt_mul.step()
            opt_pow.step()

        print(p_mul.view(n_templ))
        print(p_pow.view(n_templ))
        __tensors_mul.append(p_mul.clone().detach())
        __tensors_pow.append(p_pow.clone().detach())
        epoch_loss = torch.mean(torch.tensor(epoch_losses))
        __loss.append(epoch_loss)
        print(epoch_loss)

    for n, t in enumerate(__tensors_mul):
        torch.save(t, "/home/y.kozhevnikov/rust/{}/mul_{}.pt".format(name, n))
    for n, t in enumerate(__tensors_pow):
        torch.save(t, "/home/y.kozhevnikov/rust/{}/pow_{}.pt".format(name, n))
    with open("/home/y.kozhevnikov/rust/{}/loss.txt".format(name), 'w') as f:
        for l in __loss:
            f.write("{}\n".format(l))

    return p_pow, p_mul
Пример #5
0
        numerical_input_dim=num_input_dim,
        cat_vocab_sizes=cat_vocab_sizes,
        cat_embedding_dim=cat_embedding_dim,
        embedding_dim=EMBEDDING_DIM,
    )
    encoder.to(device)
    encoder.train()
    optimizer = optim.Adam(encoder.parameters(), lr=LR)

    distance = distances.CosineSimilarity()
    reducer = reducers.ThresholdReducer(low=0)  # basically, returns average
    loss_func = losses.TripletMarginLoss(margin=0.4,
                                         distance=distance,
                                         reducer=reducer)
    mining_func = miners.TripletMarginMiner(margin=0.4,
                                            distance=distance,
                                            type_of_triplets="semihard")

    train_losses = train_ml_model(encoder, NUM_EPOCHS, dataloader,
                                  NUM_OF_SUBSEQUENCES, mining_func, loss_func,
                                  optimizer)
    fig, axs = plt.subplots(figsize=(12, 6))

    plt.plot(train_losses, label='train')
    plt.xlabel('iter')
    plt.ylabel('loss')
    plt.title("final accuracy: {training}")
    plt.savefig(f'plots/ML_{arch}_{EMBEDDING_DIM}_{NUM_OBS}_{NUM_EPOCHS}.png')

    SCHEDULER_EPOCHS = 2
    LR = 0.002
    def __init__(self,
                 train_dl,
                 val_dl,
                 unseen_dl,
                 model,
                 optimizer,
                 scheduler,
                 criterion,
                 mining_function,
                 loss,
                 savePath='./models/',
                 device='cuda',
                 BATCH_SIZE=64):
        self.device = device
        self.train_dl = train_dl
        self.val_dl = val_dl
        self.unseen_dl = unseen_dl
        self.BATCH_SIZE = BATCH_SIZE
        self.model = model.to(self.device)
        self.optimizer = optimizer
        self.scheduler = scheduler
        self.criterion = criterion
        self.mining_function = mining_function
        self.loss = loss
        self.distance = distances.LpDistance(normalize_embeddings=True,
                                             p=2,
                                             power=1)
        self.reducer = reducers.ThresholdReducer(low=0)
        self.regularizer = regularizers.LpRegularizer(p=2)
        if self.mining_function == 'triplet':
            self.mining_func = miners.TripletMarginMiner(
                margin=0.01,
                distance=self.distance,
                type_of_triplets="semihard")
        elif self.mining_function == 'pair':
            self.mining_func = miners.PairMarginMiner(pos_margin=0,
                                                      neg_margin=0.2)

        if self.loss == 'triplet':
            self.loss_function = losses.TripletMarginLoss(
                margin=0.01, distance=self.distance, reducer=self.reducer)
        elif self.loss == 'contrastive':
            self.loss_function = losses.ContrastiveLoss(pos_margin=0,
                                                        neg_margin=1.5)
        elif self.loss == 'panc':
            self.loss_function = losses.ProxyAnchorLoss(
                9,
                128,
                margin=0.01,
                alpha=5,
                reducer=self.reducer,
                weight_regularizer=self.regularizer)
        elif self.loss == 'pnca':
            self.loss_function = losses.ProxyNCALoss(
                9,
                128,
                softmax_scale=1,
                reducer=self.reducer,
                weight_regularizer=self.regularizer)
        elif self.loss == 'normsoftmax':
            self.loss_function = losses.NormalizedSoftmaxLoss(
                9,
                128,
                temperature=0.05,
                reducer=self.reducer,
                weight_regularizer=self.regularizer)

        if self.loss in ['normsoftmax', 'panc', 'pnca']:
            self.loss_optimizer = optim.SGD(self.loss_function.parameters(),
                                            lr=0.0001,
                                            momentum=0.9)
            self.loss_scheduler = lr_scheduler.ReduceLROnPlateau(
                self.loss_optimizer,
                'min',
                patience=3,
                threshold=0.0001,
                factor=0.1,
                verbose=True)

        self.savePath = savePath + 'efigi{}_{}_128'.format(
            self.mining_function, self.loss)
Пример #7
0
# Set optimizers (trying out different learnng rates)
#trunk_optimizer = torch.optim.Adam(trunk.parameters(), lr=0.00001, weight_decay=0.0001)
#embedder_optimizer = torch.optim.Adam(embedder.parameters(), lr=0.0001, weight_decay=0.0001)
trunk_optimizer = torch.optim.Adam(trunk.parameters(),
                                   lr=0.0001,
                                   weight_decay=0.0001)
embedder_optimizer = torch.optim.Adam(embedder.parameters(),
                                      lr=0.001,
                                      weight_decay=0.0001)

# Create the loss, miner, sampler, and package them into dictionaries
# Set the loss function
loss = losses.TripletMarginLoss(margin=0.1)

# Set the mining function
miner = miners.TripletMarginMiner(margin=0.1, type_of_triplets="all")
#miner = miners.MultiSimilarityMiner(epsilon=0.1)

# Set the dataloader sampler
# 4 samples each will be returned -> for us m=2 max
sampler = samplers.MPerClassSampler(train_dataset.targets,
                                    m=2,
                                    length_before_new_iter=len(train_dataset))
#sampler  = samplers.FixedSetOfTriplets(train_dataset.targets, len(train_dataset))

# Set other training parameters
batch_size = 64
num_epochs = 1

# Package the above stuff into dictionaries.
models = {"trunk": trunk, "embedder": embedder}
Пример #8
0
def get_miner():
    return miners.TripletMarginMiner(margin=0.2, type_of_triplets='all')
Пример #9
0
def train_app(cfg):
    print(cfg.pretty())

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    # Set trunk model and replace the softmax layer with an identity function
    trunk = torchvision.models.__dict__[cfg.model.model_name](pretrained=cfg.model.pretrained)
    
    #resnet18(pretrained=True)
    #trunk = models.alexnet(pretrained=True)
    #trunk = models.resnet50(pretrained=True)
    #trunk = models.resnet152(pretrained=True)
    #trunk = models.wide_resnet50_2(pretrained=True)
    #trunk = EfficientNet.from_pretrained('efficientnet-b2')
    trunk_output_size = trunk.fc.in_features
    trunk.fc = Identity()
    trunk = torch.nn.DataParallel(trunk.to(device))

    embedder = torch.nn.DataParallel(MLP([trunk_output_size, cfg.embedder.size]).to(device))
    classifier = torch.nn.DataParallel(MLP([cfg.embedder.size, cfg.embedder.class_out_size])).to(device)

    # Set optimizers
    if cfg.optimizer.name == "sdg":
        trunk_optimizer = torch.optim.SGD(trunk.parameters(), lr=cfg.optimizer.lr, momentum=cfg.optimizer.momentum, weight_decay=cfg.optimizer.weight_decay)
        embedder_optimizer = torch.optim.SGD(embedder.parameters(), lr=cfg.optimizer.lr, momentum=cfg.optimizer.momentum, weight_decay=cfg.optimizer.weight_decay)
        classifier_optimizer = torch.optim.SGD(classifier.parameters(), lr=cfg.optimizer.lr, momentum=cfg.optimizer.momentum, weight_decay=cfg.optimizer.weight_decay)
    elif cfg.optimizer.name == "rmsprop":
        trunk_optimizer = torch.optim.RMSprop(trunk.parameters(), lr=cfg.optimizer.lr, momentum=cfg.optimizer.momentum, weight_decay=cfg.optimizer.weight_decay)
        embedder_optimizer = torch.optim.RMSprop(embedder.parameters(), lr=cfg.optimizer.lr, momentum=cfg.optimizer.momentum, weight_decay=cfg.optimizer.weight_decay)
        classifier_optimizer = torch.optim.RMSprop(classifier.parameters(), lr=cfg.optimizer.lr, momentum=cfg.optimizer.momentum, weight_decay=cfg.optimizer.weight_decay)



    # Set the datasets
    data_dir = os.environ["DATASET_FOLDER"]+"/"+cfg.dataset.data_dir
    print("Data dir: "+data_dir)

    train_dataset, val_dataset, val_samples_dataset = get_datasets(data_dir, cfg, mode=cfg.mode.type)
    print("Trainset: ",len(train_dataset), "Testset: ",len(val_dataset), "Samplesset: ",len(val_samples_dataset))

    # Set the loss function
    if cfg.embedder_loss.name == "margin_loss":
        loss = losses.MarginLoss(margin=cfg.embedder_loss.margin,nu=cfg.embedder_loss.nu,beta=cfg.embedder_loss.beta)
    if cfg.embedder_loss.name == "triplet_margin":
        loss = losses.TripletMarginLoss(margin=cfg.embedder_loss.margin)
    if cfg.embedder_loss.name == "multi_similarity":
        loss = losses.MultiSimilarityLoss(alpha=cfg.embedder_loss.alpha, beta=cfg.embedder_loss.beta, base=cfg.embedder_loss.base)

    # Set the classification loss:
    classification_loss = torch.nn.CrossEntropyLoss()

    # Set the mining function

    if cfg.miner.name == "triplet_margin":
        #miner = miners.TripletMarginMiner(margin=0.2)
        miner = miners.TripletMarginMiner(margin=cfg.miner.margin)
    if cfg.miner.name == "multi_similarity":
        miner = miners.MultiSimilarityMiner(epsilon=cfg.miner.epsilon)
        #miner = miners.MultiSimilarityMiner(epsilon=0.05)

    batch_size = cfg.trainer.batch_size
    num_epochs = cfg.trainer.num_epochs
    iterations_per_epoch = cfg.trainer.iterations_per_epoch
    # Set the dataloader sampler
    sampler = samplers.MPerClassSampler(train_dataset.targets, m=4, length_before_new_iter=len(train_dataset))


    # Package the above stuff into dictionaries.
    models = {"trunk": trunk, "embedder": embedder, "classifier": classifier}
    optimizers = {"trunk_optimizer": trunk_optimizer, "embedder_optimizer": embedder_optimizer, "classifier_optimizer": classifier_optimizer}
    loss_funcs = {"metric_loss": loss, "classifier_loss": classification_loss}
    mining_funcs = {"tuple_miner": miner}

    # We can specify loss weights if we want to. This is optional
    loss_weights = {"metric_loss": cfg.loss.metric_loss, "classifier_loss": cfg.loss.classifier_loss}


    schedulers = {
            #"metric_loss_scheduler_by_epoch": torch.optim.lr_scheduler.StepLR(classifier_optimizer, cfg.scheduler.step_size, gamma=cfg.scheduler.gamma),
            "embedder_scheduler_by_epoch": torch.optim.lr_scheduler.StepLR(embedder_optimizer, cfg.scheduler.step_size, gamma=cfg.scheduler.gamma),
            "classifier_scheduler_by_epoch": torch.optim.lr_scheduler.StepLR(classifier_optimizer, cfg.scheduler.step_size, gamma=cfg.scheduler.gamma),
            "trunk_scheduler_by_epoch": torch.optim.lr_scheduler.StepLR(embedder_optimizer, cfg.scheduler.step_size, gamma=cfg.scheduler.gamma),
            }

    experiment_name = "%s_model_%s_cl_%s_ml_%s_miner_%s_mix_ml_%02.2f_mix_cl_%02.2f_resize_%d_emb_size_%d_class_size_%d_opt_%s_lr_%02.2f_m_%02.2f_wd_%02.2f"%(cfg.dataset.name,
                                                                                                  cfg.model.model_name, 
                                                                                                  "cross_entropy", 
                                                                                                  cfg.embedder_loss.name, 
                                                                                                  cfg.miner.name, 
                                                                                                  cfg.loss.metric_loss, 
                                                                                                  cfg.loss.classifier_loss,
                                                                                                  cfg.transform.transform_resize,
                                                                                                  cfg.embedder.size,
                                                                                                  cfg.embedder.class_out_size,
                                                                                                  cfg.optimizer.name,
                                                                                                  cfg.optimizer.lr,
                                                                                                  cfg.optimizer.momentum,
                                                                                                  cfg.optimizer.weight_decay)
    record_keeper, _, _ = logging_presets.get_record_keeper("logs/%s"%(experiment_name), "tensorboard/%s"%(experiment_name))
    hooks = logging_presets.get_hook_container(record_keeper)
    dataset_dict = {"samples": val_samples_dataset, "val": val_dataset}
    model_folder = "example_saved_models/%s/"%(experiment_name)

    # Create the tester
    tester = OneShotTester(
            end_of_testing_hook=hooks.end_of_testing_hook, 
            #size_of_tsne=20
            )
    #tester.embedding_filename=data_dir+"/embeddings_pretrained_triplet_loss_multi_similarity_miner.pkl"
    tester.embedding_filename=data_dir+"/"+experiment_name+".pkl"
    end_of_epoch_hook = hooks.end_of_epoch_hook(tester, dataset_dict, model_folder)
    trainer = trainers.TrainWithClassifier(models,
            optimizers,
            batch_size,
            loss_funcs,
            mining_funcs,
            train_dataset,
            sampler=sampler,
            lr_schedulers=schedulers,
            dataloader_num_workers = cfg.trainer.batch_size,
            loss_weights=loss_weights,
            end_of_iteration_hook=hooks.end_of_iteration_hook,
            end_of_epoch_hook=end_of_epoch_hook
            )

    trainer.train(num_epochs=num_epochs)

    tester = OneShotTester()