Пример #1
0
def train_discriminator(dis, gen, criterion, optimizer, epochs,
                        dis_adversarial_train_loss, dis_adversarial_train_acc,
                        args):
    """
    Train discriminator
    """
    generate_samples(gen, args.batch_size, args.n_samples, NEGATIVE_FILE)
    data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, args.batch_size)
    for epoch in range(epochs):
        correct = 0
        total_loss = 0.
        for data, target in data_iter:
            if args.cuda:
                data, target = data.cuda(), target.cuda()
            target = target.contiguous().view(-1)
            output = dis(data)
            pred = output.data.max(1)[1]
            correct += pred.eq(target.data).cpu().sum()
            loss = criterion(output, target)
            total_loss += loss.item()
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
        data_iter.reset()
        avg_loss = total_loss / len(data_iter)
        acc = correct.item() / data_iter.data_num
        print("Epoch {}, train loss: {:.5f}, train acc: {:.3f}".format(
            epoch, avg_loss, acc))
        dis_adversarial_train_loss.append(avg_loss)
        dis_adversarial_train_acc.append(acc)
Пример #2
0
def main():
    random.seed(SEED)
    np.random.seed(SEED)

    # Define Networks
    generator = Generator(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    discriminator = Discriminator(d_num_class, VOCAB_SIZE, d_emb_dim,
                                  d_filter_sizes, d_num_filters, d_dropout)
    target_lstm = TargetLSTM(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    if opt.cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()
        target_lstm = target_lstm.cuda()
    # Generate toy data using target lstm
    print('Generating data ...')
    generate_samples(target_lstm, BATCH_SIZE, GENERATED_NUM, POSITIVE_FILE)

    # Load data from file
    gen_data_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)

    # Pretrain Generator using MLE
    gen_criterion = nn.NLLLoss(size_average=False)
    gen_optimizer = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    print('Pretrain with MLE ...')
    for epoch in range(PRE_EPOCH_NUM):
        loss = train_epoch(generator, gen_data_iter, gen_criterion,
                           gen_optimizer)
        print('Epoch [%d] Model Loss: %f' % (epoch, loss))
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
        eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
        loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
        print('Epoch [%d] True Loss: %f' % (epoch, loss))

    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Dsicriminator ...')
    for epoch in range(5):
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
        for _ in range(3):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                               dis_optimizer)
            print('Epoch [%d], loss: %f' % (epoch, loss))
    # Adversarial Training
    rollout = Rollout(generator, 0.8)
    print('#####################################################')
    print('Start Adeversatial Training...\n')
    gen_gan_loss = GANLoss()
    gen_gan_optm = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_gan_loss = gen_gan_loss.cuda()
    gen_criterion = nn.NLLLoss(size_average=False)
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    for total_batch in range(TOTAL_BATCH):
        # Train the generator for one step
        for it in range(1):
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # construct the input to the generator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(
                torch.cat([zeros, samples.data], dim=1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view((-1, ))
            # calculate the reward
            rewards = rollout.get_reward(samples, 16, discriminator)
            rewards = Variable(torch.Tensor(rewards))
            if opt.cuda:
                rewards = torch.exp(rewards.cuda()).contiguous().view((-1, ))
            prob = generator.forward(inputs)
            loss = gen_gan_loss(prob, targets, rewards)
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()

        if total_batch % 1 == 0 or total_batch == TOTAL_BATCH - 1:
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
            eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
            loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
            print('Batch [%d] True Loss: %f' % (total_batch, loss))
        rollout.update_params()

        for _ in range(4):
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                             NEGATIVE_FILE)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                        BATCH_SIZE)
            for _ in range(2):
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                                   dis_optimizer)
Пример #3
0
def train_GAN(conf_data):
    """Training Process for GAN.
    
    Parameters
    ----------
    conf_data: dict
        Dictionary containing all parameters and objects.       

    Returns
    -------
    conf_data: dict
        Dictionary containing all parameters and objects.       

    """
    seq = conf_data['GAN_model']['seq']
    if seq == 1:
        pre_epoch_num = conf_data['generator']['pre_epoch_num']
        GENERATED_NUM = 10000
        EVAL_FILE = 'eval.data'
        POSITIVE_FILE = 'real.data'
        NEGATIVE_FILE = 'gene.data'
    temp = 1  #TODO Determines how many times is the discriminator updated. Take this as a value input
    epochs = int(conf_data['GAN_model']['epochs'])
    if seq == 0:
        dataloader = conf_data['data_learn']
    mini_batch_size = int(conf_data['GAN_model']['mini_batch_size'])
    data_label = int(conf_data['GAN_model']['data_label'])
    cuda = conf_data['cuda']
    g_latent_dim = int(conf_data['generator']['latent_dim'])
    classes = int(conf_data['GAN_model']['classes'])

    w_loss = int(conf_data['GAN_model']['w_loss'])

    clip_value = float(conf_data['GAN_model']['clip_value'])
    n_critic = int(conf_data['GAN_model']['n_critic'])

    lambda_gp = int(conf_data['GAN_model']['lambda_gp'])

    log_file = open(conf_data['performance_log'] + "/log.txt", "w+")
    #Covert these to parameters of the config data
    Tensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor
    conf_data['Tensor'] = Tensor
    LongTensor = torch.cuda.LongTensor if cuda else torch.LongTensor
    conf_data['LongTensor'] = LongTensor
    FloatTensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor
    conf_data['FloatTensor'] = FloatTensor

    conf_data['epochs'] = epochs

    #print ("Just before training")
    if seq == 1:  #TODO: Change back to 1
        target_lstm = TargetLSTM(conf_data['GAN_model']['vocab_size'],
                                 conf_data['generator']['embedding_dim'],
                                 conf_data['generator']['hidden_dim'],
                                 conf_data['cuda'])
        if cuda == True:
            target_lstm = target_lstm.cuda()
        conf_data['target_lstm'] = target_lstm
        gen_data_iter = GenDataIter('real.data', mini_batch_size)
        generator = conf_data['generator_model']
        discriminator = conf_data['discriminator_model']
        g_loss_func = conf_data['generator_loss']
        d_loss_func = conf_data['discriminator_loss']
        optimizer_D = conf_data['discriminator_optimizer']
        optimizer_G = conf_data['generator_optimizer']
        #print('Pretrain with MLE ...')
        for epoch in range(pre_epoch_num):  #TODO: Change the range
            loss = train_epoch(generator, gen_data_iter, g_loss_func,
                               optimizer_G, conf_data, 'g')
            print('Epoch [%d] Model Loss: %f' % (epoch, loss))
            generate_samples(generator, mini_batch_size, GENERATED_NUM,
                             EVAL_FILE, conf_data)
            eval_iter = GenDataIter(EVAL_FILE, mini_batch_size)
            loss = eval_epoch(target_lstm, eval_iter, g_loss_func, conf_data)
            print('Epoch [%d] True Loss: %f' % (epoch, loss))

        dis_criterion = d_loss_func
        dis_optimizer = optimizer_D
        #TODO: Understand why the below two code line were there ?
        # if conf_data['cuda']:
        #     dis_criterion = dis_criterion.cuda()

        #print('Pretrain Dsicriminator ...')
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                    mini_batch_size)
        for epoch in range(5):  #TODO: change back 5
            generate_samples(generator, mini_batch_size, GENERATED_NUM,
                             NEGATIVE_FILE, conf_data)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                        mini_batch_size)
            for _ in range(3):  #TODO: change back 3
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                                   dis_optimizer, conf_data, 'd')
                print('Epoch [%d], loss: %f' % (epoch, loss))
        conf_data['generator_model'] = generator
        conf_data['discriminator_model'] = discriminator
        torch.save(conf_data['generator_model'].state_dict(),
                   conf_data['save_model_path'] + '/Seq/' + 'pre_generator.pt')
        torch.save(
            conf_data['discriminator_model'].state_dict(),
            conf_data['save_model_path'] + '/Seq/' + 'pre_discriminator.pt')

        conf_data['rollout'] = Rollout(generator, 0.8)

    for epoch in range(epochs):
        conf_data['epoch'] = epoch
        if seq == 0:
            to_iter = dataloader
        elif seq == 1:  #TODO: Change this back to 1
            to_iter = [1]

        for i, iterator in enumerate(to_iter):
            optimizer_D = conf_data['discriminator_optimizer']
            optimizer_G = conf_data['generator_optimizer']

            generator = conf_data['generator_model']
            discriminator = conf_data['discriminator_model']

            g_loss_func = conf_data['generator_loss']
            d_loss_func = conf_data['discriminator_loss']

            # if aux = 1:

            #print ("Reached here --------------> ")
            conf_data['iterator'] = i
            if seq == 0:

                if data_label == 1:
                    imgs, labels = iterator
                else:
                    imgs = iterator
                # Adversarial ground truths
                valid = Variable(Tensor(imgs.size(0), 1).fill_(1.0),
                                 requires_grad=False)
                conf_data['valid'] = valid
                fake = Variable(Tensor(imgs.size(0), 1).fill_(0.0),
                                requires_grad=False)
                conf_data['fake'] = fake
                # Configure input
                real_imgs = Variable(imgs.type(Tensor))

                if data_label == 1:
                    labels = Variable(labels.type(LongTensor))
                # Sample noise as generator input
                z = Variable(
                    Tensor(
                        np.random.normal(0, 1, (imgs.shape[0], g_latent_dim))))
                if classes > 0:
                    gen_labels = Variable(
                        LongTensor(np.random.randint(0, classes,
                                                     imgs.shape[0])))
                    conf_data['gen_labels'] = gen_labels
            # elif seq == 1: #If yes seqGAN
            #     # samples = generator.sample(mini_batch_size,conf_data['generator']['sequece_length'])
            #     # zeros = torch.zeros((mini_batch_size,1)).type(LongTensor)
            #     # imgs = Variable(torch.cat([zeros,samples.data]),dim=1)[:,:-1].contiguous() #TODO: change imgs to inps all, to make more sense of the code
            #     # targets = Variable(sample.data).contiguous().view((-1,))
            #     # rewards = rollout.get_reward(sample,16,discriminator)
            #     # rewards = Variable(Tensor(rewards))
            #     # prob = generator.forward(inputs)
            #     # loss = gen_gan_loss(prob)
            #     pass
            #     #optimizer_G

            # ---------------------
            #  Train Discriminator
            # ---------------------
            optimizer_D.zero_grad()
            if seq == 1:  #TODO change this back to 1
                dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                            mini_batch_size)
            for i in range(
                    temp
            ):  # TODO: Make this a parameter -> for x updates --> I am read the stored models here as well. Should I reamove this ???
                optimizer_D = conf_data['discriminator_optimizer']
                optimizer_G = conf_data['generator_optimizer']

                generator = conf_data['generator_model']
                discriminator = conf_data['discriminator_model']

                g_loss_func = conf_data['generator_loss']
                d_loss_func = conf_data['discriminator_loss']
                if classes <= 0:
                    #print ("Reached here 2 --------------> ")
                    if seq == 0:
                        gen_imgs = generator(z)
                        # Measure discriminator's ability to classify real from generated samples
                        #Real images
                        real_validity = discriminator(real_imgs)
                        #Fake images
                        fake_validity = discriminator(gen_imgs.detach())
                    if seq == 1:
                        generate_samples(generator, mini_batch_size,
                                         GENERATED_NUM, NEGATIVE_FILE,
                                         conf_data)
                        dis_data_iter = DisDataIter(POSITIVE_FILE,
                                                    NEGATIVE_FILE,
                                                    mini_batch_size)
                        loss = train_epoch(discriminator, dis_data_iter,
                                           d_loss_func, optimizer_D, conf_data,
                                           'd')
                        conf_data['d_loss'] = loss
                        #exit()

                else:
                    if seq == 0:
                        gen_imgs = generator(z, gen_labels)
                        real_validity = discriminator(real_imgs, labels)
                        fake_validity = discriminator(gen_imgs.detach(),
                                                      labels)

                if seq == 0:
                    conf_data['gen_imgs'] = gen_imgs
                if seq == 0:
                    if w_loss == 0:
                        real_loss = d_loss_func.loss(real_validity, valid)
                        fake_loss = d_loss_func.loss(fake_validity, fake)
                        d_loss = (real_loss + fake_loss) / 2
                    elif w_loss == 1:
                        d_loss = -d_loss_func.loss(real_validity,
                                                   valid) + d_loss_func.loss(
                                                       fake_validity, fake)
                        if lambda_gp > 0:
                            conf_data['real_data_sample'] = real_imgs.data
                            conf_data['fake_data_sample'] = gen_imgs.data
                            conf_data = compute_gradient_penalty(conf_data)
                            gradient_penalty = conf_data['gradient_penalty']
                            d_loss = d_loss + lambda_gp * gradient_penalty
                    conf_data['d_loss'] = d_loss
                    d_loss.backward()
                    optimizer_D.step()

                if clip_value > 0:
                    # Clip weights of discriminator
                    for p in discriminator.parameters():
                        p.data.clamp_(-clip_value, clip_value)

            # -----------------
            #  Train Generator
            # -----------------
            conf_data['generator_model'] = generator
            conf_data['discriminator_model'] = discriminator

            #Next 4 lines were recently added maybe have to remove this.
            conf_data['optimizer_G'] = optimizer_G
            conf_data['optimizer_D'] = optimizer_D
            conf_data['generator_loss'] = g_loss_func
            conf_data['discriminator_loss'] = d_loss_func
            if seq == 0:
                conf_data['noise'] = z

            if n_critic <= 0:
                conf_data = training_fucntion_generator(conf_data)
            elif n_critic > 0:
                # Train the generator every n_critic iterations
                if i % n_critic == 0:
                    conf_data = training_fucntion_generator(conf_data)
            #exit()

        # print ("------------------ Here (train_GAN.py)")

            if seq == 0:
                batches_done = epoch * len(dataloader) + i
                if batches_done % int(conf_data['sample_interval']) == 0:
                    if classes <= 0:
                        # print ("Here")
                        # print (type(gen_imgs.data[:25]))
                        # print (gen_imgs.data[:25].shape)
                        save_image(gen_imgs.data[:25],
                                   conf_data['result_path'] +
                                   '/%d.png' % batches_done,
                                   nrow=5,
                                   normalize=True)
                    elif classes > 0:
                        sample_image(10, batches_done, conf_data)
        if seq == 0:
            log_file.write("[Epoch %d/%d] [D loss: %f] [G loss: %f] \n" %
                           (epoch, epochs, conf_data['d_loss'].item(),
                            conf_data['g_loss'].item()))
        elif seq == 1:
            # print ("Done")
            log_file.write(
                "[Epoch %d/%d] [D loss: %f] [G loss: %f] \n" %
                (epoch, epochs, conf_data['d_loss'], conf_data['g_loss']))
    conf_data['generator_model'] = generator
    conf_data['discriminator_model'] = discriminator
    conf_data['log_file'] = log_file
    return conf_data
