您在初学者示例中使用的是非常基本的线性模型?
这是调试它的一个技巧 - 在增加批量大小时观察交叉熵(第一行来自示例,第二行是我刚刚添加的):
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
cross_entropy = tf.Print(cross_entropy, [cross_entropy], "CrossE")
在批量大小为 204 时,您将看到:
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[92.37558]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[90.107414]
但是在 205 处,你会从一开始就看到这样的序列:
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[472.02966]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[475.11697]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[1418.6655]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[1546.3833]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[1684.2932]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[1420.02]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[1796.0872]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[nan]
Ack - NaN 出现了。基本上,大批量会产生如此巨大的梯度,以至于你的模型正在失控——它应用的更新太大,并且大大超出了它应该去的方向。
在实践中,有几种方法可以解决这个问题。您可以将学习率从 0.01 降低到例如 0.005,这会导致最终准确度为 0.92。
train_step = tf.train.GradientDescentOptimizer(0.005).minimize(cross_entropy)
或者您可以使用更复杂的优化算法(Adam、Momentum 等)来尝试做更多的事情来确定梯度的方向。或者你可以使用一个更复杂的模型,它有更多的自由参数来分散那个大的梯度。