为啥 Keras Dropout 中的非零值会发生变化?

Posted

技术标签:

【中文标题】为啥 Keras Dropout 中的非零值会发生变化?【英文标题】:Why does non-zero values change in Keras Dropout?为什么 Keras Dropout 中的非零值会发生变化? 【发布时间】:2020-01-16 00:39:07 【问题描述】:

假设我有一个张量:

x = tf.reshape(tf.constant(tf.range(1, 21, dtype=tf.float32)), (5,4))

<tf.Tensor: id=1080557, shape=(5, 4), dtype=float32, numpy=
array([[ 1.,  2.,  3.,  4.],
       [ 5.,  6.,  7.,  8.],
       [ 9., 10., 11., 12.],
       [13., 14., 15., 16.],
       [17., 18., 19., 20.]], dtype=float32)>

我对它应用了 dropout:

dropout = tf.keras.layers.Dropout(0.1)
dropout(x, training=True)

<tf.Tensor: id=1080704, shape=(5, 4), dtype=float32, numpy=
array([[ 1.1111112,  2.2222223,  3.3333335,  0.       ],
       [ 5.555556 ,  6.666667 ,  7.777778 ,  8.888889 ],
       [10.       , 11.111112 , 12.222223 ,  0.       ],
       [14.444445 , 15.555556 , 16.666668 , 17.777779 ],
       [18.88889  ,  0.       , 21.111113 , 22.222223 ]], dtype=float32)>

每次运行它时,我都有 1 到 3 个归零值,这不完全是 rate=0.1。它实际适用的费率范围是多少?为什么非归零值会发生变化?

可视化 Celius Stingher 的答案:

l = 10000; r = range(l)
f = np.zeros((5,4))
for i in r:
  d = dropout(x, training=True)
  f += d
f = f/l
f

<tf.Tensor: id=1234967, shape=(5, 4), dtype=float32, numpy=
array([[ 1.0006623,  1.999991 ,  2.988533 ,  4.017763 ],
       [ 5.000613 ,  6.0477467,  7.0076656,  8.0248575],
       [ 9.048    , 10.06455  , 10.980609 , 12.010143 ],
       [12.918334 , 14.100925 , 15.039784 , 16.014153 ],
       [17.0579   , 18.112    , 19.064175 , 20.024672 ]], dtype=float32)>

【问题讨论】:

【参考方案1】:

因为 dropout 的工作方式是将每个神经元设置为 0,概率等于您传递的值。您可以将其视为二项分布[*],其中 p = 0.1n = 20 预期值等于 2标准差等于 ~1.34,这就解释了原因大多数情况下,您会看到 1 到 3 个神经元(值)被强制为 0。这就是为什么您可以在 dropout 函数中设置随机种子以确保可重复性

[*] 在本文1 中,您可以找到更多细节,他们假设 r(j) 遵循伯努利分布(因此,多个伯努利分布的重复遵循二项式分布)。

OP 问:谢谢。我明白了,但是其他值呢?为什么非归零值发生了变化?

编辑:鉴于函数的工作原理、您的模型以及您的一组值,从长远来看,应用 dropout 后的预期值必须等于应用它们之前的值。因此,如果您运行此代码进行 1000 次迭代,我预计每次运行的平均值趋于 10.5(或总共 210)。实现这一点的唯一方法是以与 dropout 相同的速率增加每个值。如果您得到worse 案例,您将删除最后三个数字,但在best 案例中,您将删除前三个数字,两个平均值的平均值为10.5,即初始平均值。解释来自我链接的论文。 (第 1933 页)

【讨论】:

谢谢。我明白了,但是其他值呢?为什么非归零值会发生变化? 我在您的答案中没有看到任何关于非零值的信息。 基于 keras 文档,用于 noise_shape=None 的 dropout 默认值。应该还有别的原因。 我不认为我可以添加更多内容,我们可以尝试将其转移到聊天中(我不会在几个小时内回来)。 是的,你是对的。我添加了您对该主题的回答的可视化。

以上是关于为啥 Keras Dropout 中的非零值会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章

用先前的非零值替换向量中的所有零

编译器是不是应该正确地将 bool 中的任意非零值解释为 true?

Keras:LSTM dropout 和 LSTM 循环 dropout 的区别

为熊猫中的每一列获取非零值

如何计算沿某一维度的 3d 体积的非零元素的平均值

java - 为啥在java中的poll方法之后PriorityQueue中的值会发生变化? [复制]