Tensorflow:如何正确使用 Adam 优化器

Posted

技术标签:

【中文标题】Tensorflow:如何正确使用 Adam 优化器【英文标题】:Tensorflow: How to use Adam optimizer properly 【发布时间】:2017-05-23 16:46:44 【问题描述】:

有人已经问过similar question,但是那里给出的解决方案对我不起作用。

我正在尝试在 tensorflow 中使用 Adam 优化器。这是我关于它的代码的一部分:

adamOptimizer = tf.train.AdamOptimizer(learning_rate=0.001, beta1=0.9,
           beta2=0.999, epsilon=1e-08, use_locking=False, name='Adam')

print('Optimizer was created!')

# Create a variable to track the global step.
global_step = tf.Variable(0, name='global_step', trainable=False)

#Initialize variables
vars_to_init = ae.get_variables_to_init(n)
vars_to_init.append(global_step)
vars_to_init.append

sess.run(tf.variables_initializer(vars_to_init))

# create an optimizer
train_op = adamOptimizer.minimize(loss, global_step=global_step)

第一次使用train_op后出现如下错误:

FailedPreconditionError(参见上文的回溯):尝试使用未初始化的值 pretrain_1/beta2_power [[节点:pretrain_1/beta2_power/read = IdentityT=DT_FLOAT, _class=["loc:@autoencoder_variables/weights1"], _device="/job:localhost/replica:0/task:0/cpu:0"]]

如果我尝试添加一行

vars_to_init.append(beta2_power)

我收到以下错误:

NameError:未定义全局名称“beta2_power”

如果我遵循similar question 的建议并将 sess.run(tf.variables_initializer(vars_to_init)) 替换为 sess.run(tf.initialize_all_variables()), 运行此行后出现以下错误:

FailedPreconditionError: 尝试使用未初始化的值 autoencoder_variables/biases1 [[节点:autoencoder_variables/biases1/read = IdentityT=DT_FLOAT, _class=["loc:@autoencoder_variables/biases1"], _device="/job:localhost/replica:0/task:0/cpu:0"]]

我在使用梯度下降优化器时没有遇到任何问题...

我做错了什么?使用此优化器的正确方法是什么?

编辑 有关该类的更多详细信息以阐明 autoencoder_variables:

class AutoEncoder(object):

_weights_str = "weights0"
_biases_str = "biases0"

def __init__(self, shape, sess):

  self.__shape = shape 
  self.__num_hidden_layers = len(self.__shape) - 2

  self.__variables = 
  self.__sess = sess

  self._setup_variables()

@property
def shape(self):
  return self.__shape

@property
def num_hidden_layers(self):
   return self.__num_hidden_layers

@property
def session(self):
   return self.__sess

def __getitem__(self, item):

return self.__variables[item]

def __setitem__(self, key, value):

self.__variables[key] = value

def _setup_variables(self):
with tf.name_scope("autoencoder_variables"):
  for i in xrange(self.__num_hidden_layers + 1):
    # Train weights
    name_w = self._weights_str.format(i + 1)
    w_shape = (self.__shape[i], self.__shape[i + 1])
    a = tf.mul(4.0, tf.sqrt(6.0 / (w_shape[0] + w_shape[1])))
    w_init = tf.random_uniform(w_shape, -1 * a, a)
    self[name_w] = tf.Variable(w_init,
                               name=name_w,
                               trainable=True)
    # Train biases
    name_b = self._biases_str.format(i + 1)
    b_shape = (self.__shape[i + 1],)
    b_init = tf.zeros(b_shape)
    self[name_b] = tf.Variable(b_init, trainable=True, name=name_b)

    if i <= self.__num_hidden_layers:

      # Hidden layer fixed weights (after pretraining before fine tuning)
      self[name_w + "_fixed"] = tf.Variable(tf.identity(self[name_w]),
                                            name=name_w + "_fixed",
                                            trainable=False)

      # Hidden layer fixed biases
      self[name_b + "_fixed"] = tf.Variable(tf.identity(self[name_b]),
                                            name=name_b + "_fixed",
                                            trainable=False)

      # Pretraining output training biases
      name_b_out = self._biases_str.format(i + 1) + "_out"
      b_shape = (self.__shape[i],)
      b_init = tf.zeros(b_shape)
      self[name_b_out] = tf.Variable(b_init,
                                     trainable=True,
                                     name=name_b_out)

def _w(self, n, suffix=""):
  return self[self._weights_str.format(n) + suffix]

def _b(self, n, suffix=""):
  return self[self._biases_str.format(n) + suffix]

def get_variables_to_init(self, n):
  assert n > 0
  assert n <= self.__num_hidden_layers + 1

  vars_to_init = [self._w(n), self._b(n)]

  if n <= self.__num_hidden_layers:
    vars_to_init.append(self._b(n, "_out"))

  if 1 < n <= self.__num_hidden_layers+1:
    # Fixed matrices for learning of deeper layers
    vars_to_init.append(self._w(n - 1, "_fixed"))
    vars_to_init.append(self._b(n - 1, "_fixed"))

  return vars_to_init

【问题讨论】:

你应该使用sess.run(tf.initialize_all_variables())。能否提供autoencoder_variables 代码? 我添加了它。如果您需要更多信息,请告诉我 我发现问题确实不在于 Adam 优化器,而在于变量结构。我想,我会尽快自己修复它 【参考方案1】:

问题是我使用一个变量值来初始化另一个变量(它在初始化期间引发了使用未初始化变量的错误)。

而不是在初始化期间使用另一个变量

self[name_b + "_fixed"] = tf.Variable(tf.identity(self[name_b]),
                                            name=name_b + "_fixed",
                                            trainable=False)

我随机初始化它

self[name_b + "_fixed"] = tf.Variable(init_b,
                                            name=name_b + "_fixed",
                                            trainable=False)

训练完成后将其分配给另一个变量:

 ae[name_w + "_fixed"] = tf.identity(ae[name_w])

【讨论】:

以上是关于Tensorflow:如何正确使用 Adam 优化器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 tensorflow 2.0.0 中使用 Lazy Adam 优化器

神经网络优化算法如何选择Adam,SGD

如何选择优化器 optimizer

Tensorflow Adam Multigpu 梯度

TensorFlow Adam Optimizer 状态未更新( get_config )

优化器