我为TensorFlow使用了Slim框架,因为它很简单。
但是我想要同时具有偏差和批处理规范化的卷积层。
在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时,是否有另一种方法来实现层中的偏差和批处理规范化?
最佳答案
批处理规范化已经包括了偏差项的添加。回顾一下,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+batchNorm,它的行为也将类似convWithOutbias+batchNorm。这与没有激活功能的多个完全连接层的行为相同。
关于python - 在卷积层中不能同时使用偏差和批量归一化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46256747/