Ejemplo n.º 1
0
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]
Ejemplo n.º 2
0
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')
Ejemplo n.º 3
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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.))
Ejemplo n.º 7
0
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)
Ejemplo n.º 9
0
def test_sample_single_word():
    list_ = ('foo', 'bar', 'foobar')
    word = generator.sample(list_)
    assert word in list_
Ejemplo n.º 10
0
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]))