Пример #4
0
def main(opt):

    cuda = opt.cuda
    visualize = opt.visualize
    print(f"cuda = {cuda}, visualize = {opt.visualize}")
    if visualize:
        if PRE_EPOCH_GEN > 0:
            pretrain_G_score_logger = VisdomPlotLogger(
                'line', opts={'title': 'Pre-train G Goodness Score'})
        if PRE_EPOCH_DIS > 0:
            pretrain_D_loss_logger = VisdomPlotLogger(
                'line', opts={'title': 'Pre-train D Loss'})
        adversarial_G_score_logger = VisdomPlotLogger(
            'line',
            opts={
                'title': f'Adversarial G {GD} Goodness Score',
                'Y': '{0, 13}',
                'X': '{0, TOTAL_BATCH}'
            })
        if CHECK_VARIANCE:
            G_variance_logger = VisdomPlotLogger(
                'line', opts={'title': f'Adversarial G {GD} Variance'})
        G_text_logger = VisdomTextLogger(update_type='APPEND')
        adversarial_D_loss_logger = VisdomPlotLogger(
            'line', opts={'title': 'Adversarial Batch D Loss'})

    # Define Networks
    generator = Generator(VOCAB_SIZE, g_emb_dim, g_hidden_dim, cuda)
    n_gen = Variable(torch.Tensor([get_n_params(generator)]))
    use_cuda = False
    if cuda:
        n_gen = n_gen.cuda()
        use_cuda = True
    print('Number of parameters in the generator: {}'.format(n_gen))
    discriminator = LSTMDiscriminator(d_num_class, VOCAB_SIZE,
                                      d_lstm_hidden_dim, use_cuda)
    c_phi_hat = AnnexNetwork(d_num_class, VOCAB_SIZE, d_emb_dim,
                             c_filter_sizes, c_num_filters, d_dropout,
                             BATCH_SIZE, g_sequence_len)
    if cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()
        c_phi_hat = c_phi_hat.cuda()

    # Generate toy data using target lstm
    print('Generating data ...')

    # Load data from file
    gen_data_iter = DataLoader(POSITIVE_FILE, BATCH_SIZE)

    gen_criterion = nn.NLLLoss(size_average=False)
    gen_optimizer = optim.Adam(generator.parameters())
    if cuda:
        gen_criterion = gen_criterion.cuda()
    # 预训练Generator
    # Pretrain Generator using MLE
    pre_train_scores = []
    if MLE:
        print('Pretrain with MLE ...')
        for epoch in range(int(np.ceil(PRE_EPOCH_GEN))):
            loss = train_epoch(generator, gen_data_iter, gen_criterion,
                               gen_optimizer, PRE_EPOCH_GEN, epoch, cuda)
            print('Epoch [%d] Model Loss: %f' % (epoch, loss))
            samples = generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                                       EVAL_FILE)
            eval_iter = DataLoader(EVAL_FILE, BATCH_SIZE)
            generated_string = eval_iter.convert_to_char(samples)
            print(generated_string)
            eval_score = get_data_goodness_score(generated_string, SPACES)
            if SPACES == False:
                kl_score = get_data_freq(generated_string)
            else:
                kl_score = -1
            freq_score = get_char_freq(generated_string, SPACES)
            pre_train_scores.append(eval_score)
            print('Epoch [%d] Generation Score: %f' % (epoch, eval_score))
            print('Epoch [%d] KL Score: %f' % (epoch, kl_score))
            print('Epoch [{}] Character distribution: {}'.format(
                epoch, list(freq_score)))

            torch.save(
                generator.state_dict(),
                f"checkpoints/MLE_space_{SPACES}_length_{SEQ_LEN}_preTrainG_epoch_{epoch}.pth"
            )

            if visualize:
                pretrain_G_score_logger.log(epoch, eval_score)
    else:
        generator.load_state_dict(torch.load(weights_path))

    # Finishing training with MLE
    if GD == "MLE":
        for epoch in range(3 * int(GENERATED_NUM / BATCH_SIZE)):
            loss = train_epoch_batch(generator, gen_data_iter, gen_criterion,
                                     gen_optimizer, PRE_EPOCH_GEN, epoch,
                                     int(GENERATED_NUM / BATCH_SIZE), cuda)
            print('Epoch [%d] Model Loss: %f' % (epoch, loss))
            samples = generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                                       EVAL_FILE)
            eval_iter = DataLoader(EVAL_FILE, BATCH_SIZE)
            generated_string = eval_iter.convert_to_char(samples)
            print(generated_string)
            eval_score = get_data_goodness_score(generated_string, SPACES)
            if SPACES == False:
                kl_score = get_data_freq(generated_string)
            else:
                kl_score = -1
            freq_score = get_char_freq(generated_string, SPACES)
            pre_train_scores.append(eval_score)
            print('Epoch [%d] Generation Score: %f' % (epoch, eval_score))
            print('Epoch [%d] KL Score: %f' % (epoch, kl_score))
            print('Epoch [{}] Character distribution: {}'.format(
                epoch, list(freq_score)))

            torch.save(
                generator.state_dict(),
                f"checkpoints/MLE_space_{SPACES}_length_{SEQ_LEN}_preTrainG_epoch_{epoch}.pth"
            )

            if visualize:
                pretrain_G_score_logger.log(epoch, eval_score)
    # 预训练Discriminator
    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Discriminator ...')
    for epoch in range(PRE_EPOCH_DIS):
        samples = generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                                   NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE,
                                    SEQ_LEN)
        for _ in range(PRE_ITER_DIS):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                               dis_optimizer, 1, 1, cuda)
            print('Epoch [%d], loss: %f' % (epoch, loss))
            if visualize:
                pretrain_D_loss_logger.log(epoch, loss)
    # 对抗训练
    # Adversarial Training
    rollout = Rollout(generator, UPDATE_RATE)
    print('#####################################################')
    print('Start Adversarial Training...\n')

    gen_gan_loss = GANLoss()
    gen_gan_optm = optim.Adam(generator.parameters())
    if cuda:
        gen_gan_loss = gen_gan_loss.cuda()
    gen_criterion = nn.NLLLoss(size_average=False)
    if cuda:
        gen_criterion = gen_criterion.cuda()

    dis_criterion = nn.NLLLoss(size_average=False)
    dis_criterion_bce = nn.BCELoss()
    dis_optimizer = optim.Adam(discriminator.parameters())
    if cuda:
        dis_criterion = dis_criterion.cuda()

    c_phi_hat_loss = VarianceLoss()
    if cuda:
        c_phi_hat_loss = c_phi_hat_loss.cuda()
    c_phi_hat_optm = optim.Adam(c_phi_hat.parameters())

    gen_scores = pre_train_scores

    for total_batch in range(TOTAL_BATCH):
        # Train the generator for one step
        for it in range(G_STEPS):
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # samples has size (BS, sequence_len)
            # Construct the input to the generator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(
                torch.cat([zeros, samples.data], dim=1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view((-1, ))
            if opt.cuda:
                inputs = inputs.cuda()
                targets = targets.cuda()
            # Calculate the reward
            rewards = rollout.get_reward(samples, discriminator, VOCAB_SIZE,
                                         cuda)
            rewards = Variable(torch.Tensor(rewards))
            if cuda:
                rewards = torch.exp(rewards.cuda()).contiguous().view((-1, ))
            rewards = torch.exp(rewards)
            # rewards has size (BS)
            prob = generator.forward(inputs)
            # prob has size (BS*sequence_len, VOCAB_SIZE)
            # 3.a
            theta_prime = g_output_prob(prob)
            # theta_prime has size (BS*sequence_len, VOCAB_SIZE)
            # 3.e and f
            c_phi_z_ori, c_phi_z_tilde_ori = c_phi_out(
                GD,
                c_phi_hat,
                theta_prime,
                discriminator,
                temperature=DEFAULT_TEMPERATURE,
                eta=DEFAULT_ETA,
                cuda=cuda)
            c_phi_z_ori = torch.exp(c_phi_z_ori)
            c_phi_z_tilde_ori = torch.exp(c_phi_z_tilde_ori)
            c_phi_z = torch.sum(c_phi_z_ori[:, 1]) / BATCH_SIZE
            c_phi_z_tilde = -torch.sum(c_phi_z_tilde_ori[:, 1]) / BATCH_SIZE
            if opt.cuda:
                c_phi_z = c_phi_z.cuda()
                c_phi_z_tilde = c_phi_z_tilde.cuda()
                c_phi_hat = c_phi_hat.cuda()
            # 3.i
            grads = []
            first_term_grads = []
            # 3.h optimization step
            # first, empty the gradient buffers
            gen_gan_optm.zero_grad()
            # first, re arrange prob
            new_prob = prob.view((BATCH_SIZE, g_sequence_len, VOCAB_SIZE))
            # 3.g new gradient loss for relax
            batch_i_grads_1 = gen_gan_loss.forward_reward_grads(
                samples, new_prob, rewards, generator, BATCH_SIZE,
                g_sequence_len, VOCAB_SIZE, cuda)
            batch_i_grads_2 = gen_gan_loss.forward_reward_grads(
                samples, new_prob, c_phi_z_tilde_ori[:, 1], generator,
                BATCH_SIZE, g_sequence_len, VOCAB_SIZE, cuda)
            # batch_i_grads_1 and batch_i_grads_2 should be of length BATCH SIZE of arrays of all the gradients
            # # 3.i
            batch_grads = batch_i_grads_1
            if GD != "REINFORCE":
                for i in range(len(batch_i_grads_1)):
                    for j in range(len(batch_i_grads_1[i])):
                        batch_grads[i][j] = torch.add(batch_grads[i][j], (-1) *
                                                      batch_i_grads_2[i][j])
            # batch_grads should be of length BATCH SIZE
            grads.append(batch_grads)
            # NOW, TRAIN THE GENERATOR
            generator.zero_grad()
            for i in range(g_sequence_len):
                # 3.g new gradient loss for relax
                cond_prob = gen_gan_loss.forward_reward(
                    i, samples, new_prob, rewards, BATCH_SIZE, g_sequence_len,
                    VOCAB_SIZE, cuda)
                c_term = gen_gan_loss.forward_reward(i, samples, new_prob,
                                                     c_phi_z_tilde_ori[:, 1],
                                                     BATCH_SIZE,
                                                     g_sequence_len,
                                                     VOCAB_SIZE, cuda)
                if GD != "REINFORCE":
                    cond_prob = torch.add(cond_prob, (-1) * c_term)
                new_prob[:, i, :].backward(cond_prob, retain_graph=True)
            # 3.h - still training the generator, with the last two terms of the RELAX equation
            if GD != "REINFORCE":
                c_phi_z.backward(retain_graph=True)
                c_phi_z_tilde.backward(retain_graph=True)
            gen_gan_optm.step()
            # 3.i
            if CHECK_VARIANCE:
                # c_phi_z term
                partial_grads = []
                for j in range(BATCH_SIZE):
                    generator.zero_grad()
                    c_phi_z_ori[j, 1].backward(retain_graph=True)
                    j_grads = []
                    for p in generator.parameters():
                        j_grads.append(p.grad.clone())
                    partial_grads.append(j_grads)
                grads.append(partial_grads)
                # c_phi_z_tilde term
                partial_grads = []
                for j in range(BATCH_SIZE):
                    generator.zero_grad()
                    c_phi_z_tilde_ori[j, 1].backward(retain_graph=True)
                    j_grads = []
                    for p in generator.parameters():
                        j_grads.append(-1 * p.grad.clone())
                    partial_grads.append(j_grads)
                grads.append(partial_grads)
                # Uncomment the below code if you want to check gradients
                """
                print('1st contribution to the gradient')
                print(grads[0][0][6])
                print('2nd contribution to the gradient')
                print(grads[1][0][6])
                print('3rd contribution to the gradient')
                print(grads[2][0][6])
                """
                #grads should be of length 3
                #grads[0] should be of length BATCH SIZE
                # 3.j
                all_grads = grads[0]
                if GD != "REINFORCE":
                    for i in range(len(grads[0])):
                        for j in range(len(grads[0][i])):
                            all_grads[i][j] = torch.add(
                                torch.add(all_grads[i][j], grads[1][i][j]),
                                grads[2][i][j])
                # all_grads should be of length BATCH_SIZE
                c_phi_hat_optm.zero_grad()
                var_loss = c_phi_hat_loss.forward(all_grads, cuda)  #/n_gen
                true_variance = c_phi_hat_loss.forward_variance(
                    all_grads, cuda)
                var_loss.backward()
                c_phi_hat_optm.step()
                print(
                    'Batch [{}] Estimate of the variance of the gradient at step {}: {}'
                    .format(total_batch, it, true_variance[0]))
                if visualize:
                    G_variance_logger.log((total_batch + it), true_variance[0])

        # Evaluate the quality of the Generator outputs
        if total_batch % 1 == 0 or total_batch == TOTAL_BATCH - 1:
            samples = generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                                       EVAL_FILE)
            eval_iter = DataLoader(EVAL_FILE, BATCH_SIZE)
            generated_string = eval_iter.convert_to_char(samples)
            print(generated_string)
            eval_score = get_data_goodness_score(generated_string, SPACES)
            if SPACES == False:
                kl_score = get_data_freq(generated_string)
            else:
                kl_score = -1
            freq_score = get_char_freq(generated_string, SPACES)
            gen_scores.append(eval_score)
            print('Batch [%d] Generation Score: %f' %
                  (total_batch, eval_score))
            print('Batch [%d] KL Score: %f' % (total_batch, kl_score))
            print('Epoch [{}] Character distribution: {}'.format(
                total_batch, list(freq_score)))

            #Checkpoint & Visualize
            if total_batch % 10 == 0 or total_batch == TOTAL_BATCH - 1:
                torch.save(
                    generator.state_dict(),
                    f'checkpoints/{GD}_G_space_{SPACES}_pretrain_{PRE_EPOCH_GEN}_batch_{total_batch}.pth'
                )
            if visualize:
                [G_text_logger.log(line) for line in generated_string]
                adversarial_G_score_logger.log(total_batch, eval_score)

        # Train the discriminator
        batch_G_loss = 0.0

        for b in range(D_EPOCHS):

            for data, _ in gen_data_iter:

                data = Variable(data)
                real_data = convert_to_one_hot(data, VOCAB_SIZE, cuda)
                real_target = Variable(torch.ones((data.size(0), 1)))
                samples = generator.sample(data.size(0),
                                           g_sequence_len)  # bs x seq_len
                fake_data = convert_to_one_hot(
                    samples, VOCAB_SIZE, cuda)  # bs x seq_len x vocab_size
                fake_target = Variable(torch.zeros((data.size(0), 1)))

                if cuda:
                    real_target = real_target.cuda()
                    fake_target = fake_target.cuda()
                    real_data = real_data.cuda()
                    fake_data = fake_data.cuda()

                real_pred = torch.exp(discriminator(real_data)[:, 1])
                fake_pred = torch.exp(discriminator(fake_data)[:, 1])

                D_real_loss = dis_criterion_bce(real_pred, real_target)
                D_fake_loss = dis_criterion_bce(fake_pred, fake_target)
                D_loss = D_real_loss + D_fake_loss
                dis_optimizer.zero_grad()
                D_loss.backward()
                dis_optimizer.step()

            gen_data_iter.reset()

            print('Batch [{}] Discriminator Loss at step and epoch {}: {}'.
                  format(total_batch, b, D_loss.data[0]))

        if visualize:
            adversarial_D_loss_logger.log(total_batch, D_loss.data[0])

    if not visualize:
        plt.plot(gen_scores)
        plt.ylim((0, 13))
        plt.title('{}_after_{}_epochs_of_pretraining'.format(
            GD, PRE_EPOCH_GEN))
        plt.show()
