MNIST tutorial的代码:
with tf.name_scope('hidden1'):
weights = tf.Variable(
tf.truncated_normal([IMAGE_PIXELS, hidden1_units],
stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))),
name='weights')
biases = tf.Variable(tf.zeros([hidden1_units]),
name='biases')
hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)
# Hidden 2
with tf.name_scope('hidden2'):
weights = tf.Variable(
tf.truncated_normal([hidden1_units, hidden2_units],
stddev=1.0 / math.sqrt(float(hidden1_units))),
name='weights')
biases = tf.Variable(tf.zeros([hidden2_units]),
name='biases')
hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)
似乎所有的偏见都是零。添加它们有什么意义?
答案 0 :(得分:6)
您正在查看网络初始化代码。这是训练前的网络。随机weights
值不会映射到该阶段的任何有用函数。相反,它们是随机的,以防止每个人工神经元学习相同的东西,因为反向传播是确定性的,你通常需要一些能够打破同一层内神经元之间对称性的东西。否则,每个训练示例都会为每个权重生成完全相同的渐变,并且一切都会以锁步方式发生变化。
下面:
biases = tf.Variable(tf.zeros([hidden1_units]),
name='biases')
biases
是一个变量。在训练期间,它会稍后改变。如果您愿意,可以从随机值开始(类似于权重),并且训练仍然可以与示例几乎完全相同。但是,随机权重在实践中已足以防止输出相互复制,因此将偏差设置为零是最简单的方法。
在一些培训后看一下偏差值,你会发现它们都是不同的。