我知道偏差与将1
添加到每个层的输入向量中的情况相同,或者就像它是具有1
的常量输出的神经元一样。从偏置神经元出来的权重是在训练期间训练的正常权重。
现在我正在研究Tensorflow中的一些神经网络代码。例如。这个(它只是CNN(VGGnet)的一部分,特别是CNN中卷积结束和完全连接的层开始的部分):
with tf.name_scope('conv5_3') as scope:
kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32,
stddev=1e-1), name='weights')
conv = tf.nn.conv2d(self.conv5_2, kernel, [1, 1, 1, 1], padding='SAME')
biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32),
trainable=True, name='biases')
out = tf.nn.bias_add(conv, biases)
self.conv5_3 = tf.nn.relu(out, name=scope)
self.parameters += [kernel, biases]
# pool5
self.pool5 = tf.nn.max_pool(self.conv5_3,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding='SAME',
name='pool4')
with tf.name_scope('fc1') as scope:
shape = int(np.prod(self.pool5.get_shape()[1:]))
fc1w = tf.Variable(tf.truncated_normal([shape, 4096],
dtype=tf.float32,
stddev=1e-1), name='weights')
fc1b = tf.Variable(tf.constant(1.0, shape=[4096], dtype=tf.float32),
trainable=True, name='biases')
pool5_flat = tf.reshape(self.pool5, [-1, shape])
fc1l = tf.nn.bias_add(tf.matmul(pool5_flat, fc1w), fc1b)
self.fc1 = tf.nn.relu(fc1l)
self.parameters += [fc1w, fc1b]
现在我的问题是,为什么在完全连接的层中卷积层0
和1
中的偏差(此模型中的每个转换层都有0
用于偏置和FC层具有1
)?或者我的解释是否仅涵盖完全连接的层,而卷积层则不同?
答案 0 :(得分:0)
偏差(在任何层中)通常用零初始化,但也可以是随机或特定的小值。引自Stanford CS231n:
初始化偏见。初始化可能是常见的 偏差为零,因为对称性破坏是由 权重中的小随机数。对于ReLU非线性,有些 人们喜欢使用0.01等小常数值来表示所有偏差 因为这可确保所有ReLU装置在开始时点火 因此获得并传播一些梯度。但是,目前尚不清楚 如果这提供了一致的改进(事实上似乎有些结果 表明这表现更差)并且更简单地说 使用0偏差初始化。
其他示例:tf.layers.dense
函数是创建FC图层的捷径,默认情况下使用zero_initializer
;并且sample CNN对所有权重和偏差使用随机初始化,并且不会影响性能。
因此,总而言之,偏差初始化并不重要(与权重初始化相比),我很确定你也可以获得与零或小随机初始化相似的训练速度。