简短回答:不要使用 Adadelta
今天很少有人使用它,你应该坚持:
-
tf.train.MomentumOptimizer
with 0.9
动量非常标准并且效果很好。缺点是你必须找到自己最好的学习率。
-
tf.train.RMSPropOptimizer
:结果较少依赖于良好的学习率。这个算法是与阿达德尔塔非常相似,但在我看来表现更好。
如果您确实想使用 Adadelta,请使用论文中的参数:learning_rate=1., rho=0.95, epsilon=1e-6
。一个更大的epsilon
一开始会有帮助,但要准备好比其他优化器等待更长的时间才能看到收敛。
请注意,在论文中,他们甚至没有使用学习率,这与保持它等于1
.
长答案
Adadelta 的起步非常缓慢。完整的算法来自paper http://www.matthewzeiler.com/pubs/googleTR2012/googleTR2012.pdf is:
问题是它们累积了更新的平方。
- 在第 0 步,这些更新的运行平均值为零,因此第一次更新将非常小。
- 由于第一次更新很小,所以一开始更新的运行平均值会很小,这在开始时是一种恶性循环
我认为 Adadelta 在更大的网络上表现得比你的更好,并且经过一些迭代后它应该等于 RMSProp 或 Adam 的性能。
这是我使用 Adadelta 优化器的代码:
import tensorflow as tf
v = tf.Variable(10.)
loss = v * v
optimizer = tf.train.AdadeltaOptimizer(1., 0.95, 1e-6)
train_op = optimizer.minimize(loss)
accum = optimizer.get_slot(v, "accum") # accumulator of the square gradients
accum_update = optimizer.get_slot(v, "accum_update") # accumulator of the square updates
sess = tf.Session()
sess.run(tf.initialize_all_variables())
for i in range(100):
sess.run(train_op)
print "%.3f \t %.3f \t %.6f" % tuple(sess.run([v, accum, accum_update]))
前 10 行:
v accum accum_update
9.994 20.000 0.000001
9.988 38.975 0.000002
9.983 56.979 0.000003
9.978 74.061 0.000004
9.973 90.270 0.000005
9.968 105.648 0.000006
9.963 120.237 0.000006
9.958 134.077 0.000007
9.953 147.205 0.000008
9.948 159.658 0.000009