Beispiel #1
0
def cal_batch_bleu(samples_sents, ref_sents):
    assert (len(samples_sents) == len(ref_sents))
    bleu_np = np.zeros([len(samples_sents)], dtype=np.float32)
    for i in range(len(samples_sents)):
        cand = map(lambda w: str(w), samples_sents[i])
        ref = map(lambda w: str(w), ref_sents[i])
        bleu_np[i] = bleu(cand, [ref], [0.4, 0.4, 0.2])
    return bleu_np
def test(args, encoder, decoder, encoder_optimizer, decoder_optimizer,
         loss_function, device, i, test_data, trg, encoder_embedding_dict,
         decoder_embedding_dict):
    if args.attention:
        run_batch_func = run_batch_with_attention
    else:
        run_batch_func = run_batch

    test_iter = data.BucketIterator(
        dataset=test_data,
        batch_size=args.batch_size,
        train=False,
        shuffle=False,
        #A key to use for sorting examples in order to batch together
        # examples with similar lengths and minimize padding.
        sort=True,
        sort_key=lambda x: len(x.src),
        repeat=False,
        sort_within_batch=True,
        device=device)

    # turn off dropout
    encoder.eval()
    decoder.eval()

    test_loss_list = []
    test_bleu_list = []
    test_reference_list, translation_output_list = [], []
    test_source_list = []
    attention_lists = []
    translation_outputs = []  #
    test_references = []  #
    for i, test_batch in enumerate(iter(test_iter)):
        #val_batch.trg: size N x B
        loss, translation_output, attention_list = run_batch_func(
            "test",
            args,
            encoder,
            decoder,
            encoder_optimizer,
            decoder_optimizer,
            loss_function,
            test_batch,
            device,
            encoder_embedding_dict,  #####
            decoder_embedding_dict  #####
        )
        #translation_output = indices, N x B
        #todo: 1. check if trg.vocab.itos is pass in this function. 2.!reference!
        test_reference = []
        test_source = []
        for each in test_batch.idx:
            test_reference.append(" ".join(test_iter.dataset[each].trg))
            test_source.append(" ".join(test_iter.dataset[each].src))
        translation_outputs.append(translation_output.detach())  #
        test_references.extend(test_reference)  #
        test_bleu = bleu(trg.vocab.itos, translation_output, test_reference)
        test_reference_list.append(test_reference)
        translation_output_list.append(
            detok(translation_output, np.array(trg.vocab.itos)))
        test_source_list.append(test_source)
        test_bleu_list.append(test_bleu)
        test_loss_list.append(loss)
        attention_lists.append(attention_list)
        if i % args.print_every == 0:
            print(
                "test, step: {}, average loss for current epoch: {}, batch loss: {}, batch bleu: {}"
                .format(  #
                    i, np.mean(test_loss_list), loss, test_bleu))  #

    bleu_for_current_epoch = bleu_epoch(trg.vocab.itos, translation_outputs,
                                        test_references)  #
    print(
        "test done. average loss for current epoch: {}, bleu for current epoch: {}"
        .format(  #
            np.mean(test_loss_list), bleu_for_current_epoch))  #

    return np.mean(
        test_loss_list
    ), bleu_for_current_epoch, test_source_list, test_reference_list, translation_output_list, attention_lists  #
def train_and_val(args, encoder, decoder, encoder_optimizer, decoder_optimizer,
                  loss_function, device, epoch_idx, train_data, val_data, trg,
                  encoder_embedding_dict, decoder_embedding_dict):

    assert args.attention, "if using cnn encoder, attention must be true"
    run_batch_func = run_batch_with_attention

    train_iter = data.BucketIterator(dataset=train_data,
                                     batch_size=args.batch_size,
                                     repeat=False,
                                     sort_key=lambda x: len(x.src),
                                     sort_within_batch=True,
                                     device=device,
                                     train=True)

    val_iter = data.BucketIterator(
        dataset=val_data,
        batch_size=args.batch_size,
        train=False,
        shuffle=False,
        #A key to use for sorting examples in order to batch together
        # examples with similar lengths and minimize padding.
        sort=True,
        sort_key=lambda x: len(x.src),
        repeat=False,
        sort_within_batch=True,
        device=device)

    # turn on dropout
    encoder.train()
    decoder.train()

    train_loss_list = []
    for i, train_batch in enumerate(iter(train_iter)):
        loss, _, _ = run_batch_func(
            "train",
            args,
            encoder,
            decoder,
            encoder_optimizer,
            decoder_optimizer,
            loss_function,
            train_batch,
            device,
            encoder_embedding_dict,  #####
            decoder_embedding_dict  #####
        )
        train_loss_list.append(loss)
        # TODO: use tensorboard to see train / val plot while training
        if i % args.print_every == 0:
            print(
                "train, epoch: {}, step: {}, average loss for current epoch: {}, batch loss: {}"
                .format(epoch_idx, i, np.mean(train_loss_list), loss))

    print(
        "train done. epoch: {}, average loss for current epoch: {}, numbatch: {}, size of last batch: {}"
        .format(epoch_idx, np.mean(train_loss_list), i + 1,
                train_batch.src[0].shape[1]))

    # turn off dropout
    encoder.eval()
    decoder.eval()

    val_loss_list = []
    val_bleu_list = []
    translation_outputs = []  #
    val_references = []  #
    for i, val_batch in enumerate(iter(val_iter)):
        #val_batch.trg: size N x B
        loss, translation_output, _ = run_batch_func(
            "val",
            args,
            encoder,
            decoder,
            encoder_optimizer,
            decoder_optimizer,
            loss_function,
            val_batch,
            device,
            encoder_embedding_dict,  #####
            decoder_embedding_dict  #####
        )
        #translation_output = indices, N x B
        #todo: 1. check if trg.vocab.itos is pass in this function. 2.!reference!
        val_reference = []
        for each in val_batch.idx:
            val_reference.append(" ".join(val_iter.dataset[each].trg))
        translation_outputs.append(translation_output.detach())  #
        val_references.extend(val_reference)  #
        val_bleu = bleu(trg.vocab.itos, translation_output, val_reference)
        val_bleu_list.append(val_bleu)
        val_loss_list.append(loss)
        if i % args.print_every == 0:
            print(
                "val, epoch: {}, step: {}, average loss for current epoch: {}, batch loss: {}, batch bleu: {}"
                .format(  #
                    epoch_idx, i, np.mean(val_loss_list), loss, val_bleu))  #

    bleu_for_current_epoch = bleu_epoch(trg.vocab.itos, translation_outputs,
                                        val_references)  #
    print(
        "val done. epoch: {}, average loss for current epoch: {}, bleu for current epoch: {}"
        .format(  #
            epoch_idx, np.mean(val_loss_list), bleu_for_current_epoch))  #

    return np.mean(train_loss_list), np.mean(
        val_loss_list), bleu_for_current_epoch  #