Ejemplo n.º 1
0
def train_style_transfer(args):
    if not (args.train_data and args.valid_data):
        print("must chose train_data and valid_data")
        sys.exit()

    # make dataset
    trans = transforms.ToTensor()
    train_dataset = FaceDataset(args.train_data, transform=trans)
    label_dict = train_dataset.get_label_dict()
    valid_dataset = FaceDataset(args.valid_data, transform=trans)
    valid_dataset.give_label_dict(label_dict)
    train_loader = data_utils.DataLoader(train_dataset,
                                         batch_size=args.batch_size,
                                         shuffle=True,
                                         num_workers=1)
    valid_loader = data_utils.DataLoader(valid_dataset,
                                         batch_size=args.batch_size,
                                         shuffle=True,
                                         num_workers=1)
    train_size = len(train_dataset)
    valid_size = len(valid_dataset)
    loaders = {"train": train_loader, "valid": valid_loader}
    dataset_sizes = {"train": train_size, "valid": valid_size}

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

    # make network
    if args.model_type == "VAE":
        net = Autoencoder(train_dataset.label_num()).to(device)
        optimizer = optim.Adam(net.parameters(),
                               lr=args.lr,
                               weight_decay=args.weight_decay)
        best_model_wts = net.state_dict()
        best_loss = 1e10
        if args.generator_model and os.path.exists(args.generator_model):
            net.load_state_dict(torch.load(args.generator_model))

    elif args.model_type == "VAEGAN":
        generator = Autoencoder(train_dataset.label_num()).to(device)
        discriminator = Discriminator().to(device)
        classifier = Classifier(train_dataset.label_num()).to(device)
        generator_optimizer = optim.Adam(generator.parameters(),
                                         lr=args.lr,
                                         weight_decay=args.weight_decay)
        discriminator_optimizer = optim.Adam(discriminator.parameters(),
                                             lr=args.lr * 0.1,
                                             weight_decay=args.weight_decay)
        best_generator_wts = generator.state_dict()
        best_discriminator_wts = discriminator.state_dict()
        best_generator_loss = 1e10
        best_discriminator_loss = 1e10
        if args.generator_model and os.path.exists(args.generator_model):
            generator.load_state_dict(torch.load(args.generator_model))
        if args.discriminator_model and os.path.exists(
                args.discriminator_model):
            discriminator.load_state_dict(torch.load(args.discriminator_model))
        if args.classifier_model:
            classifier.load_state_dict(torch.load(args.classifier_model))
    # make loss function and optimizer
    criterion = nn.BCELoss(reduction="sum")
    classifier_criterion = nn.CrossEntropyLoss(reduction="sum")

    # initialize loss
    loss_history = {"train": [], "valid": []}

    # start training
    start_time = time.time()
    for epoch in range(args.epochs):
        print("epoch {}".format(epoch + 1))

        for phase in ["train", "valid"]:
            if phase == "train":
                if args.model_type == "VAE":
                    net.train(True)
                elif args.model_type == "VAEGAN":
                    generator.train(True)
                    discriminator.train(True)
            else:
                if args.model_type == "VAE":
                    net.train(False)
                elif args.model_type == "VAEGAN":
                    generator.train(False)
                    discriminator.train(False)

            # initialize running loss
            generator_running_loss = 0.0
            discriminator_running_loss = 0.0

            for i, data in enumerate(loaders[phase]):
                inputs, label = data

                # wrap the in valiables
                if phase == "train":
                    inputs = Variable(inputs).to(device)
                    label = Variable(label).to(device)
                    torch.set_grad_enabled(True)
                else:
                    inputs = Variable(inputs).to(device)
                    label = Variable(label).to(device)
                    torch.set_grad_enabled(False)

                # zero gradients
                if args.model_type == "VAE":
                    optimizer.zero_grad()
                    mu, var, outputs = net(inputs, label)
                    loss = loss_func(inputs, outputs, mu, var)
                    if phase == "train":
                        loss.backward()
                        optimizer.step()
                    generator_running_loss += loss.item()

                elif args.model_type == "VAEGAN":
                    real_label = Variable(
                        torch.ones((inputs.size()[0], 1), dtype=torch.float) -
                        0.2 * (torch.rand(inputs.size()[0], 1))).to(device)
                    fake_label = Variable(
                        torch.zeros((inputs.size()[0], 1), dtype=torch.float) +
                        0.2 * (torch.rand(inputs.size()[0], 1))).to(device)
                    discriminator_optimizer.zero_grad()

                    real_pred = discriminator(inputs)
                    real_loss = criterion(real_pred, real_label)

                    random_index = np.random.randint(0,
                                                     train_dataset.label_num(),
                                                     inputs.size()[0])
                    generate_label = Variable(
                        torch.zeros_like(label)).to(device)
                    for i, index in enumerate(random_index):
                        generate_label[i][index] = 1
                    mu, var, outputs = generator(inputs, label)
                    fake_pred = discriminator(outputs.detach())
                    fake_loss = criterion(fake_pred, fake_label)

                    discriminator_loss = real_loss + fake_loss
                    if phase == "train":
                        discriminator_loss.backward()
                        discriminator_optimizer.step()

                    generator_optimizer.zero_grad()
                    #class_loss = classifier_criterion(classifier(outputs), torch.max(label, 1)[1])

                    dis_loss = criterion(discriminator(outputs), real_label)
                    gen_loss = loss_func(inputs, outputs, mu, var)
                    generator_loss = dis_loss + gen_loss
                    if phase == "train":
                        generator_loss.backward()
                        generator_optimizer.step()

                    discriminator_running_loss += discriminator_loss.item()
                    generator_running_loss += generator_loss.item()

            if args.model_type == "VAE":
                epoch_loss = generator_running_loss / dataset_sizes[
                    phase] * args.batch_size
                loss_history[phase].append(epoch_loss)

                print("{} loss {:.4f}".format(phase, epoch_loss))
                if phase == "valid" and epoch_loss < best_loss:
                    best_model_wts = net.state_dict()
                    best_loss = epoch_loss

            elif args.model_type == "VAEGAN":
                epoch_generator_loss = generator_running_loss / dataset_sizes[
                    phase] * args.batch_size
                epoch_discriminator_loss = discriminator_running_loss / dataset_sizes[
                    phase] * args.batch_size

                print("{} generator loss {:.4f}".format(
                    phase, epoch_generator_loss))
                print("{} discriminator loss {:.4f}".format(
                    phase, epoch_discriminator_loss))
                if phase == "valid" and epoch_generator_loss < best_generator_loss:
                    best_generator_wts = generator.state_dict()
                    best_generator_loss = epoch_generator_loss
                if phase == "valid" and epoch_discriminator_loss < best_discriminator_loss:
                    best_discriminator_wts = discriminator.state_dict()
                    best_generator_loss = epoch_discriminator_loss

    elapsed_time = time.time() - start_time
    print("training complete in {:.0f}s".format(elapsed_time))
    if args.model_type == "VAE":
        net.load_state_dict(best_model_wts)
        return net, label_dict

    elif args.model_type == "VAEGAN":
        generator.load_state_dict(best_generator_wts)
        discriminator.load_state_dict(best_discriminator_wts)
        return (generator, discriminator), label_dict
