如何在TensorFlow中正确实现卷积dropout

5
根据Dropout的原始论文所述,正则化方法可以应用于卷积层,并经常提高其性能。TensorFlow函数tf.nn.dropout通过具有noise_shape参数来支持这一点,以允许用户选择将张量的哪些部分独立地丢弃。然而,论文和文档都没有清楚地解释应该保留哪些维度的独立性,而且TensorFlow关于noise_shape如何工作的解释也不够清晰。

只有在noise_shape[i] == shape(x)[i]的维度才会做出独立决策。

我认为对于典型的CNN层输出,形状为[batch_size, height, width, channels],我们不希望单独的行或列自己掉落,而是希望整个通道(相当于完全连接的NN中的一个节点)独立于例子(即不同的通道可能会在批处理中的不同示例中取消掉)。我的想法正确吗?
如果是这样,那么如何使用noise_shape参数实现具有这种特定性的dropout?它应该是以下内容吗:
noise_shape=[batch_size, 1, 1, channels]

或者:

noise_shape=[1, height, width, 1]

我并不完全确定删除整个通道是否是标准做法。我在不同的地方读到了不同的东西,而且我觉得许多人会独立地删除单个元素(标量),即将“noise_shape”保留为默认值。 - Toke Faurby
你正在做的是空间dropout(SO帖子论文)。在我看来,即使对于卷积层,标准的dropout也是独立地应用于每个元素。 - Toke Faurby
1个回答

2

来自这里

例如,如果 shape(x) = [k, l, m, n] 并且 noise_shape = [k, 1, 1, n],则每个批次和通道组件将被独立保留,并且每行和每列将同时保留或不保留。

代码可能有助于解释。

noise_shape = noise_shape if noise_shape is not None else array_ops.shape(x)
# uniform [keep_prob, 1.0 + keep_prob)
random_tensor = keep_prob
random_tensor += random_ops.random_uniform(noise_shape,
                                           seed=seed,
                                           dtype=x.dtype)
# 0. if [keep_prob, 1.0) and 1. if [1.0, 1.0 + keep_prob)
binary_tensor = math_ops.floor(random_tensor)
ret = math_ops.div(x, keep_prob) * binary_tensor
ret.set_shape(x.get_shape())
return ret

该行random_tensor +=支持broadcast。当noise_shape[i]设置为1时,意味着这个维度中的所有元素将添加相同的随机值,范围从0到1。因此,当noise_shape=[k, 1, 1, n]时,特征图中的每一行和每一列将被一起保留或不保留。另一方面,每个示例(批次)或每个通道会接收到不同的随机值,并且它们中的每一个都将独立地被保留。


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