Esempio n. 1
0
def test(classifier, generator, data_loader, dataset="MNIST"):
    """Evaluate classifier on source or target domains."""
    # set eval state for Dropout and BN layers
    generator.eval()
    classifier.eval()

    # init loss and accuracy
    loss = 0
    acc = 0

    # set loss function
    criterion = nn.CrossEntropyLoss()

    # evaluate network
    for (images, labels) in data_loader:
        images = make_variable(images, volatile=True)
        labels = make_variable(labels.squeeze_())

        preds = classifier(generator(images))
        loss += criterion(preds, labels).data[0]

        pred_cls = preds.data.max(1)[1]
        acc += pred_cls.eq(labels.data).cpu().sum()

    loss /= len(data_loader)
    acc /= len(data_loader.dataset)

    print("Avg Loss = {:.5f}, Avg Accuracy = {:2.5%}".format(loss, acc))
Esempio n. 2
0
def evaluate_target(encoder, classifier, images, labels):
    """Evaluate classifier on source or target domains."""
    # set eval state for Dropout and BN layers
    encoder.eval()
    classifier.eval()

    # init loss and accuracy
    loss = 0
    acc = 0

    # set loss function
    criterion = nn.CrossEntropyLoss()

    # evaluate network
    images = make_variable(images, volatile=True)
    # labels = make_variable(labels.squeeze_())
    labels = make_variable(labels).long().squeeze()

    preds = classifier(encoder(images))

    _, target_predicted = torch.max(preds.data, 1)
    target_correct = (target_predicted == labels.data).sum()
    acc = target_correct / labels.size()[0]

    return acc
Esempio n. 3
0
def eval_func_datacollect(encoder, classifier, data_loader):
    """Evaluate classifier for source domain."""
    # set eval state for Dropout and BN layers
    encoder.eval()
    classifier.eval()

    # init loss and accuracy
    loss = 0
    acc = 0

    # set loss function
    criterion = nn.CrossEntropyLoss()

    labelsall = []
    predsall = []
    # evaluate network
    for (images, labels) in data_loader:
        images = make_variable(images, volatile=True)
        # labels[labels == 10] = 0
        labels = make_variable(labels).long().squeeze()
        preds = classifier(encoder(images))
        pred_cls = preds.data.max(1)[1]

        labelsall.extend(labels.data.cpu().numpy())
        predsall.extend(pred_cls.cpu().numpy())

    return labelsall, predsall
Esempio n. 4
0
def train_src_rec(encoder, classifier, generator, data_loader):
    """Train classifier for source domain."""
    ####################
    # 1. setup network #
    ####################

    # set train state for Dropout and BN layers
    encoder.train()
    classifier.train()
    generator.train()

    # setup criterion and optimizer
    
    optimizer = optim.Adam(
        generator.parameters(),
        lr=cfg.learning_rate_apt,
        betas=(cfg.beta1, cfg.beta2))

    criterionRec = torch.nn.MSELoss()

    ####################
    # 2. train network #
    ####################
    for epoch in range(cfg.num_epochs_pre_rec):
        for step, (images, labels) in enumerate(data_loader):
            # make images and labels variable
            images = make_variable(images)
            # labels[labels == 10] = 0
            labels = make_variable(labels).long().squeeze()

            # zero gradients for optimizer
            optimizer.zero_grad()
            # compute loss for critic
            feat= encoder(images)
            feat_reshape = (feat.unsqueeze(2)).unsqueeze(2)
            reconst = generator(feat_reshape)
            loss_rec = criterionRec(reconst, images)

            loss_rec.backward()
            optimizer.step()

            # print step info
            if (step+1) % cfg.log_step_pre == 0:
                print('Epoch [%d] ' 
                      'loss[%.2f] '
                    %(epoch,
                      loss_rec.data[0],
                      )
                    )


    # # save final model
    save_model(generator, "ADDA-source-generator-final.pt")

    return generator
Esempio n. 5
0
def evaluate(encoder, classifier, data_loader):
    """Evaluate classifier on source or target domains."""
    # set eval state for Dropout and BN layers
    encoder.eval()
    classifier.eval()

    # init loss and accuracy
    loss = 0.0
    acc = 0.0

    # set loss function
    criterion = nn.CrossEntropyLoss()

    # evaluate network
    for (images, labels) in data_loader:
        images = make_variable(images, volatile=True)
        labels = make_variable(labels.squeeze_())

        #print('images shape = {}'.format(images.shape))
        #print('encoding shape = {}'.format(encoder(images).shape))
        preds = classifier(encoder(images))
        #print('preds shape = {}'.format(preds.shape))
        #print('labels shape = {}'.format(labels.shape))
        cv = criterion(preds, labels)
        #print('crit val = {}'.format(cv))
        loss += cv.item() #data[0]

        pred_cls = preds.data.max(1)[1]
        #print('labels.data = {}, preds_cls = {}'.format(labels.data, pred_cls)) #!!
        #print('eq = {}'.format(pred_cls.eq(labels.data)))
        contrib =  pred_cls.eq(labels.data).cpu().sum()
        #print('contrib = {}'.format(contrib))
        acc += float(contrib)

    loss /= float(len(data_loader))
    acc /= float(len(data_loader.dataset))

    print("Avg Loss = {:.5f}, Avg Accuracy = {:2.5%}".format(loss, acc))
Esempio n. 6
0
def eval_func(encoder, classifier, data_loader, sample=False):
    """Evaluate classifier for source domain."""
    # set eval state for Dropout and BN layers
    encoder.eval()
    classifier.eval()

    # init loss and accuracy
    loss = 0
    acc = 0

    # set loss function
    criterion = nn.CrossEntropyLoss()
    # evaluate network
    for (images, labels) in data_loader:
        images = make_variable(images, volatile=True)
        # labels[labels == 10] = 0
        labels = make_variable(labels).long().squeeze()
        preds = classifier(encoder(images))
        loss += criterion(preds, labels).item()
        pred_cls = preds.data.max(1)[1]
        acc += pred_cls.eq(labels.data).cpu().sum().item()

    loss /= len(data_loader)
    acc /= len(data_loader.dataset)

    # acc /= 1800
    # acc /= 2000
    # if sample:
    #     # acc /= (len(data_loader)*cfg.batch_size)
    #     acc /= 1800
    #     # acc /= 2000
    # else:
    #     # acc /= 1800
    #     # acc /= 2000
    # acc /= len(data_loader.dataset)

    print("Avg Loss = {}, Avg Accuracy = {:2%}".format(loss, acc))
