当前位置: 首页 > 知识库问答 >
问题:

在卷积层中不能同时使用偏置和批量归一化

松骏俊
2023-03-14

由于其简单性,我将slim框架用于tensorflow。但我想有一个卷积层,既有偏差又有批量规范化。在vanilla tensorflow中,我有:

def conv2d(input_, output_dim, k_h=5, k_w=5, d_h=2, d_w=2, name="conv2d"):
    with tf.variable_scope(name):
        w = tf.get_variable('w', [k_h, k_w, input_.get_shape()[-1], output_dim],

    initializer=tf.contrib.layers.xavier_initializer(uniform=False))
    conv = tf.nn.conv2d(input_, w, strides=[1, d_h, d_w, 1], padding='SAME')

    biases = tf.get_variable('biases', [output_dim], initializer=tf.constant_initializer(0.0))
    conv = tf.reshape(tf.nn.bias_add(conv, biases), conv.get_shape())

    tf.summary.histogram("weights", w)
    tf.summary.histogram("biases", biases)

    return conv

d_bn1 = BatchNorm(name='d_bn1')
h1 = lrelu(d_bn1(conv2d(h0, df_dim + y_dim, name='d_h1_conv')))

我将其改写为slim:

h1 = slim.conv2d(h0,
                 num_outputs=self.df_dim + self.y_dim,
                 scope='d_h1_conv',
                 kernel_size=[5, 5],
                 stride=[2, 2],
                 activation_fn=lrelu,
                 normalizer_fn=layers.batch_norm,
                 normalizer_params=batch_norm_params,                           
                 weights_initializer=layers.xavier_initializer(uniform=False),
                 biases_initializer=tf.constant_initializer(0.0)
                 )

但这段代码并没有给conv层添加偏差。那是因为https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/layers/python/layers/layers.py#L1025在哪里

    layer = layer_class(filters=num_outputs,
                    kernel_size=kernel_size,
                    strides=stride,
                    padding=padding,
                    data_format=df,
                    dilation_rate=rate,
                    activation=None,
                    use_bias=not normalizer_fn and biases_initializer,
                    kernel_initializer=weights_initializer,
                    bias_initializer=biases_initializer,
                    kernel_regularizer=weights_regularizer,
                    bias_regularizer=biases_regularizer,
                    activity_regularizer=None,
                    trainable=trainable,
                    name=sc.name,
                    dtype=inputs.dtype.base_dtype,
                    _scope=sc,
                    _reuse=reuse)
    outputs = layer.apply(inputs)

在层的构造中,这导致在使用批处理规范化时没有偏差。这是否意味着我不能同时使用slim和layers库进行偏差和批量规范化?或者,当使用slim时,是否有另一种方法可以实现层中的偏差和批量规范化?

共有2个答案

郭永安
2023-03-14

我们的卷积层没有偏差的原因是我们对它们的输出应用了批量标准化。批量规范化的目标是通过以下方式获得输出:

  • 平均值=0

由于我们希望平均值为0,因此不希望添加偏离0的偏移量(偏差)。我们希望卷积层的输出只依赖于系数权重。

阎彬炳
2023-03-14

批量归一化已经包括添加偏差项。回顾BatchNorm已经:

gamma * normalized(x) + bias

因此,没有必要(也没有意义)在卷积层中添加另一个偏置项。简单地说,BatchNorm通过它们的平均值来转移激活。因此,任何常量都将被抵消。

如果你仍然想这样做,你需要删除normalizer_fn参数,并将BatchNorm添加为单层。就像我说的,这没有意义。

但解决办法是

net = slim.conv2d(net, normalizer_fn=None, ...)
net = tf.nn.batch_normalization(net)

请注意,BatchNorm依赖于非渐变更新。因此,您需要使用与UPDATE_OPS集合兼容的优化器。或者您需要手动添加tf.control_dependencies

长话短说:即使实现ConvWithBias批处理规范,它的行为也将类似于ConvWithBias批处理规范。这与没有激活功能的多个完全连接的层的行为类似。

 类似资料:
  • 我正在实现一个依赖于3D卷积的模型(对于类似于动作识别的任务),我想使用批量规范化(参见 下面的代码引用了TensorFlow r0.12,它显式地引用了变量——我的意思是我没有使用tf。承包商。学习tf以外的内容。承包商。图层。batch\u norm()函数。我这样做是为了更好地理解事情是如何运作的,并且有更多的实现自由度(例如,变量摘要)。 我将通过首先编写完全连接层的示例,然后编写2D卷积

  • 我是卷积神经网络新手,对特征映射和如何在图像上进行卷积来提取特征有概念。我很高兴知道一些关于在CNN应用批量标准化的细节。 我知道什么是特征图和不同的元素是权重在每一个特征图。但我不能理解什么是位置或空间位置。 我完全不能理解下面的句子“在alg.1中,我们让B是一个特征映射中的所有值的集合,它跨越了一个小批处理的元素和空间位置。” 如果有人能用更简单的术语来解释我,我会很高兴的

  • 卷积神经网络有一个批量过滤器, 持续不断的在图片上滚动收集图片里的信息,每一次收集的时候都只是收集一小块像素区域, 然后把收集来的信息进行整理, 这时候整理出来的信息有了一些实际上的呈现, 比如这时的神经网络能看到一些边缘的图片信息, 然后在以同样的步骤, 用类似的批量过滤器扫过产生的这些边缘信息, 神经网络从这些边缘信息里面总结出更高层的信息结构,比如说总结的边缘能够画出眼睛,鼻子等等. 再经过

  • Convolution1D层 keras.layers.convolutional.Convolution1D(nb_filter, filter_length, init='uniform', activation='linear', weights=None, border_mode='valid', subsample_length=1, W_regularizer=None, b_regu

  • Conv1D层 keras.layers.convolutional.Conv1D(filters, kernel_size, strides=1, padding='valid', dilation_rate=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zero