我已经使用BasicLSTMCell
和rnn.bidirectional_rnn
在TensorFlow中实现了双向RNN。连接接收到的输出后,我正在使用seq2seq.sequence_loss_by_example
计算损耗。我的应用程序是下一个字符预测器。
我得到一个非常低的cost
,(比单向RNN小50倍)。我怀疑我在seq2seq.sequence_loss_by_example
步骤中犯了一个错误。
这是我的模特-
# Model begins
cell_fn = rnn_cell.BasicLSTMCell
cell = fw_cell = cell_fn(args.rnn_size, state_is_tuple=True)
cell2 = bw_cell = cell_fn(args.rnn_size, state_is_tuple=True)
input_data = tf.placeholder(tf.int32, [args.batch_size, args.seq_length])
targets = tf.placeholder(tf.int32, [args.batch_size, args.seq_length])
initial_state = fw_cell.zero_state(args.batch_size, tf.float32)
initial_state2 = bw_cell.zero_state(args.batch_size, tf.float32)
with tf.variable_scope('rnnlm'):
softmax_w = tf.get_variable("softmax_w", [2*args.rnn_size, args.vocab_size])
softmax_b = tf.get_variable("softmax_b", [args.vocab_size])
with tf.device("/cpu:0"):
embedding = tf.get_variable("embedding", [args.vocab_size, args.rnn_size])
input_embeddings = tf.nn.embedding_lookup(embedding, input_data)
inputs = tf.unpack(input_embeddings, axis=1)
outputs, last_state, last_state2 = rnn.bidirectional_rnn(fw_cell,
bw_cell,
inputs,
initial_state_fw=initial_state,
initial_state_bw=initial_state2,
dtype=tf.float32)
output = tf.reshape(tf.concat(1, outputs), [-1, 2*args.rnn_size])
logits = tf.matmul(output, softmax_w) + softmax_b
probs = tf.nn.softmax(logits)
loss = seq2seq.sequence_loss_by_example([logits],
[tf.reshape(targets, [-1])],
[tf.ones([args.batch_size * args.seq_length])],
args.vocab_size)
cost = tf.reduce_sum(loss) / args.batch_size / args.seq_length
lr = tf.Variable(0.0, trainable=False)
tvars = tf.trainable_variables()
grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars),
args.grad_clip)
optimizer = tf.train.AdamOptimizer(lr)
train_op = optimizer.apply_gradients(zip(grads, tvars))
最佳答案
我认为您的代码没有任何错误。
问题是应用程序中的Bi-RNN模型的目标函数(下一个字符预测器)。
单向RNN(例如ptb_word_lm或char-rnn-tensorflow),实际上是用于预测的模型,例如,如果raw_text
为1,3,5,2,4,8,9,0
,则您的inputs
和target
将为:
inputs: 1,3,5,2,4,8,9
target: 3,5,2,4,8,9,0
并且预测为
(1)->3
,(1,3)->5
,...,(1,3,5,2,4,8,9)->0
但是在Bi-RNN中,第一个预测实际上并不只是
(1)->3
,因为代码中的output[0]
通过使用raw_text
包含了bw_cell
的反向信息(也不是(1,3)->5
,..., (1,3,5,2,4,8,9)->0
)。一个类似的例子是:我告诉你那朵花是玫瑰,然后我让你预测那朵花是什么?我认为您可以很容易地给我正确的答案,这也是为什么您在应用程序的Bi-RNN模型中得到极低的loss
的原因。实际上,我认为Bi-RNN(或Bi-LSTM)对于下一个字符预测器的应用不是合适的模型。 Bi-RNN在工作时需要完整的序列,当您要预测下一个字符时,您会发现无法轻松使用此模型。
关于python - 在双向RNN中获得极低的损耗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40817208/