Example #1
0
def reward_progressive_match_label(sample, batch, sample_score=None):
    seq_len = util.find_first_min_zero(sample)
    mask, __ = util.masked_full_like(sample,
                                     1,
                                     num_non_padding=seq_len + 1,
                                     dtype=np.int32)
    mask = mask * (seq_len > 0)
    sample, _sample = sample * mask, sample
    label = _label = batch.labels.label
    pad_width = abs(len(sample) - len(label))
    pad_width = ((0, pad_width), (0, 0))
    if len(label) < len(sample):
        label = np.pad(label, pad_width, 'constant', constant_values=0)
    elif len(sample) < len(label):
        sample = np.pad(sample, pad_width, 'constant', constant_values=0)
    diff = np.abs(sample - label)
    match = (diff == 0).astype(np.float32)  # / batch.features.dec_seq_len
    if len(_label) < len(_sample):
        match[len(_label) - 1:, :] = 0
    elif len(_sample) < len(_label):
        match = match[:len(_sample), :]
    avgmatch = np.sum(match * mask) / np.sum(mask)
    summatch = np.sum(match, axis=0)
    mismatch = np.argmin(match, axis=0)
    mismatch_mask, __ = util.masked_full_like(match,
                                              1,
                                              num_non_padding=mismatch)
    match = match * mismatch_mask
    for ib in range(sample.shape[1]):
        if summatch[ib] > 0 and mismatch[ib] == 0:
            continue
        match[mismatch[ib], ib] = -0.1
    return match, avgmatch
Example #2
0
def reward_match_label(sample, batch, partial_match=True, sample_score=None):
    seq_len = util.find_first_min_zero(sample)
    mask, __ = util.masked_full_like(sample,
                                     1,
                                     num_non_padding=seq_len + 1,
                                     dtype=np.int32)
    mask = mask * (seq_len > 0)
    sample, _sample = sample * mask, sample
    label = _label = batch.labels.label
    pad_width = abs(len(sample) - len(label))
    pad_width = ((0, pad_width), (0, 0))
    if len(label) < len(sample):
        label = np.pad(label, pad_width, 'constant', constant_values=0)
    elif len(sample) < len(label):
        sample = np.pad(sample, pad_width, 'constant', constant_values=0)
    diff = np.abs(sample - label)
    if partial_match:
        match = (diff == 0).astype(np.float32) / (seq_len + 1)
        if len(_label) < len(_sample):
            match[len(_label) - 1:, :] = 0
        elif len(_sample) < len(_label):
            match = match[:len(_sample), :]
    else:
        sumdiff = np.sum(diff, axis=0)
        match = np.zeros_like(sample, dtype=np.float32)
        for ib in range(seq_len.shape[0]):
            if sumdiff[ib] == 0:
                match[seq_len[ib], ib] = 1
    match = match * mask
    avgmatch = np.sum(match) / np.sum(seq_len > 0)
    return match, avgmatch
Example #3
0
def get_batch_data(batch,
                   y_arr,
                   unmasked_token_weight=None,
                   unmasked_seq_weight=None,
                   start_id=1,
                   seq_len_idx=1,
                   input_key='inputs',
                   seq_len_key='seq_len'):
    y_len = np.argmin(y_arr, axis=0) + 1
    y_len[batch.features[seq_len_idx] <= 0] = 0
    seq_weight = np.where(y_len > 0, 1, 0).astype(np.float32)
    if unmasked_seq_weight is not None:
        seq_weight *= unmasked_seq_weight
    token_weight, num_tokens = util.masked_full_like(y_arr, 1, y_len)
    if unmasked_token_weight is not None:
        token_weight *= unmasked_token_weight
    start = np.full((1, len(y_len)), start_id, dtype=np.int32) * seq_weight
    x_arr = np.vstack((start.astype(np.int32), y_arr))[:-1, :]
    features = batch.features._replace(**{
        input_key: x_arr,
        seq_len_key: y_len
    })
    labels = ds.SeqLabelTuple(y_arr, token_weight, seq_weight)
    batch = ds.BatchTuple(features, labels, num_tokens, batch.keep_state)
    return batch