Esempio n. 7
0
def extract(model, filepath, vid):
    """Extract features by inception_v3."""
    # data loader for frames in ingle video
    data_loader = get_dataloader(dataset="VideoFrame",
                                 path=filepath,
                                 num_frames=cfg.num_frames,
                                 batch_size=cfg.batch_size)
    # extract features by inception_v3
    feats = None
    for step, frames in enumerate(data_loader):
        print("--> extract features [{}/{}]".format(step + 1,
                                                    len(data_loader)))
        feat = model(make_variable(frames))
        feats = concat_feat_var(feats, feat.data.cpu())

    print("--> save feats to {}".format(
        cfg.inception_v3_feats_path.format(vid)))
    torch.save(feats, cfg.inception_v3_feats_path.format(vid))
    print("--> delete original video file: {}".format(filepath))
    os.remove(filepath)
Esempio n. 8
0
def genarate_labels(F, F_1, F_2, target_dataset, num_target):
    """Genrate pseudo labels for target domain dataset."""
    # set eval state for Dropout and BN layers
    F.eval()
    F_1.eval()
    F_2.eval()

    # get candidate samples
    print("Num of sampled target data: {}".format(num_target))

    # get sampled data loader
    data_loader = get_sampled_data_loader(target_dataset,
                                          num_target,
                                          shuffle=True)

    # get output of F_1 and F_2 on sampled target dataset
    out_F_1_total = None
    out_F_2_total = None
    for step, (images, _) in enumerate(data_loader):
        # convert into torch.autograd.Variable
        images = make_variable(images)
        # forward networks
        out_F = F(images)
        out_F_1 = F_1(out_F)
        out_F_2 = F_2(out_F)
        # concat outputs
        if step == 0:
            out_F_1_total = out_F_1.data.cpu()
            out_F_2_total = out_F_2.data.cpu()
        else:
            out_F_1_total = torch.cat([out_F_1_total, out_F_1.data.cpu()], 0)
            out_F_2_total = torch.cat([out_F_2_total, out_F_2.data.cpu()], 0)

    # guess pseudo labels
    excerpt, pseudo_labels = \
        guess_pseudo_labels(out_F_1_total, out_F_2_total)

    return excerpt, pseudo_labels
Esempio n. 9
0
def train_src(encoder, classifier, data_loader, tgt_data_loader_eval):
    """Train classifier for source domain."""
    ####################
    # 1. setup network #
    ####################

    # set train state for Dropout and BN layers
    encoder.train()
    classifier.train()

    # setup criterion and optimizer

    optimizer = optim.Adam(list(encoder.parameters()) +
                           list(classifier.parameters()),
                           lr=cfg.learning_rate_pre,
                           betas=(cfg.beta1, cfg.beta2))
    criterion = nn.CrossEntropyLoss()

    # optimizer = optim.Adam(
    #     itertools(encoder.parameters(), classifier.parameters()),
    #     lr=cfg.learning_rate_pre,
    #     betas=(cfg.beta1, cfg.beta2))
    # criterion = nn.CrossEntropyLoss()

    ####################
    # 2. train network #
    ####################
    for epoch in range(cfg.num_epochs_pre):
        for step, (images, labels) in enumerate(data_loader):
            # make images and labels variable
            images = make_variable(images)
            # labels[labels == 10] = 0
            labels = make_variable(labels).long().squeeze()

            # zero gradients for optimizer
            optimizer.zero_grad()
            # compute loss for critic
            preds = classifier(encoder(images))
            loss = criterion(preds, labels)
            # optimize source classifier
            loss.backward()
            optimizer.step()

            # st()

            acc = evaluate.evaluate_step(encoder, classifier, images, labels)

            # print step info
            if (step + 1) % cfg.log_step_pre == 0:
                print('Epoch [%d] '
                      'loss[%.2f] '
                      'Source_Accuracy[%.2f] ' % (epoch, loss.data[0], acc))

        # eval model on test set
        if ((epoch + 1) % cfg.eval_step_pre == 0):
            # evaluate.eval_func(encoder, classifier, tgt_data_loader_eval, sample=True)
            # evaluate.eval_func(encoder, classifier, data_loader)
            print(">>> source only <<<")
            evaluate.eval_func(encoder, classifier, tgt_data_loader_eval)

        # save model parameters
        if ((epoch + 1) % cfg.save_step_pre == 0):
            save_model(encoder, "ADDA-source-encoder-{}.pt".format(epoch + 1))
            save_model(classifier,
                       "ADDA-source-classifier-{}.pt".format(epoch + 1))

    # # save final model
    save_model(encoder, "ADDA-source-encoder-final.pt")
    save_model(classifier, "ADDA-source-classifier-final.pt")

    return encoder, classifier