Пример #5
0
def main():
    random.seed(SEED)
    np.random.seed(SEED)
    calc_bleu([1, 10, 12])
    exit()
    # Build up dataset
    s_train, s_test = load_from_big_file('../data/train_data_obama.txt')
    # idx_to_word: List of id to word
    # word_to_idx: Dictionary mapping word to id
    idx_to_word, word_to_idx = fetch_vocab(s_train, s_train, s_test)
    # TODO: 1. Prepare data for attention model
    # input_seq, target_seq = prepare_data(DATA_GERMAN, DATA_ENGLISH, word_to_idx)

    global VOCAB_SIZE
    VOCAB_SIZE = len(idx_to_word)

    save_vocab(CHECKPOINT_PATH + 'metadata.data', idx_to_word, word_to_idx,
               VOCAB_SIZE, g_emb_dim, g_hidden_dim, g_sequence_len)

    print('VOCAB SIZE:', VOCAB_SIZE)
    # Define Networks
    generator = Generator(VOCAB_SIZE, g_emb_dim, g_hidden_dim, g_sequence_len,
                          BATCH_SIZE, opt.cuda)
    discriminator = Discriminator(d_num_class, VOCAB_SIZE, d_emb_dim,
                                  d_filter_sizes, d_num_filters, d_dropout)
    target_lstm = TargetLSTM(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    if opt.cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()
        target_lstm = target_lstm.cuda()
    # Generate toy data using target lstm
    print('Generating data ...')
    generate_real_data('../data/train_data_obama.txt', BATCH_SIZE,
                       GENERATED_NUM, idx_to_word, word_to_idx, POSITIVE_FILE,
                       TEST_FILE)
    # Create Test data iterator for testing
    test_iter = GenDataIter(TEST_FILE, BATCH_SIZE)
    # generate_samples(target_lstm, BATCH_SIZE, GENERATED_NUM, POSITIVE_FILE, idx_to_word)

    # Load data from file
    gen_data_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)

    # Pretrain Generator using MLE
    # gen_criterion = nn.NLLLoss(size_average=False)
    gen_criterion = nn.CrossEntropyLoss()
    gen_optimizer = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    print('Pretrain with MLE ...')
    for epoch in range(PRE_EPOCH_NUM):
        loss = train_epoch(generator, gen_data_iter, gen_criterion,
                           gen_optimizer)
        print('Epoch [%d] Model Loss: %f' % (epoch, loss))
        print('Training Output')
        test_predict(generator, test_iter, idx_to_word, train_mode=True)

        sys.stdout.flush()
        # TODO: 2. Flags to ensure dimension of model input is handled
        # generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
        """
        eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
        print('Iterator Done')
        loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
        print('Epoch [%d] True Loss: %f' % (epoch, loss))
        """
    print('OUTPUT AFTER PRE-TRAINING')
    test_predict(generator, test_iter, idx_to_word, train_mode=True)

    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Discriminator ...')
    for epoch in range(3):
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
        for _ in range(3):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                               dis_optimizer)
            print('Epoch [%d], loss: %f' % (epoch, loss))
            sys.stdout.flush()
    # Adversarial Training
    rollout = Rollout(generator, 0.8)
    print('#####################################################')
    print('Start Adversarial Training...\n')
    gen_gan_loss = GANLoss()

    gen_gan_optm = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_gan_loss = gen_gan_loss.cuda()
    gen_criterion = nn.NLLLoss(size_average=False)
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    real_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)
    for total_batch in range(TOTAL_BATCH):
        ## Train the generator for one step
        for it in range(1):
            if real_iter.idx >= real_iter.data_num:
                real_iter.reset()
            inputs = real_iter.next()[0]
            inputs = inputs.cuda()
            samples = generator.sample(BATCH_SIZE, g_sequence_len, inputs)
            samples = samples.cpu()
            rewards = rollout.get_reward(samples, 16, discriminator)
            rewards = Variable(torch.Tensor(rewards))
            if opt.cuda:
                rewards = torch.exp(rewards.cuda()).contiguous().view((-1, ))
            prob = generator.forward(inputs)
            mini_batch = prob.shape[0]
            prob = torch.reshape(
                prob,
                (prob.shape[0] * prob.shape[1], -1))  #prob.view(-1, g_emb_dim)
            targets = copy.deepcopy(inputs).contiguous().view((-1, ))
            loss = gen_gan_loss(prob, targets, rewards)
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()
            """
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # construct the input to the genrator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(torch.cat([zeros, samples.data], dim = 1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view((-1,))
            print('', inputs.shape, targets.shape)
            print(inputs, targets)
            # calculate the reward
            rewards = rollout.get_reward(samples, 16, discriminator)
            rewards = Variable(torch.Tensor(rewards))
            if opt.cuda:
                rewards = torch.exp(rewards.cuda()).contiguous().view((-1,))
            prob = generator.forward(inputs)
            mini_batch = prob.shape[0]
            prob = torch.reshape(prob, (prob.shape[0] * prob.shape[1], -1)) #prob.view(-1, g_emb_dim)
            loss = gen_gan_loss(prob, targets, rewards)
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()
            """
        print('Batch [%d] True Loss: %f' % (total_batch, loss))

        if total_batch % 1 == 0 or total_batch == TOTAL_BATCH - 1:
            # generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
            # eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
            # loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
            if len(prob.shape) > 2:
                prob = torch.reshape(prob, (prob.shape[0] * prob.shape[1], -1))
            predictions = torch.max(prob, dim=1)[1]
            predictions = predictions.view(mini_batch, -1)
            for each_sen in list(predictions):
                print('Train Output:',
                      generate_sentence_from_id(idx_to_word, each_sen))

            test_predict(generator, test_iter, idx_to_word, train_mode=True)
            torch.save(generator.state_dict(),
                       CHECKPOINT_PATH + 'generator.model')
            torch.save(discriminator.state_dict(),
                       CHECKPOINT_PATH + 'discriminator.model')
        rollout.update_params()

        for _ in range(4):
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                             NEGATIVE_FILE)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                        BATCH_SIZE)
            for _ in range(2):
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                                   dis_optimizer)
Пример #6
0
        gen_pretrain_eval_loss.append(gen_loss)
        print("eval loss: {:.5f}\n".format(gen_loss))
    print('#####################################################\n\n')

    # Pre-train discriminator
    print('#####################################################')
    print('Start pre-training discriminator...')
    print('#####################################################\n')
    for i in range(args.d_pretrain_steps):
        print("D-Step {}".format(i))
        train_discriminator(discriminator, generator, nll_loss, dis_optimizer,
                            args.dk_epochs, dis_adversarial_train_loss,
                            dis_adversarial_train_acc, args)
        generate_samples(generator, args.batch_size, args.n_samples,
                         NEGATIVE_FILE)
        eval_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, args.batch_size)
        dis_loss, dis_acc = eval_discriminator(discriminator, eval_iter,
                                               nll_loss, args)
        dis_pretrain_eval_loss.append(dis_loss)
        dis_pretrain_eval_acc.append(dis_acc)
        print("eval loss: {:.5f}, eval acc: {:.3f}\n".format(
            dis_loss, dis_acc))
    print('#####################################################\n\n')

    # Adversarial training
    print('#####################################################')
    print('Start adversarial training...')
    print('#####################################################\n')
    rollout = Rollout(generator, args.update_rate)
    for i in range(args.rounds):
        print("Round {}".format(i))