Example #4
0
def create_seq_data_graph(in_data, out_data, prefix='decoder'):
    x_arr, x_len = util.hstack_list(in_data, padding=0, dtype=np.int32)
    y_arr, y_len = util.hstack_list(out_data, padding=0, dtype=np.int32)
    seq_weight = np.where(y_len > 0, 1, 0).astype(np.float32)
    token_weight, num_tokens = util.masked_full_like(y_arr,
                                                     1,
                                                     num_non_padding=y_len)
    all_x = tf.constant(x_arr.T, name='data_input')
    all_y = tf.constant(y_arr.T, name='data_label')
    all_len = tf.constant(x_len, name='data_len')
    all_seq_weight = tf.constant(seq_weight, name='data_seq_weight')
    all_token_weight = tf.constant(token_weight.T, name='data_token_weight')
    batch_idx_ = tf.placeholder(tf.int32,
                                shape=[None],
                                name=f'{prefix}_batch_idx')
    input_ = tf.transpose(tf.gather(all_x, batch_idx_, name=f'{prefix}_input'))
    label_ = tf.transpose(tf.gather(all_y, batch_idx_, name=f'{prefix}_label'))
    seq_len_ = tf.gather(all_len, batch_idx_, name=f'{prefix}_seq_len')
    seq_weight_ = tf.gather(all_seq_weight,
                            batch_idx_,
                            name=f'{prefix}_seq_weight')
    token_weight_ = tf.transpose(
        tf.gather(all_token_weight, batch_idx_, name=f'{prefix}_token_weight'))
    return {
        f'{prefix}_{k}': v
        for k, v in util.dict_with_key_endswith(locals(), '_').items()
    }
Example #5
0
def lseq2seq_batch_iter(enc_data,
                        dec_data,
                        label_data,
                        mask_data,
                        batch_size=1,
                        shuffle=True):
    """same as seq2seq_batch_iter, just add label"""
    data_tuple = (enc_data, dec_data, label_data, mask_data)
    for x, y, L, M in batch_iter(batch_size,
                                 shuffle,
                                 *data_tuple,
                                 pad=[[], [], 0, 2]):
        enc, enc_len = util.hstack_list(x)
        dec, dec_len = util.hstack_list(y)
        label = np.array(L, dtype=np.int32)
        mask = np.array(M, dtype=np.int32)
        in_dec = dec[:-1, :]
        out_dec = dec[1:, :]
        seq_weight = np.where(dec_len > 0, 1, 0)
        dec_len -= seq_weight
        token_weight, num_tokens = util.masked_full_like(
            out_dec, 1, num_non_padding=dec_len)
        seq_weight = seq_weight.astype(np.float32)
        features = ds.LSeq2SeqFeatureTuple(enc, enc_len, in_dec, dec_len,
                                           label, mask)
        labels = ds.SeqLabelTuple(out_dec, token_weight, seq_weight)
        yield ds.BatchTuple(features, labels, num_tokens, False)
Example #6
0
def reward_constant(sample, batch, constant=-0.1, sample_score=None):
    # return batch.labels.label_weight, np.mean(batch.labels.label_weight)
    seq_len = util.find_first_min_zero(sample)
    mask, __ = util.masked_full_like(sample,
                                     1,
                                     num_non_padding=seq_len + 1,
                                     dtype=np.int32)
    mask = mask * (seq_len > 0) * constant
    return mask * constant, np.mean(seq_len + 1) * constant
Example #7
0
def seq_batch_iter(in_data,
                   out_data,
                   weights,
                   batch_size=1,
                   shuffle=True,
                   keep_sentence=True):
    """wrapper of batch_iter to format seq data"""
    keep_state = not keep_sentence
    # add one more argumennt and pass it to "batch_iter" below
    # also add 0 for the padding
    if weights:
        # import pdb; pdb.set_trace()
        for x, y, w in batch_iter(batch_size,
                                  shuffle,
                                  in_data,
                                  out_data,
                                  weights,
                                  pad=[[], [], 0]):
            x_arr, x_len = util.hstack_list(x)
            y_arr, y_len = util.hstack_list(y)
            # w_arr, w_len = util.hstack_list(w)
            # change seq_weight to be the input weight
            seq_weight = np.where(y_len > 0, w, 0).astype(np.float32)
            # import pdb; pdb.set_trace()
            token_weight, num_tokens = util.masked_full_like(
                y_arr, w, num_non_padding=y_len)
            features = ds.SeqFeatureTuple(x_arr, x_len)
            labels = ds.SeqLabelTuple(y_arr, token_weight, seq_weight)
            yield ds.BatchTuple(features, labels, num_tokens, keep_state)
    else:
        for x, y in batch_iter(batch_size,
                               shuffle,
                               in_data,
                               out_data,
                               pad=[[], []]):
            x_arr, x_len = util.hstack_list(x)
            y_arr, y_len = util.hstack_list(y)
            seq_weight = np.where(y_len > 0, 1, 0).astype(np.float32)
            token_weight, num_tokens = util.masked_full_like(
                y_arr, 1, num_non_padding=y_len)
            features = ds.SeqFeatureTuple(x_arr, x_len)
            labels = ds.SeqLabelTuple(y_arr, token_weight, seq_weight)
            yield ds.BatchTuple(features, labels, num_tokens, keep_state)
