TensorFlow作用域报错:Variable w1_d/Adam/不存在,已尝试方案仍未解决
Variable w1_d/Adam/ does not exist, or was not created with tf.get_variable()报错问题 嘿,我帮你捋捋这个TensorFlow的报错问题——你碰到的ValueError: Variable w1_d/Adam/ does not exist, or was not created with tf.get_variable(),本质是变量作用域和优化器辅助变量的复用逻辑没对齐,而且你之前的解决方案可能没覆盖到优化器的部分。
报错根源分析
你在discriminator函数里用tf.get_variable_scope().reuse_variables()来复用变量,但这个操作只覆盖了你手动定义的w1_d、w2_d这类变量。而Adam优化器在训练时,会自动为每个可训练变量创建对应的辅助变量(比如动量变量w1_d/Adam、w1_d/Adam_1),这些变量是优化器初始化时生成的,并没有被纳入你手动设置的作用域复用逻辑里。当你第二次调用判别器(比如训练生成器时复用判别器参数),优化器找不到对应的辅助变量,就会抛出这个错误。
针对性解决方案
我给你三个关键的修复步骤,结合你的代码调整:
1. 把变量复用的控制权交给外部variable_scope
不要在discriminator函数内部设置reuse,而是在调用函数时用tf.variable_scope包裹,明确指定作用域和复用规则。这样所有在该作用域下的变量(包括优化器后续生成的辅助变量)都会被统一管理:
# 修改discriminator函数,去掉内部的reuse逻辑 def discriminator(x_data, y_data, drate, is_training, market): hidden = 64 input111 = tf.concat([x_data, y_data, market], 1) features = 26 sdev = np.sqrt(float(1/features)) w1_d = tf.get_variable("w1_d",[features, hidden],initializer = tf.random_normal_initializer(stddev=sdev)) sdev = np.sqrt(float(1/hidden)) weights2_d = tf.get_variable("w2_d", [hidden, hidden], initializer = tf.random_normal_initializer(stddev=sdev)) # 补全你截断的weights17_d定义 weights17_d = tf.get_variable("weights17_d", [hidden, 1], initializer = tf.random_normal_initializer(stddev=np.sqrt(1/hidden))) # 后续网络层逻辑... # 第一次调用:创建判别器变量 with tf.variable_scope("discriminator"): d_real = discriminator(x_real, y_real, drate, is_training=True, market=market_real) # 第二次调用:复用判别器变量 with tf.variable_scope("discriminator", reuse=True): d_fake = discriminator(x_fake, y_fake, drate, is_training=False, market=market_fake)
2. 延迟优化器定义,确保所有变量已创建
一定要等判别器的所有变量(包括两次调用的复用变量)都创建完成后,再定义优化器,并且用var_list明确指定优化器要更新的变量范围:
# 先计算判别器损失 d_loss = ... # 你的损失计算逻辑,比如交叉熵损失 # 定义优化器,只更新discriminator作用域下的可训练变量 d_optimizer = tf.train.AdamOptimizer(learning_rate=0.0002) d_train_op = d_optimizer.minimize( d_loss, var_list=tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope="discriminator") )
这样优化器会在所有变量都存在的前提下,创建对应的辅助变量,后续复用判别器时就能找到这些变量了。
3. 检查变量定义的完整性
你的精简代码里weights17_d = tf.get_va...是截断的,要确保所有用tf.get_variable()创建的变量都有完整、正确的定义,拼写错误(比如把tf.get_variable写成tf.get_va)会导致变量未被创建,进而触发类似的找不到变量的报错。
验证逻辑
调整后,当第二次调用判别器时,外部的variable_scope(reuse=True)会让该作用域下的所有变量(包括优化器的辅助变量)都被正确复用,不会再出现找不到w1_d/Adam/这类变量的情况。
内容的提问来源于stack exchange,提问作者cfen