Пример #7
0
def main():
    random.seed(SEED)
    np.random.seed(SEED)

    # Define Networks
    generator = Generator(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    discriminator = Discriminator(d_num_class, VOCAB_SIZE, d_emb_dim,
                                  d_filter_sizes, d_num_filters, d_dropout)
    if opt.cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()
    # Generate toy data using target lstm 也就是新建一个data,假装他就是真实数据
    print('啊啊')

    # Load data from file
    # 每个iter输出一个data和一个target,其中data是每个point前填个0,每个target是后面添个0
    gen_data_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)

    # Pretrain Generator using MLE
    gen_criterion = nn.NLLLoss(
        reduction='sum'
    )  #You may use CrossEntropyLoss instead, if you prefer not to add an extra LogSoftmax layer .
    gen_optimizer = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    print('Pretrain with MLE ...')
    for epoch in range(PRE_EPOCH_NUM):  #PRE_EPOCH_NUM =120
        loss = train_epoch(generator, gen_data_iter, gen_criterion,
                           gen_optimizer)  #使得generator的参数更新,使之适应gen_data_iter
        print('Epoch [%d] Model Loss: %f' % (epoch, loss))  # 9月1日

    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(reduction='sum')
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Discriminator ...')
    for epoch in range(5):
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
        for _ in range(3):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                               dis_optimizer)
            print('Epoch [%d], loss: %f' % (epoch, loss))
    # Adversarial Training
    rollout = Rollout(generator, 0.8)
    print('#####################################################')
    print('Start Adeversatial Training...\n')
    gen_gan_loss = GANLoss()
    gen_gan_optm = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_gan_loss = gen_gan_loss.cuda()
    gen_criterion = nn.NLLLoss(reduction='sum')
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    dis_criterion = nn.NLLLoss(reduction='sum')
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    for total_batch in range(TOTAL_BATCH):
        ## Train the generator for one step
        for it in range(1):
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # construct the input to the genrator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(
                torch.cat([zeros, samples.data], dim=1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view(
                (-1, ))  # 这里我不明白,为什么inputs:(batch_size,seq_len),而targets是一个序列
            # calculate the reward 为什么在rollout里reward不能直接直接由generator来sample
            rewards = rollout.get_reward(
                samples, 16, discriminator)  # rewards:(batch_size,seq_len)
            rewards = Variable(torch.Tensor(rewards))
            rewards = torch.exp(rewards).contiguous().view(
                (-1, ))  # 这是因为Discriminator的最后一层是log_Softmax
            if opt.cuda:
                rewards = rewards.cuda()
            prob = generator.forward(inputs)
            loss = gen_gan_loss(prob, targets, rewards)  #这里是点睛之笔
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()  #这里更新的是rollout里面的ori_model吗?

        rollout.update_params()  #这里理解了的话,基本没问题了

        for _ in range(4):
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                             NEGATIVE_FILE)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                        BATCH_SIZE)
            for _ in range(2):
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                                   dis_optimizer)

        print('Adversarial Training %d complete \n' % (total_batch))

    print('保存模型genetor')
    torch.save(generator.state_dict(), PATH_GPU)
