报错信息
最近在学习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