测试时的Dropout会以某种方式导致LSTM性能失败



我在使用TensorFlow时遇到了一个问题,当我使用输入dropout时,我的LSTM的性能急剧下降(从70%到<10%)。

正如我所理解的,我应该在训练期间将input_keep_probability设置为(例如)0.5,然后在测试期间设置为1。这是完全有道理的,但我不能让它工作的预期。如果我在测试期间将dropout设置为与训练期间相同,我的性能就会提高(在下面的示例中不是这样,但这需要更少的代码,并且要点是相同的)。

3次运行的精度和成本

"最佳"线为无退学,最差线为[keep_prob@train: 0.5, keep_prob@test: 1],中线为[keep_prob@train: 0.5, keep_prob@test: 0.5]。这些是测试集上的成本和准确性。它们在火车集合上的行为都与预期一致。

下面是我认为很重要的代码。遗憾的是,由于其敏感性,我不能发布完整的代码或数据样本,但如果您需要更多信息,请评论。

lstm_size = 512
numLayers = 4
numSteps = 15
lstm_cell = tf.nn.rnn_cell.LSTMCell(lstm_size, state_is_tuple=True, forget_bias=1)
lstm_cell = tf.nn.rnn_cell.DropoutWrapper(lstm_cell, input_keep_prob=input_keep_prob)
cell = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * numLayers, state_is_tuple=True)
_inputs = [tf.squeeze(s, [1]) for s in tf.split(1, numSteps, input_data)]
(outputs, state) = rnn.rnn(cell, _inputs, dtype=tf.float32)
outputs = tf.pack(outputs)
#transpose so I can put all timesteps through the softmax at once
outputsTranspose = tf.reshape(outputs, [-1, lstm_size])
softmax_w = tf.get_variable("softmax_w", [lstm_size, nof_classes])                         
softmax_b = tf.get_variable("softmax_b", [nof_classes]) 
logits = tf.matmul(outputsTranspose, softmax_w) + softmax_b
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, targets)
cost = tf.reduce_mean(loss)
targetPrediction = tf.argmax(logits, 1)
accuracy = tf.reduce_mean(tf.cast(tf.equal(targetPrediction, targets), "float"))
"""Optimizer"""
with tf.name_scope("Optimizer") as scope:
    tvars = tf.trainable_variables()
    #We clip the gradients to prevent explosion
    grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars),maxGradNorm)
    optimizer = tf.train.AdamOptimizer(learning_rate)
    gradients = zip(grads, tvars)
    train_op = optimizer.apply_gradients(gradients)

with tf.Session() as sess:
    sess.run(init_op);
    for i in range(nofBatches * nofEpochs):
        example_batch, label_batch = sess.run(readTrainDataOp)
        result = sess.run([train_op, accuracy, trainSummaries], feed_dict = {input_data: example_batch, targets: label_batch, input_keep_prob:trainInputKeepProbability, batch_size_ph:batch_size})
        #logging
        if i % 50 == 0:
            runTestSet()
            #relevant part of runTestSet(): 
            #result = sess.run([cost, accuracy], feed_dict = {input_data: testData, targets: testLabels, input_keep_prob:testInputKeepProbability, batch_size_ph:testBatchSize})
            #logging

我做错了什么导致了这种意想不到的行为?

编辑:这是一个输入样本的图像见下一个链接。

这个问题在只有一层的情况下仍然存在。

编辑:我做了一个重现问题的例子。只需运行带有testrongamples路径的python脚本。Npy作为第一个参数,到检查点的路径作为第二个参数

尝试input_keep_prob = output_keep_prob = 0.7进行训练1.0保留问题用于测试

0.5 keep问题在我的LSTM上也不能很好地工作

最新更新