Esempio n. 10
0
def train(classifier, generator, critic, src_data_loader, tgt_data_loader):
    """Train generator, classifier and critic jointly."""
    ####################
    # 1. setup network #
    ####################

    # set train state for Dropout and BN layers
    classifier.train()
    generator.train()
    critic.train()

    # set criterion for classifier and optimizers
    criterion = nn.CrossEntropyLoss()
    optimizer_c = get_optimizer(classifier, "Adam")
    optimizer_g = get_optimizer(generator, "Adam")
    optimizer_d = get_optimizer(critic, "Adam")

    # zip source and target data pair
    data_iter_src = get_inf_iterator(src_data_loader)
    data_iter_tgt = get_inf_iterator(tgt_data_loader)

    # counter
    g_step = 0

    # positive and negative labels
    pos_labels = make_variable(torch.FloatTensor([1]))
    neg_labels = make_variable(torch.FloatTensor([-1]))

    ####################
    # 2. train network #
    ####################

    for epoch in range(params.num_epochs):
        ###########################
        # 2.1 train discriminator #
        ###########################
        # requires to compute gradients for D
        for p in critic.parameters():
            p.requires_grad = True

        # set steps for discriminator
        if g_step < 25 or g_step % 500 == 0:
            # this helps to start with the critic at optimum
            # even in the first iterations.
            critic_iters = 100
        else:
            critic_iters = params.d_steps

        # loop for optimizing discriminator
        for d_step in range(critic_iters):
            # convert images into torch.Variable
            images_src, labels_src = next(data_iter_src)
            images_tgt, _ = next(data_iter_tgt)
            images_src = make_variable(images_src)
            labels_src = make_variable(labels_src.squeeze_())
            images_tgt = make_variable(images_tgt)
            if images_src.size(0) != params.batch_size or \
                    images_tgt.size(0) != params.batch_size:
                continue

            # zero gradients for optimizer
            optimizer_d.zero_grad()

            # compute source data loss for discriminator
            feat_src = generator(images_src)
            d_loss_src = critic(feat_src.detach())
            d_loss_src = d_loss_src.mean()
            d_loss_src.backward(neg_labels)

            # compute target data loss for discriminator
            feat_tgt = generator(images_tgt)
            d_loss_tgt = critic(feat_tgt.detach())
            d_loss_tgt = d_loss_tgt.mean()
            d_loss_tgt.backward(pos_labels)

            # compute gradient penalty
            gradient_penalty = calc_gradient_penalty(critic, feat_src.data,
                                                     feat_tgt.data)
            gradient_penalty.backward()

            # optimize weights of discriminator
            d_loss = -d_loss_src + d_loss_tgt + gradient_penalty
            optimizer_d.step()

        ########################
        # 2.2 train classifier #
        ########################

        # zero gradients for optimizer
        optimizer_c.zero_grad()

        # compute loss for critic
        preds_c = classifier(generator(images_src).detach())
        c_loss = criterion(preds_c, labels_src)

        # optimize source classifier
        c_loss.backward()
        optimizer_c.step()

        #######################
        # 2.3 train generator #
        #######################
        # avoid to compute gradients for D
        for p in critic.parameters():
            p.requires_grad = False

        # zero grad for optimizer of generator
        optimizer_g.zero_grad()

        # compute source data classification loss for generator
        feat_src = generator(images_src)
        preds_c = classifier(feat_src)
        g_loss_cls = criterion(preds_c, labels_src)
        g_loss_cls.backward()

        # compute source data discriminattion loss for generator
        feat_src = generator(images_src)
        g_loss_src = critic(feat_src).mean()
        g_loss_src.backward(pos_labels)

        # compute target data discriminattion loss for generator
        feat_tgt = generator(images_tgt)
        g_loss_tgt = critic(feat_tgt).mean()
        g_loss_tgt.backward(neg_labels)

        # compute loss for generator
        g_loss = g_loss_src - g_loss_tgt + g_loss_cls

        # optimize weights of generator
        optimizer_g.step()
        g_step += 1

        ##################
        # 2.4 print info #
        ##################
        if ((epoch + 1) % params.log_step == 0):
            print("Epoch [{}/{}]:"
                  "d_loss={:.5f} c_loss={:.5f} g_loss={:.5f} "
                  "D(x)={:.5f} D(G(z))={:.5f} GP={:.5f}".format(
                      epoch + 1, params.num_epochs, d_loss.data[0],
                      c_loss.data[0], g_loss.data[0], d_loss_src.data[0],
                      d_loss_tgt.data[0], gradient_penalty.data[0]))

        #############################
        # 2.5 save model parameters #
        #############################
        if ((epoch + 1) % params.save_step == 0):
            save_model(critic, "WGAN-GP_critic-{}.pt".format(epoch + 1))
            save_model(classifier,
                       "WGAN-GP_classifier-{}.pt".format(epoch + 1))
            save_model(generator, "WGAN-GP_generator-{}.pt".format(epoch + 1))

    return classifier, generator
