Tensorflow:使用Adam优化器

52

我正在尝试使用tensorflow中的一些简单模型,其中之一与第一个MNIST for ML Beginners example非常相似,但维度较大。我能够使用梯度下降优化器无问题地进行训练,并获得足够好的收敛效果。当我尝试使用ADAM优化器时,我会遇到以下错误:

tensorflow.python.framework.errors.FailedPreconditionError: Attempting to use uninitialized value Variable_21/Adam
     [[Node: Adam_2/update_Variable_21/ApplyAdam = ApplyAdam[T=DT_FLOAT, use_locking=false, _device="/job:localhost/replica:0/task:0/cpu:0"](Variable_21, Variable_21/Adam, Variable_21/Adam_1, beta1_power_2, beta2_power_2, Adam_2/learning_rate, Adam_2/beta1, Adam_2/beta2, Adam_2/epsilon, gradients_11/add_10_grad/tuple/control_dependency_1)]]

在运行过程中,抱怨未初始化的特定变量会发生变化。这个错误是什么意思?它表明了什么出了问题?似乎无论使用哪种学习率都会发生。

5个回答

101

AdamOptimizer类创建额外的变量,称为“slots”,以保存“m”和“v”累加器的值。

如果你好奇,可以在这里查看源代码,它实际上非常易读:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/training/adam.py#L39 其他优化器,如Momentum和Adagrad也使用slots。

在训练模型之前必须初始化这些变量。

初始化变量的常规方法是调用tf.initialize_all_variables(),该方法会在调用时向图中添加初始化变量的操作。

(顺便说一下:与其名称所暗示的不同,initialize_all_variables() 不会初始化任何东西,它只会添加操作以在运行时初始化变量。)

你必须在添加优化器后调用initialize_all_variables()。

...build your model...
# Add the optimizer
train_op = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# Add the ops to initialize variables.  These will include 
# the optimizer slots added by AdamOptimizer().
init_op = tf.initialize_all_variables()

# launch the graph in a session
sess = tf.Session()
# Actually intialize the variables
sess.run(init_op)
# now train your model
for ...:
  sess.run(train_op)

1
假设我想在中途更换优化器(和其他变量),那么如何初始化它而不破坏已经训练好的变量? - dolbi
@dolbi 没有一种优雅的方法,但我使用我在这里概述的方法。自从将AdamOptimizer添加到图中以来,您可以使用tf.initialize_variables([list,of,variables])仅使用新变量和tf.all_variables()。我必须说,这种方法不应该在意味着要运行多次的代码中使用,但在实验时效果很好。 - Poik
4
此答案曾正确,但现在该方法已被 tf.global_variables_initializer() 替代。 - LYu

4

FailedPreconditionError: 尝试使用未初始化的值 是与tensorflow相关的最常见错误之一。从官方文档中,FailedPreconditionError

当运行一个在tf.Variable被初始化之前读取它的操作时,这个异常通常会被抛出。

在你的情况下,错误甚至解释了哪个变量没有被初始化:Attempting to use uninitialized value Variable_1。TF教程之一详细介绍了变量、它们的创建/初始化/保存/加载

基本上,要初始化变量,你有三个选项:

我几乎总是使用第一种方法。记得将其放在会话运行中。所以你会得到像这样的结果:

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

如果您想了解更多关于变量的信息,请阅读this documentation,了解如何report_uninitialized_variables并检查is_variable_initialized

1

0

在AdamOptimizer之后运行init,而不需要在之前定义init或运行init

sess.run(tf.initialize_all_variables())

或者

sess.run(tf.global_variables_initializer())


-3

我曾经遇到过类似的问题。(使用GradientDescent优化器进行训练没有问题,但是当使用Adam优化器或任何带有自己变量的优化器时会出现错误)

将会话更改为交互式会话解决了我的问题。

sess = tf.Session()

进入

sess = tf.InteractiveSession()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接