dropout 在 mini-batch 梯度下降中的混淆用法

Confused usage of dropout in mini-batch gradient descent

我的问题到最后了

一个 example CNN 使用 mini-batch GD 训练并在最后一个全连接层(第 60 行)使用 dropout 作为

fc1 = tf.layers.dropout(fc1, rate=dropout, training=is_training)

起初我认为 tf.layers.dropouttf.nn.dropout 随机将列中的神经元设置为零。但是我最近发现不是这样的。下面的代码打印了 dropout 的作用。我使用 fc0 作为 4 样本 x 10 特征矩阵,fc 作为退出版本。

import tensorflow as tf
import numpy as np

fc0 = tf.random_normal([4, 10])
fc = tf.nn.dropout(fc0, 0.5)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

a, b = sess.run([fc0, fc])
np.savetxt("oo.txt", np.vstack((a, b)), fmt="%.2f", delimiter=",")

并且在输出中oo.txt(原始矩阵:第1-4行,丢弃矩阵:第5-8行):

0.10,1.69,0.36,-0.53,0.89,0.71,-0.84,0.24,-0.72,-0.44
0.88,0.32,0.58,-0.18,1.57,0.04,0.58,-0.56,-0.66,0.59
-1.65,-1.68,-0.26,-0.09,-1.35,-0.21,1.78,-1.69,-0.47,1.26
-1.52,0.52,-0.99,0.35,0.90,1.17,-0.92,-0.68,-0.27,0.68
0.20,0.00,0.71,-0.00,0.00,0.00,-0.00,0.47,-0.00,-0.87
0.00,0.00,0.00,-0.00,3.15,0.07,1.16,-0.00,-1.32,0.00
-0.00,-3.36,-0.00,-0.17,-0.00,-0.42,3.57,-3.37,-0.00,2.53
-0.00,1.05,-1.99,0.00,1.80,0.00,-0.00,-0.00,-0.55,1.35

我对 proper? dropout 的理解是,在 mini-batchbatch梯度下降阶段,反向传播更新"thinned network"[=59=的权重和偏差].然而,在 example 的实现中,一批中每个样本 的神经元被随机 丢弃,如 oo.txt 第 5 至 8 行所示,对于每个样本,"thinned network" 是 不同的

作为比较,在随机梯度下降的情况下,样本被一个接一个地馈入神经网络,并且在每次迭代中,更新每个 tf.layers.dropout 引入 "thinned network" 的权重.

我的问题是,在mini-batch或者batch training中,不应该实现对所有样本在一批中敲除相同的神经元吗?也许通过在每次迭代时对所有输入批次样本应用一个掩码? 类似于:

# ones: a 1xN all 1s tensor
# mask: a 1xN 0-1 tensor, multiply fc1 by mask with broadcasting along the axis of samples
mask = tf.layers.dropout(ones, rate=dropout, training=is_training)
fc1 = tf.multiply(fc1, mask)

现在我在想 example 中的 dropout 策略可能是 weighted 更新某个神经元权重的方式,如果一个神经元保留在小批量中 10 个样本中的 1 个,其权重将更新 alpha * 1/10 * (y_k_hat-y_k) * x_k,与 alpha * 1/10 * sum[(y_k_hat-y_k) * x_k] 相比,另一个神经元的权重保留在所有 10 个样本中?

截图来自here

Dropout 通常用于防止过度拟合。在这种情况下,它将对其中一个神经元施加巨大的权重。通过不时地将其随机设为 0,您可以强制网络使用更多神经元来确定结果。为了让它运作良好,你应该为每个例子丢弃不同的神经元,这样你计算的梯度与你在没有丢弃的情况下得到的梯度更相似。

如果您要为批次中的每个示例丢弃相同的神经元,我的猜测是您的梯度会不太稳定(对于您的应用程序可能无关紧要)。

此外,dropout 会放大其余值,以将平均激活保持在大致相同的水平。没有它,当您关闭 dropout 时,网络会学习错误的偏见或过度饱和。

如果您仍然希望在批处理中丢弃相同的神经元,则将丢弃应用于形状为 (1, num_neurons) 的所有 1 张量,然后将其与激活相乘。

使用 dropout 时,您实际上是在尝试使用 Monte-Carlo 采样(通过积分符号下的微分,平均梯度等于平均值)。通过为每个 mini-batch 固定一个 dropout mask,你只是在连续的梯度估计之间引入相关性,这会增加方差并导致训练速度变慢。

想象一下,对小批量中的每个图像使用不同的 dropout-mask,但是从同一图像的 k 个副本形成小批量;很明显,这完全是白费力气!