Esempio n. 11
0
def domain_adapt(F, F_1, F_2, F_t, source_dataset, target_dataset, excerpt,
                 pseudo_labels, plot):
    """Perform Doamin Adaptation between source and target domains."""
    # set criterion for classifier and optimizers
    criterion = nn.CrossEntropyLoss()
    if 0:
        optimType = "Adam"
        cfg.learning_rate = 1.0E-4
    else:
        optimType = "sgd"
        cfg.learning_rate = 1.0E-4
    optimizer_F = get_optimizer(F, optimType)
    optimizer_F_1 = get_optimizer(F_1, optimType)
    optimizer_F_2 = get_optimizer(F_2, optimType)
    optimizer_F_t = get_optimizer(F_t, optimType)

    # get labelled target dataset
    print('pseudo_labels = %s' % str(pseudo_labels))
    target_dataset_labelled = get_dummy(target_dataset,
                                        excerpt,
                                        pseudo_labels,
                                        get_dataset=True)

    # merge soruce data and target data
    merged_dataset = ConcatDataset([source_dataset, target_dataset_labelled])

    print('target_dataset_labelled = %d' % len(target_dataset_labelled))

    # start training
    plt.figure()

    for k in range(cfg.num_epochs_k):
        # set train state for Dropout and BN layers
        F.train()
        F_1.train()
        F_2.train()
        F_t.train()

        losses = []

        merged_dataloader = make_data_loader(merged_dataset)
        target_dataloader_labelled = make_data_loader(target_dataset_labelled)
        target_dataloader_labelled_iter = get_inf_iterator(
            target_dataloader_labelled)

        if 0:
            plt.figure()
            atr.showDataSet(target_dataloader_labelled)
            plt.waitforbuttonpress()

        if 0:
            # There's a bug here, the labels are not the same data type.  print them out!!
            source_dataloader_iter = get_inf_iterator(
                make_data_loader(source_dataset))

            a, b = next(source_dataloader_iter)
            c, d = next(target_dataloader_labelled_iter)
            print('source labels = {}'.format(b))
            print('target labels = {}'.format(d))
            sys.exit(0)

        for epoch in range(cfg.num_epochs_adapt):
            if optimType == 'sgd':
                adjustLearningRate(optimizer_F, cfg.learning_rate, epoch,
                                   cfg.num_epochs_adapt)
                adjustLearningRate(optimizer_F_1, cfg.learning_rate, epoch,
                                   cfg.num_epochs_adapt)
                adjustLearningRate(optimizer_F_2, cfg.learning_rate, epoch,
                                   cfg.num_epochs_adapt)
                adjustLearningRate(optimizer_F_t, cfg.learning_rate, epoch,
                                   cfg.num_epochs_adapt)

            for step, rez in enumerate(merged_dataloader):
                #!!print('rez = %s' % rez)
                images, labels = rez
                if images.shape[0] < cfg.batch_size:
                    print('WARNING: batch of size %d smaller than desired %d: skipping' % \
                          (images.shape[0], cfg.batch_size))
                    continue

                # sample from T_l
                images_tgt, labels_tgt = next(target_dataloader_labelled_iter)
                while images_tgt.shape[0] < cfg.batch_size:
                    print('WARNING: target batch of size %d smaller than desired %d' % \
                          (images_tgt.shape[0], cfg.batch_size))
                    images_tgt, labels_tgt = next(
                        target_dataloader_labelled_iter)

                # convert into torch.autograd.Variable
                images = make_variable(images)
                labels = make_variable(labels)
                images_tgt = make_variable(images_tgt)
                labels_tgt = make_variable(labels_tgt)

                # zero-grad optimizer
                optimizer_F.zero_grad()
                optimizer_F_1.zero_grad()
                optimizer_F_2.zero_grad()
                optimizer_F_t.zero_grad()

                # forward networks
                #print('images shape = {}'.format(images.shape))#!!
                out_F = F(images)
                #print('out_F = {}'.format(out_F.shape))#!!
                out_F_1 = F_1(out_F)
                out_F_2 = F_2(out_F)
                out_F_t = F_t(F(images_tgt))

                # compute labelling loss
                loss_similiar = calc_similiar_penalty(F_1, F_2)
                loss_F_1 = criterion(out_F_1, labels)
                loss_F_2 = criterion(out_F_2, labels)
                loss_labelling = loss_F_1 + loss_F_2 + 0.03 * loss_similiar
                loss_labelling.backward()

                # compute target specific loss
                loss_F_t = criterion(out_F_t, labels_tgt)
                loss_F_t.backward()

                # optimize
                optimizer_F.step()
                optimizer_F_1.step()
                optimizer_F_2.step()
                optimizer_F_t.step()

                losses.append(loss_F_t.item())

                # print step info
                if ((step + 1) % cfg.log_step == 0):
                    print("K[{}/{}] Epoch [{}/{}] Step[{}/{}] Loss("
                          "labelling={:.5f} target={:.5f})".format(
                              k + 1,
                              cfg.num_epochs_k,
                              epoch + 1,
                              cfg.num_epochs_adapt,
                              step + 1,
                              len(merged_dataloader),
                              loss_labelling.item(),  #.data[0],
                              loss_F_t.item(),  #.data[0],
                          ))
                    #!!print('end of loop')

                    if plot:
                        plt.clf()
                        plt.plot(losses)
                        plt.grid(1)
                        plt.title(
                            'Loss for domain adaptation, k = {}/{}, epoch = {}/{}'
                            .format(k, cfg.num_epochs_k, epoch,
                                    cfg.num_epochs_adapt))
                        plt.waitforbuttonpress(0.0001)

        # re-compute the number of selected taget data
        num_target = (k + 2) * len(source_dataset) // 20
        num_target = min(num_target, cfg.num_target_max)
        print(">>> Set num of sampled target data: {}".format(num_target))

        # re-generate pseudo labels
        excerpt, pseudo_labels = generate_labels(F,
                                                 F_1,
                                                 F_2,
                                                 target_dataset,
                                                 num_target,
                                                 useWeightedSampling=True)
        print(">>> Genrate pseudo labels [{}] numtarget = {}".format(
            len(target_dataset_labelled), num_target))

        print('sizes = {}, {}, excerpt = {}, \npseudo_labels = {}'.format(
            len(excerpt), len(pseudo_labels), excerpt, pseudo_labels))

        # get labelled target dataset
        target_dataset_labelled = get_dummy(target_dataset,
                                            excerpt,
                                            pseudo_labels,
                                            get_dataset=True)

        # re-merge soruce data and target data
        merged_dataset = ConcatDataset(
            [source_dataset, target_dataset_labelled])

        # save model
        if ((k + 1) % cfg.save_step == 0):
            save_model(F, "adapt-F-{}.pt".format(k + 1))
            save_model(F_1, "adapt-F_1-{}.pt".format(k + 1))
            save_model(F_2, "adapt-F_2-{}.pt".format(k + 1))
            save_model(F_t, "adapt-F_t-{}.pt".format(k + 1))

    # save final model
    save_model(F, "adapt-F-final.pt")
    save_model(F_1, "adapt-F_1-final.pt")
    save_model(F_2, "adapt-F_2-final.pt")
    save_model(F_t, "adapt-F_t-final.pt")
