Tensorflow——关于Variable xxx/Adam does not exist报错原因探究

报错信息

最近在学习deepcolor漫画自动上色项目,运行main.py的时候,由于项目使用的tensorflow版本较老,所以报了一些错误,其中我认为最棘手的就是这个错误:
错误信息太长,加个回车变成两行方便看

ValueError: Variable d_h0_conv/w/Adam does not exist, or was not created with tf.get_variable(). 
Did you mean to set reuse=tf.AUTO_REUSE in VarScope?

错误代码片段

print tf.get_variable_scope().reuse     # 输出False
self.disc_true, disc_true_logits = self.discriminator(self.real_AB, reuse=False)
self.disc_fake, disc_fake_logits = self.discriminator(self.fake_AB, reuse=True)

……(不必要的部分)

t_vars = tf.trainable_variables()
self.d_vars = [var for var in t_vars if 'd_' in var.name]
self.g_vars = [var for var in t_vars if 'g_' in var.name]

# 下面这行是报错行
self.d_optim = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.d_loss, var_list=self.d_vars)
self.g_optim = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.g_loss, var_list=self.g_vars)

错误原因测试

加入一些代码进行错误测试,运行结果我写在了注释里:

print tf.get_variable_scope().reuse     # 输出False
self.disc_true, disc_true_logits = self.discriminator(self.real_AB, reuse=False)
self.disc_fake, disc_fake_logits = self.discriminator(self.fake_AB, reuse=True)
print tf.get_variable_scope().reuse     # 输出True,说明上面一行起到了将reuse赋值为True的作用

# 此时的reuse因为上面的调用被置为了True,则当前variable_scope中,部分定义变量的方法会受限
# 以下两行不受影响,说明reuse和普通的变量定义方式没关系
suibian = 1
print suibian
# 以下变量定义受到了影响,说明使用get_variable之类的函数定义变量,会受到reuse的影响
# (报错信息:ValueError: Variable v does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?)
v = tf.get_variable("v", shape=[1], initializer=tf.constant_initializer(1.0))
print v

……(不必要的部分)

t_vars = tf.trainable_variables()
self.d_vars = [var for var in t_vars if 'd_' in var.name]
self.g_vars = [var for var in t_vars if 'g_' in var.name]

# 下面这行是报错行
self.d_optim = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.d_loss, var_list=self.d_vars)
self.g_optim = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.g_loss, var_list=self.g_vars)

有资料说明,tf.train.AdamOptimizer()调用时会定义Adam变量,但这些资料没有说明定义细节,经分析,我认为定义细节是这样的:

首先告知读者必要事项,以上代码的倒数第二行中,我的var_list中的第一个变量是d_h0_conv/w,而报错信息中的变量是d_h0_conv/w/Adam,说明tf.train.AdamOptimizer()是为var_list中的变量xxx创建名为xxx/Adam的变量。

另外,注意以下这种报错格式:

ValueError: Variable xx does not exist, or was not created with tf.get_variable(). 
Did you mean to set reuse=tf.AUTO_REUSE in VarScope?

在刚才的错误测试代码中,在reuse为True的情况下,尝试用get_variable()创建变量会报这种错误,而普通的变量定义不会触发这种错误,比如用x = 1定义变量x;以及文章开头提到的tf.train.AdamOptimizer()报错也是这个格式。所以基本可以肯定tf.train.AdamOptimizer()创建Adam变量的方式是使用get_variable()之类的函数进行创建,或者严谨点讲,至少其不是用普通的创建变量的方式进行创建。

错误解决

添加一些代码,如下是添加之后的样子(顺便附上几行注释供读者理解):

print tf.get_variable_scope().reuse     # 输出False
self.disc_true, disc_true_logits = self.discriminator(self.real_AB, reuse=False)
self.disc_fake, disc_fake_logits = self.discriminator(self.fake_AB, reuse=True)

……(不必要的部分)

t_vars = tf.trainable_variables()
self.d_vars = [var for var in t_vars if 'd_' in var.name]
self.g_vars = [var for var in t_vars if 'g_' in var.name]

with tf.variable_scope(tf.get_variable_scope(), reuse=tf.AUTO_REUSE):
      # AdamOptimizer函数会为var_list中的每一个变量创建Adam变量,而且是在这个scope下创建,var_list中的第一个变量就是d_h0_conv/w,
      # 所以先创建d_h0_conv/w/Adam,如果不加上面那行,则此时的reuse是True,而其是新创建的变量,所以会报错,
      # 这也说明了AdamOptimizer定义Adam变量的方式不是普通定义方式,而是用get_variable之类的函数定义
      self.d_optim = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.d_loss, var_list=self.d_vars)
      self.g_optim = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.g_loss, var_list=self.g_vars)

如果你有任何问题,你可以通过邮件联系我: [email protected] .
我的github博客:umbrellalalalala.github.io

发布了36 篇原创文章 · 获赞 41 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/umbrellalalalala/article/details/87174039