Пример #8
0
            gen_gan_optm.step()
        
        rollout.update_params() 

        g_save_path = os.path.join(m_save_path, c_cat)
        if not os.path.exists(g_save_path):
            os.mkdir(g_save_path)
        g_save_path = os.path.join(g_save_path, 'generator'+str(total_batch)+'.pkl')
        # torch.save(generator.state_dict(), g_save_path)
        print('mul_loss ',loss.item())
                      
        for p in range(4):
            NEGATIVE_FILE1 =  NEGATIVE_FILE + '\\' + str(total_batch) + '\\gene'
            samples_lenth = generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE1,x_info,x_ids,start_id_list,end_id_list,bank_dict)                                        
            NEGATIVE_FILEtxt = NEGATIVE_FILE + '\\' + str(total_batch) + '\\gene.txt'
            dis_data_iter = DisDataIter(real_data_id1, NEGATIVE_FILEtxt, BATCH_SIZE)
            for q in range(2):                        
                total_loss = 0.
                total_words = 0.                        
                n = 0 
                for (data, target) in dis_data_iter:
                    n+=1
                    data = Variable(data)
                    target = Variable(target)
                    if opt.cuda:
                        data, target = data.cuda(), target.cuda()
                    target = target.contiguous().view(-1) 
                    pred = discriminator.forward(data) 
                    loss = dis_criterion(pred, target) # negative log likelihood loss                            
                    total_loss += loss.item()
                    total_words += data.size(0) * data.size(1)       