Esempio n. 12
0
def pre_train(F, F_1, F_2, F_t, source_data, plot):
    """Pre-train models on source domain dataset."""
    # set train state for Dropout and BN layers
    F.train()
    F_1.train()
    F_2.train()
    F_t.train()

    # set criterion for classifier and optimizers
    criterion = nn.CrossEntropyLoss()
    if 0:
        optimType = "Adam"
        cfg.learning_rate = 1.0E-4
    else:
        optimType = "sgd"
        cfg.learning_rate = 1.0E-3
    optimizer_F = get_optimizer(F, optimType)
    optimizer_F_1 = get_optimizer(F_1, optimType)
    optimizer_F_2 = get_optimizer(F_2, optimType)
    optimizer_F_t = get_optimizer(F_t, optimType)

    losses = []

    if plot:
        plt.figure()

    # start training
    for epoch in range(cfg.num_epochs_pre):
        if optimType == 'sgd':
            adjustLearningRate(optimizer_F, cfg.learning_rate, epoch,
                               cfg.num_epochs_pre)
            adjustLearningRate(optimizer_F_1, cfg.learning_rate, epoch,
                               cfg.num_epochs_pre)
            adjustLearningRate(optimizer_F_2, cfg.learning_rate, epoch,
                               cfg.num_epochs_pre)
            adjustLearningRate(optimizer_F_t, cfg.learning_rate, epoch,
                               cfg.num_epochs_pre)

        for step, (images, labels) in enumerate(source_data):
            # convert into torch.autograd.Variable
            images = make_variable(images)
            labels = make_variable(labels)

            # zero-grad optimizer
            optimizer_F.zero_grad()
            optimizer_F_1.zero_grad()
            optimizer_F_2.zero_grad()
            optimizer_F_t.zero_grad()

            # forward networks
            out_F = F(images)

            #!!
            #out_F = torch.flatten(out_F,1)

            out_F_1 = F_1(out_F)
            out_F_2 = F_2(out_F)
            out_F_t = F_t(out_F)

            # compute loss
            loss_similiar = calc_similiar_penalty(F_1, F_2)
            loss_F_1 = criterion(out_F_1, labels)
            loss_F_2 = criterion(out_F_2, labels)
            loss_F_t = criterion(out_F_t, labels)
            loss_F = loss_F_1 + loss_F_2 + loss_F_t + 0.03 * loss_similiar
            loss_F.backward()

            # optimize
            optimizer_F.step()
            optimizer_F_1.step()
            optimizer_F_2.step()
            optimizer_F_t.step()

            losses.append(loss_F.item())

            # print step info
            if ((step + 1) % cfg.log_step == 0):
                print("Epoch [{}/{}] Step[{}/{}] Loss("
                      "Total={:.5f} F_1={:.5f} F_2={:.5f} "
                      "F_t={:.5f} sim={:.5f})"
                      #!!                      "F_t={:.5f})"
                      .format(epoch + 1,
                              cfg.num_epochs_pre,
                              step + 1,
                              len(source_data),
                              loss_F.item(), #.data[0],
                              loss_F_1.item(), #.data[0],
                              loss_F_2.item(), #.data[0],
                              loss_F_t.item(), #.data[0],
                              loss_similiar.item(), #.data[0],
                              ))

                if plot:
                    plt.clf()
                    plt.plot(losses)
                    plt.grid(1)
                    plt.title('Loss for pre-training')
                    plt.waitforbuttonpress(0.0001)

        # save model
        if ((epoch + 1) % cfg.save_step == 0):
            save_model(F, "pretrain-F-{}.pt".format(epoch + 1))
            save_model(F_1, "pretrain-F_1-{}.pt".format(epoch + 1))
            save_model(F_2, "pretrain-F_2-{}.pt".format(epoch + 1))
            save_model(F_t, "pretrain-F_t-{}.pt".format(epoch + 1))

    # save final model
    save_model(F, "pretrain-F-final.pt")
    save_model(F_1, "pretrain-F_1-final.pt")
    save_model(F_2, "pretrain-F_2-final.pt")
    save_model(F_t, "pretrain-F_t-final.pt")
Esempio n. 13
0
def domain_adapt(F, F_1, F_2, F_t, source_dataset, target_dataset, excerpt,
                 pseudo_labels):
    """Perform Doamin Adaptation between source and target domains."""
    # set criterion for classifier and optimizers
    criterion = nn.CrossEntropyLoss()
    optimizer_F = get_optimizer(F, "Adam")
    optimizer_F_1 = get_optimizer(F_1, "Adam")
    optimizer_F_2 = get_optimizer(F_2, "Adam")
    optimizer_F_t = get_optimizer(F_t, "Adam")

    # get labelled target dataset
    target_dataset_labelled = get_dummy(target_dataset,
                                        excerpt,
                                        pseudo_labels,
                                        get_dataset=True)

    # merge soruce data and target data
    merged_dataset = ConcatDataset([source_dataset, target_dataset_labelled])

    # start training
    for k in range(cfg.num_epochs_k):
        # set train state for Dropout and BN layers
        F.train()
        F_1.train()
        F_2.train()
        F_t.train()

        merged_dataloader = make_data_loader(merged_dataset)
        target_dataloader_labelled = get_inf_iterator(
            make_data_loader(target_dataset_labelled))

        for epoch in range(cfg.num_epochs_adapt):
            for step, (images, labels) in enumerate(merged_dataloader):
                # sample from T_l
                images_tgt, labels_tgt = next(target_dataloader_labelled)

                # convert into torch.autograd.Variable
                images = make_variable(images)
                labels = make_variable(labels)
                images_tgt = make_variable(images_tgt)
                labels_tgt = make_variable(labels_tgt)

                # zero-grad optimizer
                optimizer_F.zero_grad()
                optimizer_F_1.zero_grad()
                optimizer_F_2.zero_grad()
                optimizer_F_t.zero_grad()

                # forward networks
                out_F = F(images)
                out_F_1 = F_1(out_F)
                out_F_2 = F_2(out_F)
                out_F_t = F_t(F(images_tgt))

                # compute labelling loss
                loss_similiar = calc_similiar_penalty(F_1, F_2)
                loss_F_1 = criterion(out_F_1, labels)
                loss_F_2 = criterion(out_F_2, labels)
                loss_labelling = loss_F_1 + loss_F_2 + loss_similiar
                loss_labelling.backward()

                # compute target specific loss
                loss_F_t = criterion(out_F_t, labels_tgt)
                loss_F_t.backward()

                # optimize
                optimizer_F.step()
                optimizer_F_1.step()
                optimizer_F_2.step()
                optimizer_F_t.step()

                # print step info
                if ((step + 1) % cfg.log_step == 0):
                    print("K[{}/{}] Epoch [{}/{}] Step[{}/{}] Loss("
                          "labelling={:.5f} target={:.5f})".format(
                              k + 1,
                              cfg.num_epochs_k,
                              epoch + 1,
                              cfg.num_epochs_adapt,
                              step + 1,
                              len(merged_dataloader),
                              loss_labelling.data[0],
                              loss_F_t.data[0],
                          ))

        # re-compute the number of selected taget data
        num_target = (k + 2) * len(source_dataset) // 20
        num_target = min(num_target, cfg.num_target_max)
        print(">>> Set num of sampled target data: {}".format(num_target))

        # re-generate pseudo labels
        excerpt, pseudo_labels = genarate_labels(F, F_1, F_2, target_dataset,
                                                 num_target)
        print(">>> Genrate pseudo labels [{}]".format(
            len(target_dataset_labelled)))

        # get labelled target dataset
        target_dataset_labelled = get_dummy(target_dataset,
                                            excerpt,
                                            pseudo_labels,
                                            get_dataset=True)

        # re-merge soruce data and target data
        merged_dataset = ConcatDataset(
            [source_dataset, target_dataset_labelled])

        # save model
        if ((k + 1) % cfg.save_step == 0):
            save_model(F, "adapt-F-{}.pt".format(k + 1))
            save_model(F_1, "adapt-F_1-{}.pt".format(k + 1))
            save_model(F_2, "adapt-F_2-{}.pt".format(k + 1))
            save_model(F_t, "adapt-F_t-{}.pt".format(k + 1))

    # save final model
    save_model(F, "adapt-F-final.pt")
    save_model(F_1, "adapt-F_1-final.pt")
    save_model(F_2, "adapt-F_2-final.pt")
    save_model(F_t, "adapt-F_t-final.pt")