Ejemplo n.º 2
0
N_val_btot = sdat_val.get_Nbatches_tot()

print('Training Batches: ', N_train_btot)
print('Validation Batches: ', N_val_btot)

# ----------- START TRAINING LOOP ---------------------
for i_epoch in range(num_epochs):
    d_train_wloss = 0.0
    d_train_gploss = 0.0
    g_train_loss = 0.0
    d_val_wloss = 0.0
    d_val_gploss = 0.0
    g_val_loss = 0.0

    G.train()
    D.train()
    for i_batch in range(N_train_btot):
        for i_c in range(n_critic):
            # ---------- DISCRIMINATOR STEP ---------------
            (data_b, i_vc) = sdat_train.get_rand_batch()
            real_wfs = torch.from_numpy(data_b).float()
            i_vc = [torch.from_numpy(i_v).float() for i_v in i_vc]
            Nsamp = real_wfs.size(0)
            if cuda:
                real_wfs = real_wfs.cuda()
                i_vc = [i_v.cuda() for i_v in i_vc]
            d_optimizer.zero_grad()

            z = noise(Nbatch, z_size)
            z = torch.from_numpy(z).float()
            if cuda:
Ejemplo n.º 3
0
fixed_noise = torch.randn(128, latent_size, 1, 1, device=device)

history = {
    'lossD': [],
    'lossG': [],
    'valLossD': [],
    'avgStart': [],
    'avgEnd': [],
    'valid': [],
    'validHist': [],
    'imgs': [],
    'epoch': []
}

for epoch in range(n_epochs):
    netD.train()
    netG.train()
    for i, data in enumerate(loader['train']):

        x_real = data['moves'].type(Tensor)

        valid = Tensor(x_real.size(0), 1).fill_(1)
        fake = Tensor(x_real.size(0), 1).fill_(0)

        if epoch == 0 and i == 0:
            viz.images(x_real[:16].flip(2),
                       opts=dict(title='Epoch' + str(epoch),
                                 width=1000,
                                 height=250))

        netD.zero_grad()