这是使用TensorFlow 1.3和一些更高级的tf.contrib API使用ScheduledEmbeddingTrainingHelper的基本示例。这是一个sequence2sequence模型,其中解码器的初始隐藏状态是编码器的最终隐藏状态。仅展示如何在单个批次上进行训练(明显的任务是“反转此序列”)。对于实际的训练任务,我建议查看tf.contrib.learn APIs,例如learn_runner、Experiment和tf.estimator.Estimator。
import tensorflow as tf
import numpy as np
from tensorflow.python.layers.core import Dense
vocab_size = 7
embedding_size = 5
lstm_units = 10
src_batch = np.array([[1, 2, 3], [4, 5, 6]])
trg_batch = np.array([[3, 2, 1], [6, 5, 4]])
source_seq = tf.placeholder(shape=(None, None), dtype=tf.int32)
target_seq = tf.placeholder(shape=(None, None), dtype=tf.int32)
source_seq_len = tf.placeholder(shape=(None,), dtype=tf.int32)
target_seq_len = tf.placeholder(shape=(None,), dtype=tf.int32)
batch_size, sequence_size = tf.unstack(tf.shape(target_seq))
sos_slice = tf.zeros([batch_size, 1], dtype=tf.int32)
decoder_input = tf.concat([sos_slice, target_seq], axis=1)
embedding_matrix = tf.get_variable(
name="embedding_matrix",
shape=[vocab_size, embedding_size],
dtype=tf.float32)
source_seq_embedded = tf.nn.embedding_lookup(embedding_matrix, source_seq)
decoder_input_embedded = tf.nn.embedding_lookup(embedding_matrix, decoder_input)
unused_encoder_outputs, encoder_state = tf.nn.dynamic_rnn(
tf.contrib.rnn.LSTMCell(lstm_units),
source_seq_embedded,
sequence_length=source_seq_len,
dtype=tf.float32)
sampling_prob = tf.Variable(0.0, dtype=tf.float32)
helper = tf.contrib.seq2seq.ScheduledEmbeddingTrainingHelper(
decoder_input_embedded,
target_seq_len,
embedding_matrix,
sampling_probability=sampling_prob)
output_layer = Dense(vocab_size)
decoder = tf.contrib.seq2seq.BasicDecoder(
tf.contrib.rnn.LSTMCell(lstm_units),
helper,
encoder_state,
output_layer=output_layer)
outputs, state, seq_len = tf.contrib.seq2seq.dynamic_decode(decoder)
loss = tf.contrib.seq2seq.sequence_loss(
logits=outputs.rnn_output,
targets=target_seq,
weights=tf.ones(trg_batch.shape))
train_op = tf.contrib.layers.optimize_loss(
loss=loss,
global_step=tf.contrib.framework.get_global_step(),
optimizer=tf.train.AdamOptimizer,
learning_rate=0.001)
with tf.Session() as session:
session.run(tf.global_variables_initializer())
_, _loss = session.run([train_op, loss], {
source_seq: src_batch,
target_seq: trg_batch,
source_seq_len: [3, 3],
target_seq_len: [3, 3],
sampling_prob: 0.5
})
print("Loss: " + str(_loss))
对于ScheduledOutputTrainingHelper,我希望只需更换助手并使用:
helper = tf.contrib.seq2seq.ScheduledOutputTrainingHelper(
target_seq,
target_seq_len,
sampling_probability=sampling_prob)
然而,这样会出现错误,因为LSTM单元期望每个时间步长的多维输入(形状为(batch_size, input_dims))。我将在GitHub上提出问题,以查明这是否是一个错误,或者是否有其他方法使用ScheduledOutputTrainingHelper。
ScheduledOutputTrainingHelper
和ScheduledEmbeddingTrainingHelper
之间的区别在于前者直接将 RNN 的输出作为下一个时间步骤的输入(当不使用当前时间步骤的目标作为下一个输入时),而后者(同样,当不使用当前时间步骤的目标作为下一个输入时)将 RNN 的输出视为一个逻辑值,对其应用 softmax 函数,从结果分布中采样一个令牌,然后使用它来索引嵌入矩阵中下一个时间步骤的输入。 - user1953384