Esempio n. 14
0
def pre_train(F, F_1, F_2, F_t, source_data):
    """Pre-train models on source domain dataset."""
    # set train state for Dropout and BN layers
    F.train()
    F_1.train()
    F_2.train()
    F_t.train()

    # set criterion for classifier and optimizers
    criterion = nn.CrossEntropyLoss()
    optimizer_F = get_optimizer(F, "Adam")
    optimizer_F_1 = get_optimizer(F_1, "Adam")
    optimizer_F_2 = get_optimizer(F_2, "Adam")
    optimizer_F_t = get_optimizer(F_t, "Adam")

    # start training
    for epoch in range(cfg.num_epochs_pre):
        for step, (images, labels) in enumerate(source_data):
            # convert into torch.autograd.Variable
            images = make_variable(images)
            labels = make_variable(labels)

            # zero-grad optimizer
            optimizer_F.zero_grad()
            optimizer_F_1.zero_grad()
            optimizer_F_2.zero_grad()
            optimizer_F_t.zero_grad()

            # forward networks
            out_F = F(images)
            out_F_1 = F_1(out_F)
            out_F_2 = F_2(out_F)
            out_F_t = F_t(out_F)

            # compute loss
            loss_similiar = calc_similiar_penalty(F_1, F_2)
            loss_F_1 = criterion(out_F_1, labels)
            loss_F_2 = criterion(out_F_2, labels)
            loss_F_t = criterion(out_F_t, labels)
            loss_F = loss_F_1 + loss_F_2 + loss_F_t + loss_similiar
            loss_F.backward()

            # optimize
            optimizer_F.step()
            optimizer_F_1.step()
            optimizer_F_2.step()
            optimizer_F_t.step()

            # print step info
            if ((step + 1) % cfg.log_step == 0):
                print("Epoch [{}/{}] Step[{}/{}] Loss("
                      "Total={:.5f} F_1={:.5f} F_2={:.5f} "
                      "F_t={:.5f} sim={:.5f})".format(
                          epoch + 1,
                          cfg.num_epochs_pre,
                          step + 1,
                          len(source_data),
                          loss_F.data[0],
                          loss_F_1.data[0],
                          loss_F_2.data[0],
                          loss_F_t.data[0],
                          loss_similiar.data[0],
                      ))

        # save model
        if ((epoch + 1) % cfg.save_step == 0):
            save_model(F, "pretrain-F-{}.pt".format(epoch + 1))
            save_model(F_1, "pretrain-F_1-{}.pt".format(epoch + 1))
            save_model(F_2, "pretrain-F_2-{}.pt".format(epoch + 1))
            save_model(F_t, "pretrain-F_t-{}.pt".format(epoch + 1))

    # save final model
    save_model(F, "pretrain-F-final.pt")
    save_model(F_1, "pretrain-F_1-final.pt")
    save_model(F_2, "pretrain-F_2-final.pt")
    save_model(F_t, "pretrain-F_t-final.pt")
Esempio n. 15
0
def train(classifier, generator, critic, src_data_loader, tgt_data_loader):
    """Train generator, classifier and critic jointly."""
    ####################
    # 1. setup network #
    ####################

    # set train state for Dropout and BN layers
    classifier.train()
    generator.train()
    # set criterion for classifier and optimizers
    criterion = nn.CrossEntropyLoss()
    optimizer_c = get_optimizer(classifier, "Adam")

    # zip source and target data pair
    data_iter_src = get_inf_iterator(src_data_loader)

    # counter
    g_step = 0

    ####################
    # 2. train network #
    ####################

    for epoch in range(params.num_epochs):
        ###########################
        # 2.1 train discriminator #
        ###########################
        # requires to compute gradients for D
        for p in critic.parameters():
            p.requires_grad = True

        # set steps for discriminator
        if g_step < 25 or g_step % 500 == 0:
            # this helps to start with the critic at optimum
            # even in the first iterations.
            critic_iters = 100
        else:
            critic_iters = params.d_steps
        critic_iters = 0
        # loop for optimizing discriminator
        #for d_step in range(critic_iters):
        # convert images into torch.Variable
        images_src, labels_src = next(data_iter_src)

        images_src = make_variable(images_src).cuda()
        labels_src = make_variable(labels_src.squeeze_()).cuda()
        # print(type(images_src))

        ########################
        # 2.2 train classifier #
        ########################

        # zero gradients for optimizer
        optimizer_c.zero_grad()

        # compute loss for critic
        preds_c = classifier(generator(images_src))
        c_loss = criterion(preds_c, labels_src)

        # optimize source classifier
        c_loss.backward()
        optimizer_c.step()
        g_step += 1

        ##################
        # 2.4 print info #
        ##################
        if ((epoch + 1) % 500 == 0):
            # print("Epoch [{}/{}]:"
            #       "c_loss={:.5f}"
            #       "D(x)={:.5f}"
            #       .format(epoch + 1,
            #               params.num_epochs,
            #               c_loss.item(),
            #               ))
            test(classifier, generator, src_data_loader, params.src_dataset)
        if ((epoch + 1) % 500 == 0):
            save_model(generator, "Mnist-generator-{}.pt".format(epoch + 1))
            save_model(classifier, "Mnist-classifer{}.pt".format(epoch + 1))
