假设我有一个使用 SGD 的简单 AND 神经元:
data = np.array([
(0, 0),
(0, 1),
(1, 0),
(1, 1),
])
labels = np.array([
[0],
[0],
[0],
[1],
])
x = tf.placeholder(tf.float32, shape=[None, 2])
y = tf.placeholder(tf.float32, shape=[None, 1])
w = tf.Variable(initial_value=[[-0.31199348], [-0.46391705]], dtype=tf.float32)
b = tf.Variable(initial_value=[-1.94877], dtype=tf.float32)
h = tf.nn.bias_add(tf.matmul(x, w), b)
error = tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=h)
optimizer = tf.train.GradientDescentOptimizer().minimize(error)
因此我会出现二维错误:
In [0]: error.get_shape()
Out[0]: TensorShape([Dimension(None), Dimension(1)])
如果我检查 error w.r.t. 的梯度w 使用简单的脚本:
In [1]: print sess.run(
tf.gradients(error, w),
feed_dict={
x: data,
y: labels,
},
)
我会看到以下内容:
Out[1]: array([[-0.8440423 ], [-0.85625702]]
现在,如果我更改 error 以跨批处理计算 mean:
In [2]: error = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=h),
reduction_indices=0,
)
我会有一个单维错误:
In [3]: error.get_shape()
Out[3]: (1,)
使用相同的脚本我会看到不同的结果:
Out[4]: [[-0.21101058], [-0.21406426]]
这实际上非常有意义,因为现在它是相同的结果除以 4(批量大小)- 这就是真正的意思。
我无法理解的是,在第一种情况下,tensorflow 是如何计算梯度的,其中包含二维 error(基本上我们有多个错误,而不是一个错误)?如果它隐式计算第一个维度(批处理)的平均值,对我来说似乎是合理的,但正如我们所见,情况并非如此。
请您参考如下方法:
现在我有了一个答案:tensorflow 只是对第一个维度(即批处理)的误差求和。
