如何在TensorFlow中关闭测试时的dropout?

34

我对Tensorflow和机器学习都比较新,所以我在此为一个(很可能)琐碎的问题道歉。

我使用dropout技术来提高网络的学习速度,它似乎运作得很好。接下来,我想测试该网络是否按照如下方式工作:

   def Ask(self, image):
        return self.session.run(self.model, feed_dict = {self.inputPh: image})

很明显,由于仍然存在dropout,每次都会产生不同的结果。我能想到的一个解决方案是创建两个单独的模型——一个用于训练,另一个用于实际使用网络的后续,但是,这样的解决方案对我来说似乎不切实际。

解决这个问题的常见方法是什么?


解决这个问题的常见方法是什么?
6个回答

57

最简单的方法是使用placeholder_with_default函数来更改keep_prob参数:

prob = tf.placeholder_with_default(1.0, shape=())
layer = tf.nn.dropout(layer, prob)

使用此方法进行训练时,您可以设置参数如下:

sess.run(train_step, feed_dict={prob: 0.5})

当你评估时,将使用默认值1.0。


我尝试了这种方法,但是当将'prob'分配给tf.layers.dropout(<layer>,rate=prob,training=True)时,它会给我返回NaN错误。我使用了您建议的带有默认值的占位符。问题链接:https://stackoverflow.com/questions/54069395/input-contains-nan-infinity-or-a-value-too-large-for-dtypefloat64-in-tensor - Suleka_28
2
因为 tf.nn.dropout 中有 drop_probability 而没有 keep_probability - nessuno

12
使用新的tf.estimator API,您可以指定一个模型函数,该函数根据您是在训练还是测试时返回不同的模型,但仍允许您重用模型代码。在您的模型函数中,您需要执行类似以下操作:
def model_fn(features, labels, mode):

    training = (mode == tf.estimator.ModeKeys.TRAIN)
    ...
    t = tf.layers.dropout(t, rate=0.25, training=training, name='dropout_1')
    ...
mode参数会根据您调用的是estimator.train(...)还是estimator.predict(...)自动传递。

1
如果我们想使用估算器的冻结图而不是saved_model,该怎么办?我们如何指定我们处于哪种模式? - leonard

10

在tensorflow的dropout层中,你应该设置keep_prob,该变量是保留权重的概率,建议将该变量设置在0.5到0.8之间。在测试网络时,只需将keep_prob设置为1。

你应该定义类似以下的内容:

keep_prob = tf.placeholder(tf.float32, name='keep_prob')
drop = tf.contrib.rnn.DropoutWrapper(layer1, output_keep_prob=keep_prob)

然后更改会话中的值:

_ = sess.run(cost, feed_dict={'input':training_set, 'output':training_labels, 'keep_prob':0.8}) # During training
_ = sess.run(cost, feed_dict={'input':testing_set, 'output':testing_labels, 'keep_prob':1.}) # During testing

4

如果您不想使用Estimator API,可以通过以下方式创建dropout:

tf_is_traing_pl = tf.placeholder_with_default(True, shape=())
tf_drop_out = tf.layers.dropout(last_output, rate=0.8, training=tf.is_training_pl)

因此,在进行评估时,您应该使用{'tf_is_training': False}来为会话提供数据,而不是更改丢失率。

1

随着Tensorflow的更新,应该使用tf.layer.dropout类而不是tf.nn.dropout。

这支持is_training参数。使用它可以让您的模型一次定义keep_prob,并且不依赖于feed_dict来管理外部参数。这可以实现更好的重构代码。

更多信息:https://www.tensorflow.org/api_docs/python/tf/layers/dropout


0

当你进行测试时,你应该将层的输出乘以1/drop_prob。

在这种情况下,你需要在测试阶段增加一个额外的乘法步骤。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接