Esempio n. 16
0
def train_tgt(src_encoder, tgt_encoder, critic, src_data_loader,
              tgt_data_loader, src_classifier, tgt_classifier,
              tgt_data_loader_eval, generator, discriminator, Saver, logger):
    """Train encoder for target domain."""
    torch.cuda.set_device(0)
    ####################
    # 1. setup network #
    ####################
    # set train state for Dropout and BN layers
    src_classifier.eval()
    src_encoder.eval()

    tgt_encoder.train()
    tgt_classifier.eval()

    critic.train()
    generator.train()
    discriminator.train()

    # setup criterion and optimizer
    criterion = nn.CrossEntropyLoss()
    criterionRec = torch.nn.MSELoss()
    criterionGAN = loss.GANLoss()

    optimizer_tgt = optim.Adam(tgt_encoder.parameters(),
                               lr=cfg.learning_rate_apt,
                               betas=(cfg.beta1, cfg.beta2))
    optimizer_critic = optim.Adam(critic.parameters(),
                                  lr=cfg.learning_rate_apt_D,
                                  betas=(cfg.beta1, cfg.beta2))

    optimizer_autoencoder_ge = optim.Adam(list(tgt_encoder.parameters()) +
                                          list(generator.parameters()),
                                          lr=cfg.learning_rate_apt,
                                          betas=(cfg.beta1, cfg.beta2))
    optimizer_autoencoder_ad = optim.Adam(discriminator.parameters(),
                                          lr=cfg.learning_rate_apt_D,
                                          betas=(cfg.beta1, cfg.beta2))

    len_data_loader = min(len(src_data_loader), len(tgt_data_loader))

    ####################
    # 2. train network #
    ####################
    stepall = 0
    for epoch in range(cfg.num_epochs):
        # zip source and target data pair
        data_zip = enumerate(zip(src_data_loader, tgt_data_loader))
        for step, ((images_src, labels_src), (images_tgt,
                                              labels_tgt)) in data_zip:

            # make images variable
            images_src = make_variable(images_src)
            images_tgt = make_variable(images_tgt)

            labels_src = make_variable(labels_src).long().squeeze()
            labels_tgt = make_variable(labels_tgt).long().squeeze()

            ###########################
            # train discriminator #
            ###########################
            # zero gradients for optimizer
            optimizer_critic.zero_grad()

            # extract and concat features
            feat_src = src_encoder(images_src)
            feat_tgt = tgt_encoder(images_tgt)
            feat_concat = torch.cat((feat_src, feat_tgt), 0)

            # predict on discriminator
            pred_concat = critic(feat_concat.detach())

            # prepare real and fake label
            label_src = make_variable(torch.ones(feat_src.size(0)).long())
            label_tgt = make_variable(torch.zeros(feat_tgt.size(0)).long())
            label_concat = torch.cat((label_src, label_tgt), 0)

            # compute loss for critic
            loss_critic = criterion(pred_concat, label_concat)
            loss_critic.backward()

            # optimize critic
            optimizer_critic.step()

            ############################
            # train target encoder #
            ############################

            # zero gradients for optimizer
            optimizer_tgt.zero_grad()

            # predict on discriminator
            pred_tgt = critic(feat_tgt)

            # prepare fake labels
            label_tgt = make_variable(torch.ones(feat_tgt.size(0)).long())

            # compute loss for target encoder
            loss_tgt = criterion(pred_tgt, label_tgt)
            loss_tgt.backward()

            # optimize target encoder
            optimizer_tgt.step()

            ###########################
            # train autoencoder #
            ###########################

            # generator

            optimizer_autoencoder_ge.zero_grad()

            feat_src = src_encoder(images_src)
            feat_src_reshape = (feat_src.unsqueeze(2)).unsqueeze(2)
            reconst_src = generator(feat_src_reshape)
            loss_ge_src = criterionRec(reconst_src, images_src)

            feat_tgt = tgt_encoder(images_tgt)
            feat_tgt_reshape = (feat_tgt.unsqueeze(2)).unsqueeze(2)
            reconst_tgt = generator(feat_tgt_reshape)
            # loss_ge_tgt = criterionRec(reconst_tgt, images_tgt)

            reconst_src_G = discriminator(reconst_src)
            reconst_tgt_G = discriminator(reconst_tgt)

            loss_reconst_src_G = criterionGAN(reconst_src_G, True)
            loss_reconst_tgt_G = criterionGAN(reconst_tgt_G, True)

            loss_autoencoder_ge = cfg.para_const * loss_ge_src + loss_reconst_src_G + loss_reconst_tgt_G

            loss_autoencoder_ge.backward()
            optimizer_autoencoder_ge.step()

            # discriminator
            optimizer_autoencoder_ad.zero_grad()

            reconst_src_D = discriminator(reconst_src.detach())
            reconst_tgt_D = discriminator(reconst_tgt.detach())

            loss_reconst_src_D = criterionGAN(reconst_src_D, True)
            loss_reconst_tgt_D = criterionGAN(reconst_tgt_D, False)

            loss_autoencoder_ad = (loss_reconst_src_D +
                                   loss_reconst_tgt_D) * cfg.para_autoD

            loss_autoencoder_ad.backward()
            optimizer_autoencoder_ad.step()

            #######################
            # print step info #
            #######################

            acc_src = evaluate.evaluate_step(src_encoder, src_classifier,
                                             images_src, labels_src)
            acc_tgt = evaluate.evaluate_step(tgt_encoder, tgt_classifier,
                                             images_tgt, labels_tgt)

            infodic = OrderedDict([
                ('loss_reconst', loss_ge_src.data[0]),
                ('feat_d_loss', loss_critic.data[0]),
                ('feat_g_loss', loss_tgt.data[0]),
                ('auto_g_loss', loss_autoencoder_ge.data[0]),
                ('auto_d_loss', loss_autoencoder_ad.data[0]),
                ('acc_src', acc_src), ('acc_tgt', acc_tgt)
            ])

            for tag, value in infodic.items():
                logger.scalar_summary(tag, value, stepall)

            if ((step + 1) % cfg.log_step == 0):
                Saver.print_current_errors(epoch, (step + 1), infodic)

            stepall += 1

            # eval model on test set
        evaluate.eval_func(tgt_encoder, tgt_classifier, tgt_data_loader_eval)
        #############################
        # 2.4 save model parameters #
        #############################
        if ((epoch + 1) % cfg.save_step == 0):
            torch.save(
                critic.state_dict(),
                os.path.join(cfg.model_root, cfg.name,
                             "ADDA-critic-{}.pt".format(epoch + 1)))
            torch.save(
                tgt_encoder.state_dict(),
                os.path.join(cfg.model_root, cfg.name,
                             "ADDA-target-encoder-{}.pt".format(epoch + 1)))
            torch.save(
                tgt_classifier.state_dict(),
                os.path.join(
                    cfg.model_root, cfg.name,
                    "ADDA-target-tgt-classifier-{}.pt".format(epoch + 1)))
            torch.save(
                generator.state_dict(),
                os.path.join(cfg.model_root, cfg.name,
                             "ADDA-generator-{}.pt".format(epoch + 1)))

    torch.save(critic.state_dict(),
               os.path.join(cfg.model_root, cfg.name, "ADDA-critic-final.pt"))
    torch.save(
        tgt_encoder.state_dict(),
        os.path.join(cfg.model_root, cfg.name, "ADDA-target-encoder-final.pt"))
    torch.save(
        tgt_classifier.state_dict(),
        os.path.join(cfg.model_root, cfg.name,
                     "ADDA-target-tgt-classifier-final.pt"))
    torch.save(
        generator.state_dict(),
        os.path.join(cfg.model_root, cfg.name,
                     "ADDA-generator-final.pt".format(epoch + 1)))

    return tgt_encoder, tgt_classifier
