在卷积层中,我应该在哪里应用dropout?

5

由于在应用卷积层时,“层”这个词经常意味着不同的东西(有些人将所有内容视为单个层,而其他人则将卷积、非线性和池化视为不同的“层”;参见图9.7),因此我不清楚在卷积层中何时应用dropout。

dropout是在非线性和池化之间发生吗?


例如,在TensorFlow中,它会是这样的吗?
kernel_logits = tf.nn.conv2d(input_tensor, ...) + biases
activations = tf.nn.relu(kernel_logits)
kept_activations = tf.nn.dropout(activations, keep_prob)
output = pool_fn(kept_activations, ...)

另一个例子建议在池化之后应用dropout。 - orome
我一直在尝试使用dropout代替对图像进行2x2平均下采样的实验。我的理论是,如果不是对每个2x2图像区域进行下采样,而是使用dropout有效地生成更多略微不同的图像,则我将拥有更多的训练样本,并能够进行长时间的训练并获得更好的结果。经过尝试许多不同的设置和长时间的训练运行后,将dropout作为将下采样转化为内容生成的手段已被证明是无效的。 - Anton Codes
更新,使用3x3实际上会有很大的差别。在3x3下采样时使用dropout而不是仅仅使用平均值,会产生显著的差异。在MNIST上,这意味着使用dropout在3x3下采样到卷积然后最大池化可以得到92.5%的正确率,而使用平均值在3x3下采样到卷积然后最大池化只能得到84.2%的正确率。 - Anton Codes
1个回答

2

你可以尝试在不同的地方应用dropout,但是为了防止过拟合,我不确定在池化之前会出现什么问题。对于CNN,我看到的是在使用tensorflow.nn.dropout时,它会在非线性和池化之后应用:

    # Create a convolution + maxpool layer for each filter size
    pooled_outputs = []
    for i, filter_size in enumerate(filters):
        with tf.name_scope("conv-maxpool-%s" % filter_size):
            # Convolution Layer
            filter_shape = [filter_size, embedding_size, 1, num_filters]
            W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W")
            b = tf.Variable(tf.constant(0.1, shape=[num_filters]), name="b")
            conv = tf.nn.conv2d(
                self.embedded_chars_expanded,
                W,
                strides=[1, 1, 1, 1],
                padding="VALID",
                name="conv")
            # Apply nonlinearity
            h = tf.nn.relu(tf.nn.bias_add(conv, b), name="relu")
            # Maxpooling over the outputs
            pooled = tf.nn.max_pool(
                h,
                ksize=[1, sequence_length - filter_size + 1, 1, 1],
                strides=[1, 1, 1, 1],
                padding='VALID',
                name="pool")
            pooled_outputs.append(pooled)



    # Combine all the pooled features
    num_filters_total = num_filters * len(filters)
    self.h_pool = tf.concat(3, pooled_outputs)
    self.h_pool_flat = tf.reshape(self.h_pool, [-1, num_filters_total])

    # Add dropout
    with tf.name_scope("dropout"):
        self.h_drop = tf.nn.dropout(self.h_pool_flat, self.dropout_keep_prob)

回复:“就防止过拟合而言,在池化之前可能不会遇到太多问题”,我认为这并不是为了避免在卷积层出现过拟合;而是为了在后续层中引入噪声(6.1.3节前的最后一段)。 - orome

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