Пример #9
0
def main(generator_, discriminator, model_index):
    #random.seed(SEED)
    #np.random.seed(SEED)

    perf_dict = {}
    true_loss = []
    generator_loss = []
    disc_loss = []
    nb_batch_per_epoch = int(GENERATED_NUM / BATCH_SIZE)

    # Define Networks
    generator = copy.deepcopy(generator_)

    #target_lstm = TargetLSTM(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    if opt.cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()
        #target_lstm = target_lstm.cuda()
    # Generate toy data using target lstm
    #print('Generating data ...')
    #generate_samples(target_lstm, BATCH_SIZE, GENERATED_NUM, POSITIVE_FILE)

    # Load data from file
    #gen_data_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)

    # Pretrain Generator using MLE
    gen_criterion = nn.NLLLoss(reduction='sum')
    gen_optimizer = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    print('Pretrain with MLE ...')
    for epoch in range(PRE_EPOCH_NUM):
        loss = train_epoch(generator, gen_data_iter, gen_criterion,
                           gen_optimizer)
        print('Epoch [%d] Model Loss: %f' % (epoch, loss))
        generator_loss.append(loss)
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
        eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
        loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
        true_loss.append(loss)
        print('Epoch [%d] True Loss: %f' % (epoch, loss))

    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(reduction='sum')
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Discriminator ...')
    for epoch in range(5):
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
        for _ in range(3):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                               dis_optimizer)
            disc_loss.append(loss)
            print('Epoch [%d], loss: %f' % (epoch, loss))
    # Adversarial Training
    rollout = Rollout(generator, 0.8)
    print('#####################################################')
    print('Start Adeversatial Training...\n')
    gen_gan_loss = GANLoss()
    gen_gan_optm = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_gan_loss = gen_gan_loss.cuda()

    # gen_criterion = nn.NLLLoss(reduction='sum')
    # if opt.cuda:
    #     gen_criterion = gen_criterion.cuda()
    # dis_criterion = nn.NLLLoss(reduction='sum')
    # dis_optimizer = optim.Adam(discriminator.parameters())
    # if opt.cuda:
    #     dis_criterion = dis_criterion.cuda()

    for total_batch in range(TOTAL_BATCH):
        ## Train the generator for one step
        for it in range(1):
            print(it)
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # construct the input to the genrator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(
                torch.cat([zeros, samples.data], dim=1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view((-1, ))
            # calculate the reward
            rewards = rollout.get_reward(samples, 16, discriminator)
            rewards = Variable(torch.Tensor(rewards))
            rewards = torch.exp(rewards).contiguous().view((-1, ))
            if opt.cuda:
                rewards = rewards.cuda()
            prob = generator.forward(inputs)
            loss = gen_gan_loss(prob, targets, rewards)
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()

        if total_batch % 1 == 0 or total_batch == TOTAL_BATCH - 1:
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
            eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
            loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
            true_loss.append(loss)
            print('Batch [%d] True Loss: %f' % (total_batch, loss))
            loss_gen = eval_epoch(generator, gen_data_iter, gen_criterion)
            print('Epoch [%d] Model Loss: %f' % (total_batch, loss_gen))
            generator_loss.append(loss_gen)
        rollout.update_params()

        for _ in range(4):
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                             NEGATIVE_FILE)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                        BATCH_SIZE)
            for _ in range(2):
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                                   dis_optimizer)
                disc_loss.append(loss)

    perf_dict['true_loss'] = true_loss
    perf_dict['generator_loss'] = generator_loss
    perf_dict['disc_loss'] = disc_loss
    np.save('perf_dict' + str(model_index), perf_dict)
