def test_sample_multiple_words(): list_ = ('foo', 'bar', 'foobar') words = generator.sample(list_, 2) assert len(words) == 2 assert words[0] in list_ assert words[1] in list_ assert words[0] is not words[1]
def save_policy_examples(folder, policy): evaluation = generator.sample(policy, math.ceil(100 / config.batch_size)) os.makedirs(folder + '/pngs') os.makedirs(folder + '/sequences') save_pngs(evaluation, folder + '/pngs') save_sequences(evaluation, folder + '/sequences')
def train_discriminator(discriminator, dis_opt, real_data_samples, generator, real_val, d_steps, epochs): """ Training the discriminator on real_data_samples (positive) and generated samples from generator (negative). Samples are drawn d_steps times, and the discriminator is trained for epochs epochs. """ pos_val = helpers.positive_sample(real_val, 100) neg_val = generator.sample(100, MAX_SEQ_LEN) val_inp, val_target = helpers.prepare_discriminator_data(pos_val, neg_val, gpu=CUDA) for d_step in range(d_steps): s = helpers.batchwise_sample(generator, POS_NEG_SAMPLES, BATCH_SIZE, MAX_SEQ_LEN) dis_inp, dis_target = helpers.prepare_discriminator_data( real_data_samples, s, gpu=CUDA) for epoch in range(epochs): print('d-step %d epoch %d : ' % (d_step + 1, epoch + 1), end='') sys.stdout.flush() total_loss = 0 total_acc = 0 for i in range(0, 2 * POS_NEG_SAMPLES, BATCH_SIZE): inp, target = dis_inp[i:i + BATCH_SIZE], dis_target[i:i + BATCH_SIZE] dis_opt.zero_grad() out = discriminator.batchClassify(inp) loss_fn = nn.BCELoss() loss = loss_fn(out, target) loss.backward() dis_opt.step() total_loss += loss.data.item() total_acc += torch.sum( (out > 0.5) == (target > 0.5)).data.item() if (i / BATCH_SIZE) % ceil( ceil(2 * POS_NEG_SAMPLES / float(BATCH_SIZE)) / 10.) == 0: # roughly every 10% of an epoch print('.', end='') sys.stdout.flush() total_loss /= ceil(2 * POS_NEG_SAMPLES / float(BATCH_SIZE)) total_acc /= float(2 * POS_NEG_SAMPLES) val_pred = discriminator.batchClassify(val_inp) print(' average_loss = %.4f, train_acc = %.4f, val_acc = %.4f' % (total_loss, total_acc, torch.sum( (val_pred > 0.5) == (val_target > 0.5)).data.item() / 200.))
def eval(val_iter, discriminator, generator): # validation discriminator.eval() print('validation :', end=' ') total_acc = 0 num_samples = 0 total_loss = 0 for i, data in enumerate(val_iter): tgt_data = data.target[0].permute(1, 0) # batch_size X length src_data_wrap = data.source ans = data.answer[0] if CUDA: scr_data = data.source[0].to(device) scr_lengths = data.source[1].to(device) ans = ans.to(device) src_data_wrap = (scr_data, scr_lengths, ans) real_samples = tgt_data real_lengths = data.target[1] passage = src_data_wrap[0].permute(1, 0) with torch.no_grad(): fake_samples, fake_lengths = generator.sample(src_data_wrap) # prepare prepare_discriminator_data input fake_samples = fake_samples.cpu() fake_lengths = fake_lengths.cpu() ans = ans.permute(1, 0).cpu() # shuffle data dis_inp, dis_target, dis_len, dis_pa, dis_an = helpers.prepare_discriminator_data( real_samples, real_lengths, fake_samples, fake_lengths, passage, ans, tgt_special) inp, target = dis_inp, dis_target lengths, pa = dis_len, dis_pa an = dis_an if CUDA: inp = inp.to(device) target = target.to(device).type(torch.float) lengths = lengths.to(device) pa = pa.to(device) an = an.to(device) pa = (pa, an) # inp = (inp, lengths) out = discriminator.batchClassify(inp, pa) loss_fn = nn.BCELoss() # todo: should .cuda?? loss = loss_fn(out, target) total_loss += loss.item() num_samples += tgt_data.size(0) * 2 total_acc += torch.sum((out > 0.5) == (target > 0.5)).item() total_acc = total_acc * 1.0 / float(num_samples) print('loss = %.4f' % (total_loss / (num_samples)), end=' ') print('val_acc = %.4f\n' % (total_acc)) discriminator.train() return total_acc
def make_dataset(directory, policy, label, num_batches) -> Dataset: """ This function creates a Dataset of type dataset.Dataset with samples generated by the given generating net. The data gets stored in the given directory. Note that the dataset only saves image paths and not the images itsself. If the data gets removed the dataset becomes invalid. :param directory: The path to the directory in which the generated samples will be stored for the dataset. :param policy: The net generating the data samples for the dataset. :param label: The label for the generated data, should be equal to label_synth in configs. Can be None. :param num_batches: The amount of batches generated with the generator net. :return: Returns a dataset of type dataset.Dataset. """ clear_directory(directory) sequences = generator.sample(policy, num_batches) save_pngs(sequences, directory) dataset = Dataset(directory, label) return dataset
def train_discriminator(discriminator,dis_opt,real_data_samples,generator,oracle,d_steps,epochs): #通过鉴别器对真实数据和生成器生成的数据进行训练 #样本通过d步得到,鉴别器通过epochs次的训练 #生成一小部分验证集 pos_val = oracle.sample(100) neg_val = generator.sample(100) val_inp,val_target = helpers.prepare_discriminator_data(pos_val,neg_val,gpu=CUDA) for d_step in range(d_steps): s = helpers.batchwise_sample(generator,POS_NEG_SAMPLES,BATCH_SIZE) dis_inp,dis_target = helpers.prepare_discriminator_data(real_data_samples,s,gpu=CUDA) for epoch in range(epochs): print('d_step %d epoch %d:' %(d_step+1,epoch+1),end='') sys.stdout.flush() total_loss = 0 total_acc = 0 for i in range(0,2*POS_NEG_SAMPLES,BATCH_SIZE): inp,target = dis_inp[i:i+BATCH_SIZE],dis_target[i:i+BATCH_SIZE] dis_opt.zero_grad() out = discriminator.batchClassify(inp) loss_fn = nn.BCELoss() loss = loss_fn(out,target) loss.backward() dis_opt.step() total_loss += loss.data.item() total_acc += torch.sum((out>0.5)==(target>0.5)).data.item() if(i/BATCH_SIZE) % ceil(ceil(2*POS_NEG_SAMPLES/float(BATCH_SIZE))/10) == 0: print('.',end='') sys.stdout.flush() total_acc /= ceil(2*POS_NEG_SAMPLES/float(BATCH_SIZE)) total_acc /= float(2*POS_NEG_SAMPLES) val_pred = discriminator.batchClassify(val_inp) print(' average_loss = %.4f, train_acc = %.4f, val_acc = %.4f' % ( total_loss, total_acc, torch.sum((val_pred > 0.5) == (val_target > 0.5)).data.item() / 200.))
def train_discriminator(discriminator, dis_opt, real_data_samples, generator, oracle, d_steps, epochs, args): """ Training the discriminator on real_data_samples (positive) and generated samples from generator (negative). Samples are drawn d_steps times, and the discriminator is trained for epochs epochs. """ # generating a small validation set before training (using oracle and generator) pos_val = oracle.sample(100) neg_val = generator.sample(100) val_inp, val_target = helpers.prepare_discriminator_data(pos_val, neg_val, gpu=args.cuda) val_buffer = torch.zeros(200 * args.max_seq_len, args.vocab_size) if args.cuda: val_buffer = val_buffer.cuda() val_inp_oh = helpers.get_oh(val_inp, val_buffer) inp_buf = torch.zeros(args.d_bsz * args.max_seq_len, args.vocab_size) if args.cuda: inp_buf = inp_buf.cuda() num_data = len(real_data_samples) for d_step in range(d_steps): s = helpers.batchwise_sample(generator, args.num_data) dis_inp, dis_target = helpers.prepare_discriminator_data( real_data_samples, s, gpu=args.cuda) for epoch in range(epochs): print('d-step %d epoch %d : ' % (d_step + 1, epoch + 1), end='') sys.stdout.flush() total_loss = 0 total_acc = 0 for i in range(0, 2 * num_data, args.d_bsz): if i + args.d_bsz > 2 * num_data: break inp, target = dis_inp[i:i + args.d_bsz], dis_target[i:i + args.d_bsz] inp_oh = helpers.get_oh(inp, inp_buf) dis_opt.zero_grad() out = discriminator.batchClassify(Variable(inp_oh)) loss_fn = nn.BCELoss() loss = loss_fn(out, Variable(target)) loss.backward() dis_opt.step() total_loss += loss.data[0] total_acc += torch.sum( (out > 0.5) == (Variable(target) > 0.5)).data[0] if (i / args.d_bsz) % ceil( ceil(2 * num_data / float(args.d_bsz)) / 10.) == 0: # roughly every 10% of an epoch print('.', end='') sys.stdout.flush() total_loss /= ceil(2 * num_data / float(args.d_bsz)) total_acc /= float(2 * num_data) val_pred = discriminator.batchClassify(Variable(val_inp_oh)) print(' average_loss = %.4f, train_acc = %.4f, val_acc = %.4f' % (total_loss, total_acc, torch.sum((val_pred > 0.5) == (Variable(val_target) > 0.5)).data[0] / 200.))
import torch from models import VanillaRNN, LSTMSimple from utils import get_device, char_mapping from generator import sample char_to_idx, idx_to_char = char_mapping() config = { "VOCAB_SIZE": len(char_to_idx.keys()), "HIDDEN": 200, # For songs sampling "TEMPERATURE": 1, "TAKE_MAX_PROBABLE": False, "LIMIT_LEN": 300 } MODEL_INPUT = "$" # MODEL_INPUT = "$" model = LSTMSimple(config["VOCAB_SIZE"], config["HIDDEN"], config["VOCAB_SIZE"]).to(get_device()) model.init_state() model.load_state_dict(torch.load("trained_models/model2019-11-26-03-06.pth", map_location='cpu')) text = sample(model, MODEL_INPUT, config) print(text)
def test_sample_single_word(): list_ = ('foo', 'bar', 'foobar') word = generator.sample(list_) assert word in list_
def train_discriminator(discriminator, dis_opt, train_iter, generator, out_acc, epochs, ADV_batches = None): """ Training the discriminator on real_data_samples (positive) and generated samples from generator (negative). Samples are drawn d_steps times, and the discriminator is trained for epochs epochs. """ def eval(val_iter, discriminator, generator): # validation discriminator.eval() print('validation :', end=' ') total_acc = 0 num_samples = 0 total_loss = 0 for i, data in enumerate(val_iter): tgt_data = data.target[0].permute(1, 0) # batch_size X length src_data_wrap = data.source ans = data.answer[0] if CUDA: scr_data = data.source[0].to(device) scr_lengths = data.source[1].to(device) ans = ans.to(device) src_data_wrap = (scr_data, scr_lengths, ans) real_samples = tgt_data real_lengths = data.target[1] passage = src_data_wrap[0].permute(1, 0) with torch.no_grad(): fake_samples, fake_lengths = generator.sample(src_data_wrap) # prepare prepare_discriminator_data input fake_samples = fake_samples.cpu() fake_lengths = fake_lengths.cpu() ans = ans.permute(1, 0).cpu() # shuffle data dis_inp, dis_target, dis_len, dis_pa, dis_an = helpers.prepare_discriminator_data(real_samples, real_lengths, fake_samples, fake_lengths, passage, ans, tgt_special) inp, target = dis_inp, dis_target lengths, pa = dis_len, dis_pa an = dis_an if CUDA: inp = inp.to(device) target = target.to(device) lengths = lengths.to(device) pa = pa.to(device) an = an.to(device) pa = (pa, an) # inp = (inp, lengths) out = discriminator.batchClassify(inp, pa) loss_fn = nn.BCELoss() # todo: should .cuda?? loss = loss_fn(out, target) total_loss += loss.item() num_samples += tgt_data.size(0) * 2 total_acc += torch.sum((out > 0.5) == (target > 0.5)).item() total_acc = total_acc * 1.0 / float(num_samples) print('loss = %.4f' % (total_loss / (num_samples)), end=' ') print('val_acc = %.4f\n' % (total_acc)) discriminator.train() return total_acc d_step = 0 while(1): d_step += 1 passages = [] anses = [] real_samples = [] fake_samples = [] real_lengths = [] fake_lengths = [] for i, data in enumerate(train_iter): if ADV_batches is not None: if i+1 == ADV_batches: break tgt_data = data.target[0].permute(1, 0) # batch_size X length src_data_wrap = data.source ans = data.answer[0] if CUDA: scr_data = data.source[0].to(device) scr_lengths = data.source[1].to(device) ans = ans.to(device) src_data_wrap = (scr_data, scr_lengths, ans) real_sample = tgt_data real_length = data.target[1] with torch.no_grad(): fake_sample, fake_length = generator.sample(src_data_wrap) fake_sample = fake_sample.cpu() fake_length = fake_length.cpu() ans = ans.permute(1, 0).cpu() # keep lengths as the same in order to pack passage = src_data_wrap[0].permute(1, 0) pad_len = max_sent_len - passage.size(1) m = nn.ConstantPad1d((0, pad_len), src_pad) passage = m(passage) ans = m(ans) # keep lengths as the same in order to pack pad_len = max_sent_len - real_sample.size(1) m = nn.ConstantPad1d((0, pad_len), tgt_pad) real_sample = m(real_sample) real_samples.append(real_sample) real_lengths.append(real_length) fake_samples.append(fake_sample) fake_lengths.append(fake_length) passages.append(passage) anses.append(ans) real_samples = torch.cat(real_samples, 0).type(torch.LongTensor) real_lengths = torch.cat(real_lengths, 0).type(torch.LongTensor) fake_samples = torch.cat(fake_samples, 0).type(torch.LongTensor) fake_lengths = torch.cat(fake_lengths, 0).type(torch.LongTensor) passages = torch.cat(passages, 0).type(torch.LongTensor) anses = torch.cat(anses, 0).type(torch.LongTensor) dis_inp, dis_target, dis_len, dis_pa, dis_an = helpers.prepare_discriminator_data(real_samples, real_lengths, fake_samples, fake_lengths, passages, anses, tgt_special) # iterator # for i, dis_data in enumerate(dis_iter): # dis_inp = dis_data.question[0] # dis_target = dis_data.target # dis_pa = dis_data.passage[0] # dis_an = dis_data.answer[0] # collect discriminator data # disc_writer = open("disc.json", "w") # question0 = rev.reverse(dis_inp.permute(1,0)) # answer0 = ans_rev.reverse(dis_an.permute(1, 0)) # passage0 = src_rev.reverse(dis_pa.permute(1, 0)) # for i in range(len(dis_inp)): # disc_writer.write("{\"question\": \"" + question0[i][6:] + "\", ") # disc_writer.write("\"answer\": \"" + answer0[i] + "\", ") # disc_writer.write("\"passage\": \"" + passage0[i] + "\", ") # disc_writer.write("\"target\": \"" + str(int(dis_target[i].item())) + "\"}" + "\n") # # showcases # print(' sample showcase:') # show = rev.reverse(dis_inp[:Show_num].permute(1, 0)) # for i in range(Show_num): # print(show[i]) for epoch in range(epochs): discriminator.train() print('\n d-step %d epoch %d : ' % (d_step, epoch + 1), end='') total_loss = 0 total_acc = 0 true_acc = 0 num_samples = dis_inp.size(0) for i in range(0, num_samples, batch_size): inp, target = dis_inp[i: i + batch_size], dis_target[i: i + batch_size] # lengths = dis_len[i: i + batch_size] pa = dis_pa[i: i + batch_size] an = dis_an[i: i + batch_size] if CUDA: inp = inp.to(device) target = target.to(device) # lengths = lengths.to(device) an = an.to(device) pa = pa.to(device) pa = (pa, an) # inp = (inp, lengths) dis_opt.zero_grad() out = discriminator.batchClassify(inp, pa) # hidden = none over here loss_fn = nn.BCELoss() loss = loss_fn(out, target) loss.backward() dis_opt.step() total_loss += loss.item() total_acc += torch.sum((out>0.5)==(target>0.5)).item() true = (target > 0.5).type(torch.FloatTensor) out = out.cpu() out_true = out * true true_acc += torch.sum(out_true > 0.5).item() total_acc = total_acc * 1.0 / float(num_samples) true_acc = true_acc * 1.0 / float(num_samples/2) print('loss = %.4f, train_acc = %.4f' % (total_loss/(num_samples), total_acc), end=' ') print('true_acc = %.4f' % true_acc) val_acc = eval(val_iter, discriminator, generator) # dis_opt.updateLearningRate(val_acc) # todo: when to stop the discriminator MLE training(below is my randomly settings) flag = 0 if ADV_batches is None: if val_acc > out_acc: flag = 1 break elif d_step+1 == 8 and epoch+1 == 5: flag = 1 break else: if d_step+1 == 4 and epoch+1 == 5: flag = 1 break if flag == 1: break
def fit(model, train_encoded, val_encoded, config): """ Fit the models weights and save the training and validation loss in the model :param model: nn. Module :param train_encoded: Encoded training data :param val_encoded: Encoded validation data :param config: dict with settings :return: """ n_songs_train = len(train_encoded) n_songs_val = len(val_encoded) criterion = nn.CrossEntropyLoss() optimizer = Adam(model.parameters(), lr=config["LR"], weight_decay=config["WEIGHT_DECAY"]) for epoch in range(1, config["EPOCHS"] + 1): train_loss = 0 # Enter train mode to activate Dropout and Batch Normalization layers model.train() # Shuffle songs for each epoch random.shuffle(train_encoded) for i, song in enumerate(train_encoded): # Reset state for each song model.init_state() song_loss = 0 n = 0 # Number of chunks made from song for seq, target in SlidingWindowLoader(song, window=config["CHUNK_SIZE"]): # Chunks is sometimes empty if len(seq) == 0: continue n += 1 # One-hot encode chunk tensor input_onehot = to_onehot(seq, config["VOCAB_SIZE"]) optimizer.zero_grad() # Reset gradient for every forward output = model(input_onehot.unsqueeze(1)) # Size = (chunk_length, batch, vocab_size) output.squeeze_(1) # Back to 2D chunk_loss = criterion(output, target.long()) chunk_loss.backward() optimizer.step() song_loss += chunk_loss.item() train_loss += song_loss / n if i % 100 == 0: print("Song: {}, AvgTrainLoss: {}".format(i, train_loss / (i + 1))) # Append average training loss for this epoch model.training_losses.append(train_loss / n_songs_train) # Generate a song at this epoch song = sample(model, "$", config) print("{}\n{}\n{}".format("-" * 40, song, "-" * 40)) # Validation with torch.no_grad(): print("Validating") model.eval() # Turns of Dropout and BatchNormalization val_loss = 0 for song in val_encoded: # Reset state model.init_state() song_loss = 0 n = 0 for seq, target in SlidingWindowLoader(song, window=config["CHUNK_SIZE"]): # Chunks is sometimes empty if len(seq) == 0: continue n += 1 # One-hot encode chunk tensor input_onehot = to_onehot(seq, config["VOCAB_SIZE"]) output = model(input_onehot.unsqueeze(1)) # Size = (chunk_length, batch, vocab_size) output.squeeze_(1) # Back to 2D song_loss += criterion(output, target.long()).item() val_loss += song_loss / n model.validation_losses.append(val_loss / n_songs_val) print("Epoch {}, Training loss: {}, Validation Loss: {}".format(epoch, model.training_losses[-1], model.validation_losses[-1]))