我已经使用BasicLSTMCellrnn.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_lmchar-rnn-tensorflow),实际上是用于预测的模型,例如,如果raw_text1,3,5,2,4,8,9,0,则您的inputstarget将为:

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/

10-12 21:33