Пример #10
0
def main():
    random.seed(SEED)
    np.random.seed(SEED)

    # Define Networks
    generator = Generator(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    discriminator = Discriminator(d_num_class, VOCAB_SIZE, d_emb_dim,
                                  d_filter_sizes, d_num_filters, d_dropout)
    target_lstm = TargetLSTM(VOCAB_SIZE, g_emb_dim, g_hidden_dim,
                             opt.cuda)  #和Generator函数只有sample方法不一样;
    if opt.cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()
        target_lstm = target_lstm.cuda()
    # Generate toy data using target lstm 也就是新建一个data,假装他就是真实数据
    print('Generating data ...')
    generate_samples(target_lstm, BATCH_SIZE, GENERATED_NUM,
                     POSITIVE_FILE)  #没经过啥子训练,直接随机一个lstm产出9984*20的矩阵

    # Load data from file
    # 每个iter输出一个data和一个target,其中data是每个point前填个0,每个target是后面添个0
    gen_data_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)

    # Pretrain Generator using MLE
    gen_criterion = nn.NLLLoss(
        reduction='sum'
    )  #You may use CrossEntropyLoss instead, if you prefer not to add an extra LogSoftmax layer .
    gen_optimizer = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    print('Pretrain with MLE ...')
    for epoch in range(PRE_EPOCH_NUM):  #PRE_EPOCH_NUM =120
        loss = train_epoch(generator, gen_data_iter, gen_criterion,
                           gen_optimizer)  #使得generator的参数更新,使之适应gen_data_iter
        print('Epoch [%d] Model Loss: %f' % (epoch, loss))  # 9月1日
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
        eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
        loss = eval_epoch(target_lstm, eval_iter,
                          gen_criterion)  # generator有向target_lstm靠近吗?
        print('Epoch [%d] True Loss: %f' % (epoch, loss))

    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(reduction='sum')
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Discriminator ...')
    for epoch in range(5):
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
        for _ in range(3):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                               dis_optimizer)
            print('Epoch [%d], loss: %f' % (epoch, loss))
    # Adversarial Training 前面的预训练的目的是什么??????
    rollout = Rollout(generator, 0.8)
    print('#####################################################')
    print('Start Adeversatial Training...\n')
    gen_gan_loss = GANLoss()
    gen_gan_optm = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_gan_loss = gen_gan_loss.cuda()
    gen_criterion = nn.NLLLoss(reduction='sum')
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    dis_criterion = nn.NLLLoss(reduction='sum')
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    for total_batch in range(TOTAL_BATCH):
        ## Train the generator for one step
        for it in range(1):
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # construct the input to the genrator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(
                torch.cat([zeros, samples.data], dim=1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view(
                (-1, ))  # 这里我不明白,为什么inputs:(batch_size,seq_len),而targets是一个序列
            # calculate the reward
            rewards = rollout.get_reward(
                samples, 16, discriminator)  # rewards:(batch_size,seq_len)
            rewards = Variable(torch.Tensor(rewards))
            rewards = torch.exp(rewards).contiguous().view((-1, ))
            if opt.cuda:
                rewards = rewards.cuda()
            prob = generator.forward(inputs)
            loss = gen_gan_loss(prob, targets, rewards)
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()

        if total_batch % 1 == 0 or total_batch == TOTAL_BATCH - 1:  #
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
            eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
            loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
            print('Batch [%d] True Loss: %f' % (total_batch, loss))
        rollout.update_params()  #这里理解了的话,基本没问题了

        for _ in range(4):
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                             NEGATIVE_FILE)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                        BATCH_SIZE)
            for _ in range(2):
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                                   dis_optimizer)
Пример #11
0
def main():
    random.seed(SEED)
    np.random.seed(SEED)
    track_blue = []
    # Build up dataset
    s_train, s_test = load_from_big_file('obama_speech',g_sequence_len)
    # idx_to_word: List of id to word
    # word_to_idx: Dictionary mapping word to id
    idx_to_word, word_to_idx = fetch_vocab(s_train, s_train, s_test)
    # input_seq, target_seq = prepare_data(DATA_GERMAN, DATA_ENGLISH, word_to_idx)

    global VOCAB_SIZE
    VOCAB_SIZE = len(idx_to_word)
    save_vocab(CHECKPOINT_PATH + 'metadata.data', idx_to_word, word_to_idx, VOCAB_SIZE, g_emb_dim, g_hidden_dim)

    print('VOCAB SIZE:', VOCAB_SIZE)
    # Define Networks
    generator = Generator(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    discriminator = Discriminator(d_num_class, VOCAB_SIZE, d_emb_dim, d_filter_sizes, d_num_filters, d_dropout)
    if opt.cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()

    # Generate toy data using target lstm
    print('Generating data ...')

    # Generate samples either from sentences file or lstm
    # Sentences file will be structured input sentences
    # LSTM based is BOG approach
    generate_real_data('obama_speech', BATCH_SIZE, GENERATED_NUM, idx_to_word, word_to_idx,
                       POSITIVE_FILE, TEST_FILE)
    # generate_samples(target_lstm, BATCH_SIZE, GENERATED_NUM, POSITIVE_FILE, idx_to_word)
    # generate_samples(target_lstm, BATCH_SIZE, 10, TEST_FILE, idx_to_word)
    # Create Test data iterator for testing
    test_iter = GenDataIter(TEST_FILE, BATCH_SIZE)
    #test_predict(generator, test_iter, idx_to_word, train_mode=True)

    # Load data from file
    gen_data_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)
    lines = read_file(POSITIVE_FILE)

    refrences = []
    for line in lines:
        phrase = []
        for char in line:
            phrase.append(idx_to_word[char])

        refrences.append(' '.join(phrase))
        #refrences.append(phrase)



    # Pretrain Generator using MLE
    gen_criterion = nn.NLLLoss(size_average=False)
    gen_optimizer = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    print('Pretrain with MLE ...')
    for epoch in range(PRE_EPOCH_NUM):
        loss = train_epoch(generator, gen_data_iter, gen_criterion, gen_optimizer)
        print('Epoch [%d] Model Loss: %f' % (epoch, loss))
        sys.stdout.flush()
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
        if track_training:
            lines = read_file(EVAL_FILE)
            hypotheses = []
            for line in lines:
                phrase = []
                for char in line:
                    phrase.append(idx_to_word[char])

                hypotheses.append(' '.join(phrase))
                #hypotheses.append(phrase)

            bleu_score=get_moses_multi_bleu(hypotheses, refrences, lowercase=True)
            track_blue.append(bleu_score)
            print(track_blue)

        # generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
        # eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
        # loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
        # print('Epoch [%d] True Loss: %f' % (epoch, loss))

    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Discriminator ...')
    for epoch in range(5):
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
        for _ in range(3):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion, dis_optimizer)
            print('Epoch [%d], loss: %f' % (epoch, loss))
            #sys.stdout.flush()

    # Adversarial Training
    rollout = Rollout(generator, 0.8)
    print('#####################################################')
    print('Start Adversarial Training...\n')
    gen_gan_loss = GANLoss()
    gen_gan_optm = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_gan_loss = gen_gan_loss.cuda()
    gen_criterion = nn.NLLLoss(size_average=False)
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    for total_batch in range(TOTAL_BATCH):
        ## Train the generator for one step
        for it in range(1):
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # construct the input to the genrator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(torch.cat([zeros, samples.data], dim=1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view((-1,))
            # calculate the reward
            rewards = rollout.get_reward(samples, 16, discriminator)
            rewards = Variable(torch.Tensor(rewards))
            rewards = torch.exp(rewards).contiguous().view((-1,))
            if opt.cuda:
                rewards = rewards.cuda()
            prob = generator.forward(inputs)
            # print('SHAPE: ', prob.shape, targets.shape, rewards.shape)
            loss = gen_gan_loss(prob, targets, rewards)
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()
            # print('GEN PRED DIM: ', prob.shape)

        if total_batch % 1 == 0 or total_batch == TOTAL_BATCH - 1:
            # generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
            # eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
            # loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
            # print('Batch [%d] True Loss: %f' % (total_batch, loss))

            # predictions = torch.max(prob, dim=1)[1]
            # predictions = predictions.view(BATCH_SIZE, -1)
            # # print('PRED SHAPE:' , predictions.shape)
            # for each_sen in list(predictions):
            #     print('Training Output:', generate_sentence_from_id(idx_to_word, each_sen, DEBUG_FILE))
            #
            # test_predict(generator, test_iter, idx_to_word, train_mode=True)
            loss_gen = eval_epoch(generator, gen_data_iter, gen_criterion)
            print('Epoch [%d] Model Loss: %f' % (total_batch, loss_gen))
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
            #show_some_generated_sequences(idx_to_word, 10, EVAL_FILE)
            sys.stdout.flush()
            if track_training:
                lines = read_file(EVAL_FILE)
                hypotheses = []
                for line in lines:
                    phrase = []
                    for char in line:
                        phrase.append(idx_to_word[char])

                    hypotheses.append(' '.join(phrase))
                    # hypotheses.append(phrase)

                bleu_score = get_moses_multi_bleu(hypotheses, refrences, lowercase=True)
                track_blue.append(bleu_score)
                print(track_blue)

            torch.save(generator.state_dict(), CHECKPOINT_PATH + 'generator_seqgan.model')
            torch.save(discriminator.state_dict(), CHECKPOINT_PATH + 'discriminator_seqgan.model')
        rollout.update_params()

        for _ in range(4):
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
            for _ in range(2):
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion, dis_optimizer)

    track_blue = np.array(track_blue)
    np.save(ROOT_PATH + 'track_blue_seqgan2.npy', track_blue)

    plt.plot(track_blue)
    plt.show()
