pyt*_*hor 15 python tensorflow
我正在为初学者查看Tensorflow MNIST示例,并发现在此部分中:
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
Run Code Online (Sandbox Code Playgroud)
将批量大小从100更改为高于204会导致模型无法收敛.它可以达到204,但是在205和我试过的任何更高的数字,精度最终将<10%.这是一个错误,关于算法的东西,还有什么?
这是运行OS X的二进制安装,似乎是0.5.0版本.
dga*_*dga 28
您是否在初学者示例中使用了非常基本的线性模型?
这是调试它的技巧 - 在增加批量大小时观察交叉熵(第一行来自示例,第二行我刚添加):
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
cross_entropy = tf.Print(cross_entropy, [cross_entropy], "CrossE")
Run Code Online (Sandbox Code Playgroud)
批量大小为204时,您会看到:
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[92.37558]
I tensorflow/core/kernels/logging_ops.cc:64] CrossE[90.107414]
Run Code Online (Sandbox Code Playgroud)
但是在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]
Run Code Online (Sandbox Code Playgroud)
Ack - NaN出现了.基本上,大批量大小正在创建如此巨大的梯度,使您的模型失控 - 它所应用的更新太大,并且超出应该大幅度的方向.
在实践中,有几种方法可以解决这个问题.您可以将学习率从.01降低到比如.005,这样最终的准确度为0.92.
train_step = tf.train.GradientDescentOptimizer(0.005).minimize(cross_entropy)
Run Code Online (Sandbox Code Playgroud)
或者你可以使用更复杂的优化算法(Adam,Momentum等),它试图做更多的事情来弄清楚渐变的方向.或者你可以使用一个更复杂的模型,它有更多的自由参数来分散那个大的梯度.
小智 16
@dga给出了一个很好的答案,但我想扩大一点.
当我写初学者教程时,我实现了成本函数,如下所示:
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
我这样写的是因为它看起来与交叉熵的数学定义最相似.但实际上这样做可能会更好:
cross_entropy = -tf.reduce_mean(y_*tf.log(y))
为什么使用均值而不是总和会更好?好吧,如果我们求和,那么批量加倍会使成本增加一倍,并且还会使梯度的幅度加倍.除非我们调整我们的学习率(或使用为我们调整它的算法,如@dga建议),否则我们的训练会爆炸!但是如果我们使用均值,那么我们的学习率就会变得与我们的批量大小无关,这很好.
我鼓励你看看亚当(tf.train.AdamOptimizer()
).与SGD相比,摆弄事物往往更宽容.
小智 15
发生0*log(0)时发生Nan:
更换:
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
Run Code Online (Sandbox Code Playgroud)
有:
cross_entropy = -tf.reduce_sum(y_*tf.log(y + 1e-10))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8106 次 |
最近记录: |