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)
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)
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
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()
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)
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))
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)
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)
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)
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)
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)
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)