Esempio n. 17
0
    model = make_cuda(
        inception_v3(pretrained=True, transform_input=True, extract_feat=True))
    pca = PCAWrapper(n_components=cfg.n_components)
    model.eval()

    # data loader for frames in ingle video
    # data_loader = get_dataloader(dataset="VideoFrame",
    #                              path=cfg.video_file,
    #                              num_frames=cfg.num_frames,
    #                              batch_size=cfg.batch_size)
    # data loader for frames decoded from several videos
    data_loader = get_dataloader(dataset="FrameImage",
                                 path=cfg.frame_root,
                                 batch_size=cfg.batch_size)

    # extract features by inception_v3
    feats = None
    for step, frames in enumerate(data_loader):
        print("extracting feature [{}/{}]".format(step + 1, len(data_loader)))
        feat = model(make_variable(frames))
        feats = concat_feat(feats, feat.data.cpu())

    # recude dimensions by PCA
    X = feats.numpy()
    pca.fit(X)
    X_ = pca.transform(X)
    print("reduce X {} to X_ {}".format(X.shape, X_.shape))

    # sabe PCA params
    pca.save_params(filepath=cfg.pca_model)
Esempio n. 18
0
def generate_labels(F,
                    F_1,
                    F_2,
                    target_dataset,
                    num_target,
                    useWeightedSampling=False):
    """Genrate pseudo labels for target domain dataset."""
    # set eval state for Dropout and BN layers
    F.eval()
    F_1.eval()
    F_2.eval()

    # get candidate samples
    print("Num of sampled target data: {}".format(num_target))

    # get sampled data loader
    if useWeightedSampling:
        classCounts, target_labels = atr.getClassCountsOfDataSet(
            target_dataset)
        assert np.all(classCounts > 0)
        classWeights = 1.0 / classCounts.astype(float)
        sampleWeights = classWeights[target_labels]
        target_sampler = torch.utils.data.sampler.WeightedRandomSampler(
            sampleWeights, num_target, replacement=True)
        #data_loader = make_data_loader(target_dataset, sampler=target_sampler, shuffle=False)
    else:
        dummy = get_sampled_data_loader(target_dataset,
                                        num_target,
                                        shuffle=True)
        target_sampler = dummy.sampler

    # Use this sampler to select out the indices we want.
    targetIndices = [z for z in target_sampler]

    # Make a subset random dampler and data loader.
    sampler = SubsetSampler(targetIndices)
    data_loader = torch.utils.data.DataLoader(dataset=target_dataset,
                                              batch_size=cfg.batch_size,
                                              shuffle=False,
                                              sampler=sampler)

    # get output of F_1 and F_2 on sampled target dataset
    out_F_1_total = None
    out_F_2_total = None
    gtTotal = None

    for step, (images, gt) in enumerate(data_loader):
        # convert into torch.autograd.Variable
        images = make_variable(images)
        # forward networks
        out_F = F(images)
        out_F_1 = F_1(out_F)
        out_F_2 = F_2(out_F)

        # concat outputs
        if step == 0:
            out_F_1_total = out_F_1.data.cpu()
            out_F_2_total = out_F_2.data.cpu()
            gtTotal = gt.data.cpu()
        else:
            out_F_1_total = torch.cat([out_F_1_total, out_F_1.data.cpu()], 0)
            out_F_2_total = torch.cat([out_F_2_total, out_F_2.data.cpu()], 0)
            gtTotal = torch.cat([gtTotal, gt.data.cpu()])

    print('gt type = {}, val = {}'.format(type(gtTotal), gtTotal))

    # guess pseudo labels
    excerpt, pseudo_labels = \
        guess_pseudo_labels(out_F_1_total, out_F_2_total)

    #print('pl shape before = {}'.format(pseudo_labels.shape))
    if 0:
        # Using GT labels shows these are correct.  The problem is that the labels from guess function are
        # not correct.
        pseudo_labels = torch.tensor([gtTotal[z] for z in excerpt])
        #print('pl shape after = {}'.format(pseudo_labels.shape))

    # Convert these indices into the subset into indices into target dataset.
    excerpt = np.array([targetIndices[i] for i in excerpt])

    assert len(excerpt) <= num_target
    assert np.all(np.logical_and(excerpt >= 0, excerpt < len(target_dataset)))
    print('Max excerpt = {}, but length of target data set = {}'.format(
        excerpt.max(), len(target_dataset)))

    return excerpt, pseudo_labels