Example #8
0
 def test_masked_full_like(self):
     data = np.random.randn(4, 3)
     num_non_padding = np.array([4, 1, 0])
     outputs, total = util.masked_full_like(data, 1, num_non_padding=num_non_padding,
                                            padding=0, dtype=np.float32)
     self.assertEqual(total, np.sum(num_non_padding), 'num padding is correct')
     self.assertTrue(np.all(np.sum(outputs, axis=0) == num_non_padding),
                     'num padding is correct')
     self.assertEqual(data.shape, outputs.shape, 'output has the same shape')
     self.assertTrue(np.all(outputs[:, -1] == 0), 'padding value is correct')
Example #9
0
def _format_word2def(x, w, c, y, sw):
    enc, enc_len = util.hstack_list(x)
    dec, dec_len = util.hstack_list(y)
    word = np.array(w, dtype=np.int32)
    char, char_len = util.vstack_list(c)
    in_dec = dec[:-1, :]
    out_dec = dec[1:, :]
    seq_weight = np.array(sw, dtype=np.float32)
    dec_len -= np.where(dec_len > 0, 1, 0)
    token_weight, num_tokens = util.masked_full_like(out_dec,
                                                     1,
                                                     num_non_padding=dec_len)
    seq_weight = seq_weight.astype(np.float32)
    features = ds.Word2DefFeatureTuple(enc, enc_len, word, char, char_len,
                                       in_dec, dec_len)
    labels = ds.SeqLabelTuple(out_dec, token_weight, seq_weight)
    return ds.BatchTuple(features, labels, num_tokens, False)
Example #10
0
def seq2seq_batch_iter(enc_data, dec_data, batch_size=1, shuffle=True):
    """wrapper of batch_iter to format seq2seq data"""
    for x, y in batch_iter(batch_size,
                           shuffle,
                           enc_data,
                           dec_data,
                           pad=[[], []]):
        enc, enc_len = util.hstack_list(x)
        dec, dec_len = util.hstack_list(y)
        in_dec = dec[:-1, :]
        out_dec = dec[1:, :]
        seq_weight = np.where(dec_len > 0, 1, 0)
        dec_len -= seq_weight
        token_weight, num_tokens = util.masked_full_like(
            out_dec, 1, num_non_padding=dec_len)
        seq_weight = seq_weight.astype(np.float32)
        features = ds.Seq2SeqFeatureTuple(enc, enc_len, in_dec, dec_len)
        labels = ds.SeqLabelTuple(out_dec, token_weight, seq_weight)
        yield ds.BatchTuple(features, labels, num_tokens, False)
Example #11
0
def reward_ngram_lm(sample,
                    batch,
                    lm,
                    vocab,
                    token_score=True,
                    sample_score=None):
    # XXX: This is incredibly inefficient. We need a better way to get sequence
    # likelihood from LM using a list of word ids.

    if sample_score is None:

        def score(s):
            return np.power(10, s)
    else:

        def score(s):
            score = (s / np.log10(np.e)) - sample_score[it, ib]
            return score

    seq_len = np.argmin(sample, axis=0)
    mask, __ = util.masked_full_like(sample,
                                     1,
                                     num_non_padding=seq_len + 1,
                                     dtype=np.int32)
    sample, _sample = sample * mask, sample
    scores = np.zeros_like(sample, dtype=np.float32)
    words = vocab.i2w(sample)
    for ib in range(sample.shape[1]):
        state1, state2 = kenlm.State(), kenlm.State()
        lm.BeginSentenceWrite(state1)
        # sentence = []
        for it in range(sample.shape[0]):
            s = lm.BaseScore(state1, words[it][ib], state2)
            scores[it, ib] = score(s)
            state1, state2 = state2, state1
            if words[it][ib] == '</s>':
                # scores[it, ib] = 1 / (1 + lm.perplexity(' '.join(sentence)))
                break
            # sentence.append(words[it][ib])
    # scores = scores * mask
    # scores = (1 / (1 - scores)) * mask
    return scores, np.sum(scores) / np.sum(mask)
Example #12
0
def seq_batch_iter(in_data,
                   out_data,
                   batch_size=1,
                   shuffle=True,
                   keep_sentence=True):
    """wrapper of batch_iter to format seq data"""
    keep_state = not keep_sentence
    for x, y in batch_iter(batch_size,
                           shuffle,
                           in_data,
                           out_data,
                           pad=[[], []]):
        x_arr, x_len = util.hstack_list(x)
        y_arr, y_len = util.hstack_list(y)
        seq_weight = np.where(y_len > 0, 1, 0).astype(np.float32)
        token_weight, num_tokens = util.masked_full_like(y_arr,
                                                         1,
                                                         num_non_padding=y_len)
        features = ds.SeqFeatureTuple(x_arr, x_len)
        labels = ds.SeqLabelTuple(y_arr, token_weight, seq_weight)
        yield ds.BatchTuple(features, labels, num_tokens, keep_state)