def PG_BLEU(generator_):
    def read_file(data_file):
        with open(data_file, 'r') as f:
            lines = f.readlines()
        lis = []
        for line in lines:
            l = line.strip().split(' ')
            l = [int(s) for s in l]
            lis.append(l)
        return lis

    lines = read_file(POSITIVE_FILE)
    train_dataset = AmazonReviewGloveDataset('train_small.csv')
    vocab = train_dataset.indexer.index_to_word[1::]
    del train_dataset

    refrences = []
    for line in lines:
        phrase = []
        for char in line:
            phrase.append(vocab[char])

        #refrences.append(' '.join(phrase))
        refrences.append(phrase)

    hypotheses = []
    for line in lines[:3]:
        phrase = []
        for char in line:
            phrase.append(vocab[char])

        #hypotheses.append(' '.join(phrase))
        hypotheses.append(phrase)

    BLEUscore = nltk.translate.bleu_score.sentence_bleu(
        refrences, hypotheses[0])

    nb_batch_per_epoch = int(GENERATED_NUM / BATCH_SIZE)

    # Define Networks
    generator = copy.deepcopy(generator_)
    discriminator = Discriminator(d_num_class, VOCAB_SIZE, d_emb_dim,
                                  d_filter_sizes, d_num_filters, d_dropout)
    #target_lstm = TargetLSTM(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    if opt.cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()
        #target_lstm = target_lstm.cuda()
    # Generate toy data using target lstm
    #print('Generating data ...')
    #generate_samples(target_lstm, BATCH_SIZE, GENERATED_NUM, POSITIVE_FILE)

    # Load data from file
    #gen_data_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)

    # Pretrain Generator using MLE
    gen_criterion = nn.NLLLoss(reduction='sum')
    gen_optimizer = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    print('Pretrain with MLE ...')
    for epoch in range(40):
        loss = train_epoch(generator, gen_data_iter, gen_criterion,
                           gen_optimizer)
        print('Epoch [%d] Model Loss: %f' % (epoch, loss))
        generator_loss.append(loss)
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
        eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
        loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
        true_loss.append(loss)
        print('Epoch [%d] True Loss: %f' % (epoch, loss))

    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(reduction='sum')
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Discriminator ...')
    for epoch in range(1):
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
        for _ in range(1):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                               dis_optimizer)
            disc_loss.append(loss)
            print('Epoch [%d], loss: %f' % (epoch, loss))
    # Adversarial Training
    rollout = bleu_Rollout(generator, 0.8, refrences, vocab)
    print('#####################################################')
    print('Start Adeversatial Training...\n')
    gen_gan_loss = GANLoss()
    gen_gan_optm = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_gan_loss = gen_gan_loss.cuda()

    for total_batch in range(TOTAL_BATCH):
        ## Train the generator for one step
        #nb_batch_per_epoch
        for it in range(1):
            #print(it)
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # construct the input to the genrator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(
                torch.cat([zeros, samples.data], dim=1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view((-1, ))
            # calculate the reward
            rewards = rollout.get_reward(samples, 2)
            rewards = Variable(torch.Tensor(rewards))
            rewards = torch.exp(rewards).contiguous().view((-1, ))
            if opt.cuda:
                rewards = rewards.cuda()
            prob = generator.forward(inputs)
            loss = gen_gan_loss(prob, targets, rewards)
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()

        if total_batch % 1 == 0 or total_batch == TOTAL_BATCH - 1:
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
            eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
            loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
            true_loss.append(loss)
            print('Batch [%d] True Loss: %f' % (total_batch, loss))
            loss_gen = eval_epoch(generator, gen_data_iter, gen_criterion)
            print('Epoch [%d] Model Loss: %f' % (total_batch, loss_gen))
            generator_loss.append(loss_gen)
        rollout.update_params()

        for _ in range(4):
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM,
                             NEGATIVE_FILE)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE,
                                        BATCH_SIZE)
            for _ in range(2):
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion,
                                   dis_optimizer)
                disc_loss.append(loss)

    perf_dict_pgbleu['true_loss'] = true_loss
    perf_dict_pgbleu['generator_loss'] = generator_loss
    perf_dict_pgbleu['disc_loss'] = disc_loss
    np.save('perf_dict', perf_dict)
Пример #13
0
def main():
    random.seed(SEED)
    np.random.seed(SEED)
    
    # Build up dataset
    s_train, s_test = load_from_big_file('../data/train_data_obama.txt')
    # idx_to_word: List of id to word
    # word_to_idx: Dictionary mapping word to id
    idx_to_word, word_to_idx = fetch_vocab(s_train, s_train, s_test)
    # TODO: 1. Prepare data for attention model
    # input_seq, target_seq = prepare_data(DATA_GERMAN, DATA_ENGLISH, word_to_idx)

    global VOCAB_SIZE
    VOCAB_SIZE = len(idx_to_word)

    print('VOCAB SIZE:' , VOCAB_SIZE)
    # Define Networks
    generator = Generator(VOCAB_SIZE, g_emb_dim, g_hidden_dim, g_sequence_len, BATCH_SIZE, opt.cuda)
    discriminator = Discriminator(d_num_class, VOCAB_SIZE, d_emb_dim, d_filter_sizes, d_num_filters, d_dropout)
    target_lstm = TargetLSTM(VOCAB_SIZE, g_emb_dim, g_hidden_dim, opt.cuda)
    if opt.cuda:
        generator = generator.cuda()
        discriminator = discriminator.cuda()
        target_lstm = target_lstm.cuda()
    # Generate toy data using target lstm
    print('Generating data ...')
    generate_samples(target_lstm, BATCH_SIZE, GENERATED_NUM, POSITIVE_FILE, idx_to_word)
    
    # Load data from file
    gen_data_iter = GenDataIter(POSITIVE_FILE, BATCH_SIZE)

    # Pretrain Generator using MLE
    gen_criterion = nn.NLLLoss(size_average=False)
    gen_optimizer = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    print('Pretrain with MLE ...')
    for epoch in range(PRE_EPOCH_NUM):
        loss = train_epoch(generator, gen_data_iter, gen_criterion, gen_optimizer)
        print('Epoch [%d] Model Loss: %f'% (epoch, loss))
        # TODO: 2. Flags to ensure dimension of model input is handled
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
        print('Gen sampled')
        eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
        print('Iterator Done')
        loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
        print('Epoch [%d] True Loss: %f' % (epoch, loss))

    # Pretrain Discriminator
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    print('Pretrain Dsicriminator ...')
    for epoch in range(3):
        generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
        dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
        for _ in range(3):
            loss = train_epoch(discriminator, dis_data_iter, dis_criterion, dis_optimizer)
            print('Epoch [%d], loss: %f' % (epoch, loss))
    # Adversarial Training 
    rollout = Rollout(generator, 0.8)
    print('#####################################################')
    print('Start Adeversatial Training...\n')
    gen_gan_loss = GANLoss()
    gen_gan_optm = optim.Adam(generator.parameters())
    if opt.cuda:
        gen_gan_loss = gen_gan_loss.cuda()
    gen_criterion = nn.NLLLoss(size_average=False)
    if opt.cuda:
        gen_criterion = gen_criterion.cuda()
    dis_criterion = nn.NLLLoss(size_average=False)
    dis_optimizer = optim.Adam(discriminator.parameters())
    if opt.cuda:
        dis_criterion = dis_criterion.cuda()
    for total_batch in range(TOTAL_BATCH):
        ## Train the generator for one step
        for it in range(1):
            samples = generator.sample(BATCH_SIZE, g_sequence_len)
            # construct the input to the genrator, add zeros before samples and delete the last column
            zeros = torch.zeros((BATCH_SIZE, 1)).type(torch.LongTensor)
            if samples.is_cuda:
                zeros = zeros.cuda()
            inputs = Variable(torch.cat([zeros, samples.data], dim = 1)[:, :-1].contiguous())
            targets = Variable(samples.data).contiguous().view((-1,))
            # calculate the reward
            rewards = rollout.get_reward(samples, 16, discriminator)
            rewards = Variable(torch.Tensor(rewards))
            if opt.cuda:
                rewards = torch.exp(rewards.cuda()).contiguous().view((-1,))
            prob = generator.forward(inputs)
            prob = torch.reshape(prob, (prob.shape[0] * prob.shape[1], -1)) #prob.view(-1, g_emb_dim)
            loss = gen_gan_loss(prob, targets, rewards)
            gen_gan_optm.zero_grad()
            loss.backward()
            gen_gan_optm.step()

        print('Batch [%d] True Loss: %f' % (total_batch, loss))

        if total_batch % 10 == 0 or total_batch == TOTAL_BATCH - 1:
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM, EVAL_FILE)
            eval_iter = GenDataIter(EVAL_FILE, BATCH_SIZE)
            loss = eval_epoch(target_lstm, eval_iter, gen_criterion)
            
            predictions = torch.max(prob, dim=1)[1]
            predictions = predictions.view(BATCH_SIZE, -1)
            # print('PRED SHAPE:' , predictions.shape)
            for each_sen in list(predictions):
                print('Sample Output:', generate_sentence_from_id(idx_to_word, each_sen, DEBUG_FILE))
            sys.stdout.flush()

            torch.save(generator.state_dict(), './experiment_3_10000/generator.model')
            torch.save(discriminator.state_dict(), './experiment_3_10000/discriminator.model')
        rollout.update_params()
        
        for _ in range(4):
            generate_samples(generator, BATCH_SIZE, GENERATED_NUM, NEGATIVE_FILE)
            dis_data_iter = DisDataIter(POSITIVE_FILE, NEGATIVE_FILE, BATCH_SIZE)
            for _ in range(2):
                loss = train_epoch(discriminator, dis_data_iter, dis_criterion, dis_optimizer)