【问题标题】:Why input is scaled in tf.nn.dropout in tensorflow?为什么输入在张量流中的 tf.nn.dropout 中进行缩放?
【发布时间】:2016-04-08 10:18:39
【问题描述】:

我不明白为什么 dropout 在 tensorflow 中会这样工作。 CS231n 的博客说,"dropout is implemented by only keeping a neuron active with some probability p (a hyperparameter), or setting it to zero otherwise." 也可以从图片中看到(取自同一站点)

来自 tensorflow 网站,With probability keep_prob, outputs the input element scaled up by 1 / keep_prob, otherwise outputs 0.

现在,为什么输入元素放大了1/keep_prob?为什么不保留输入元素的概率而不用1/keep_prob 对其进行缩放?

【问题讨论】:

  • 这就是所谓的权重缩放推理规则

标签: machine-learning neural-network deep-learning tensorflow


【解决方案1】:

这是一个快速实验,可以消除任何剩余的混乱。

从统计上讲,NN 层的权重通常接近正态分布(但不一定),但即使在实践中尝试对完美正态分布进行采样时,也存在总是计算错误。

然后考虑以下实验:

DIM = 1_000_000                      # set our dims for weights and input
x = np.ones((DIM,1))                 # our input vector
#x = np.random.rand(DIM,1)*2-1.0     # or could also be a more realistic normalized input

probs = [1.0, 0.7, 0.5, 0.3]         # define dropout probs

W = np.random.normal(size=(DIM,1))   # sample normally distributed weights
print("W-mean = ", W.mean())         # note the mean is not perfect --> sampling error!

# DO THE DRILL
h = defaultdict(list)
for i in range(1000):
  for p in probs:
    M = np.random.rand(DIM,1)
    M = (M < p).astype(int)
    Wp = W * M
    a = np.dot(Wp.T, x)
    h[str(p)].append(a)

for k,v in h.items():
  print("For drop-out prob %r the average linear activation is %r (unscaled) and %r (scaled)" % (k, np.mean(v), np.mean(v)/float(k)))

样本输出:

x-mean =  1.0
W-mean =  -0.001003985674840264
For drop-out prob '1.0' the average linear activation is -1003.985674840258 (unscaled) and -1003.985674840258 (scaled)
For drop-out prob '0.7' the average linear activation is -700.6128015029908 (unscaled) and -1000.8754307185584 (scaled)
For drop-out prob '0.5' the average linear activation is -512.1602655283492 (unscaled) and -1024.3205310566984 (scaled)
For drop-out prob '0.3' the average linear activation is -303.21194422742315 (unscaled) and -1010.7064807580772 (scaled)

请注意,由于统计上不完美的正态分布,未缩放的激活会减少。

您能发现W-mean 与平均线性激活均值之间的明显相关性吗?

【讨论】:

    【解决方案2】:

    如果您继续阅读cs231n,则会解释 dropoutinverted dropout 之间的区别。

    由于我们希望在测试时保持前向传递不变(并在训练期间调整我们的网络),tf.nn.dropout 直接实现 inverted dropout,缩放值。

    【讨论】:

      【解决方案3】:

      假设网络有n 神经元,我们应用了退出率1/2

      训练阶段,我们将剩下n/2 个神经元。因此,如果您期望所有神经元的输出 x,现在您将获得 x/2。所以对于每一个batch,网络权重都是按照这个x/2来训练的

      测试/推理/验证阶段,我们不应用任何 dropout,因此输出为 x。因此,在这种情况下,输出将是 x 而不是 x/2,这会给您错误的结果。因此,您可以在测试期间将其缩放到 x/2。

      而不是上述特定于测试阶段的缩放。 Tensorflow 的 dropout 层所做的是,无论是否有 dropout(训练或测试),它都会缩放输出,使总和保持不变。

      【讨论】:

        【解决方案4】:

        这种缩放使相同的网络可以用于训练(keep_prob &lt; 1.0)和评估(keep_prob == 1.0)。来自Dropout paper

        这个想法是在测试时使用单个神经网络而不会丢失。该网络的权重是经过训练的权重的缩小版本。如果在训练期间以概率 p 保留一个单元,则该单元的传出权重在测试时乘以 p,如图 2 所示。

        TensorFlow 实现不是在测试时添加操作以将权重缩小keep_prob,而是添加一个操作以在训练时将权重放大1. / keep_prob。对性能的影响可以忽略不计,代码也更简单(因为我们使用相同的图表并将keep_prob 视为tf.placeholder(),根据我们是在训练还是评估网络,它会提供不同的值)。

        【讨论】:

        • 对不起,我是这个概念的新手。也许我错过了一些明显的东西。你能给出一个更简单的解释吗?我的意思是为什么 1/keep_prob?如果我使用 keep_prob 与 1/keep_prob 会有什么区别。顺便说一句,我从你的解释中理解了为什么代码变得更简单。
        • 目的是保持权重的预期总和相同——因此激活的预期值相同——与keep_prob无关。如果(在进行 dropout 时)我们禁用概率为keep_prob 的神经元,我们需要将其他权重乘以1. / keep_prob 以保持该值相同(在预期中)。否则,例如,非线性会根据keep_prob 的值产生完全不同的结果。
        猜你喜欢
        • 1970-01-01
        • 2020-05-10
        • 1970-01-01
        • 1970-01-01
        • 2019-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多