Tensorflow和变量范围-如何正确重用范围?
我重新设计了一个我以前用Keras制作的GAN。到目前为止没有问题,但是我注意到,根据我实现范围重用的方式,我的模型没有得到正确的训练。也许有人能帮助我了解正在发生的事情: 工作版本:Tensorflow和变量范围-如何正确重用范围?,tensorflow,deep-learning,tensorflow-gpu,tensor,Tensorflow,Deep Learning,Tensorflow Gpu,Tensor,我重新设计了一个我以前用Keras制作的GAN。到目前为止没有问题,但是我注意到,根据我实现范围重用的方式,我的模型没有得到正确的训练。也许有人能帮助我了解正在发生的事情: 工作版本: with tf.variable_scope('g/h0') as scope: reuse_scope = scope if reuse else None h0 = tf.contrib.layers.fully_connected( z, 4*4*512,
with tf.variable_scope('g/h0') as scope:
reuse_scope = scope if reuse else None
h0 = tf.contrib.layers.fully_connected(
z,
4*4*512,
activation_fn=None,
reuse=reuse_scope,
scope='g/h0'
)
h0 = tf.nn.relu(h0)
with tf.variable_scope('g/h0') as scope:
if reuse:
scope.reuse_variables()
h0 = tf.contrib.layers.fully_connected(
z,
4*4*512,
activation_fn=None
)
h0 = tf.nn.relu(h0)
不工作版本:
with tf.variable_scope('g/h0') as scope:
reuse_scope = scope if reuse else None
h0 = tf.contrib.layers.fully_connected(
z,
4*4*512,
activation_fn=None,
reuse=reuse_scope,
scope='g/h0'
)
h0 = tf.nn.relu(h0)
with tf.variable_scope('g/h0') as scope:
if reuse:
scope.reuse_variables()
h0 = tf.contrib.layers.fully_connected(
z,
4*4*512,
activation_fn=None
)
h0 = tf.nn.relu(h0)
两个版本都会导致一个工作网络,而第二个版本则会导致一个从不更新的网络。我不明白为什么第一个版本会导致一个正确的情况
在TensorBoard中,根据我选择的版本,图形看起来非常不同。我怀疑梯度反向传播不正确
第二个版本有没有办法做到这一点?我觉得这更容易理解。我认为你应该尝试用这种方式定义你的范围:
reuse = ... # True or False
with tf.variable_scope('g/h0') as scope:
h0 = tf.contrib.layers.fully_connected(
z,
4*4*512,
activation_fn=None,
reuse=reuse,
scope='fully_connected',
)
h0 = tf.nn.relu(h0)
如果将重用设置为False
,则完全连接的层将“照常”创建。如果将其设置为True
,则不会创建额外的参数,但权重和偏差将从另一个作用域中重新使用(当然,使用相同的名称,并在其中创建了具有相同名称的变量)
参数必须是reuse
或True
(或False
,自然)None
参数与范围
无关。它只是内部作用域名称。例如,如果设置重用
,则完全连接层内的权重参数将为范围='g/h0'
,但如果未设置,则将为'g/h0/g/h0/weights:0'
'g/h0/完全连接/weights:0'
tf.contrib.layers.fully\u connected
中使用reuse=True
变量,您需要指定范围
完整的工作示例:
import tensorflow as tf
## A value for z that you did not specify in your question
z = tf.placeholder(tf.float32, (2,1))
## First fully-connected layer with ut result
with tf.variable_scope('g/h0'):
h0 = tf.contrib.layers.fully_connected(
z,
4*4*512,
activation_fn=None,
reuse=None
)
h0 = tf.nn.relu(h0)
tf.global_variables()
# Returns [<tf.Variable 'g/h0/fully_connected/weights:0' shape=(1, 8192) dtype=float32_ref>, <tf.Variable 'g/h0/fully_connected/biases:0' shape=(8192,) dtype=float32_ref>]
# Second layer ith resuse = True
with tf.variable_scope('g/h0'):
h0 = tf.contrib.layers.fully_connected(
z,
4*4*512,
activation_fn=None,
reuse=True, scope = 'fully_connected'
)
h0 = tf.nn.relu(h0)
tf.global_variables()
# Returns [<tf.Variable 'g/h0/fully_connected/weights:0' shape=(1, 8192) dtype=float32_ref>, <tf.Variable 'g/h0/fully_connected/biases:0' shape=(8192,) dtype=float32_ref>]
# => the same parameters are used for both layers
将tensorflow导入为tf
##问题中未指定的z值
z=tf.占位符(tf.float32,(2,1))
##具有ut结果的第一个完全连接层
使用tf.变量_范围('g/h0'):
h0=tf.contrib.layers.fully_连接(
Z
4*4*512,
激活\u fn=无,
重用=无
)
h0=tf.nn.relu(h0)
tf.global_变量()
#返回[,]
#第二层ith resuse=真
使用tf.变量_范围('g/h0'):
h0=tf.contrib.layers.fully_连接(
Z
4*4*512,
激活\u fn=无,
重用=真,范围='完全连接'
)
h0=tf.nn.relu(h0)
tf.global_变量()
#返回[,]
#=>两层使用相同的参数
我的猜测(尽管我对重用几乎没有经验)是,您应该给重用
一个布尔值(是否要重用另一个范围中的变量),而不是范围名如果您精确重用,那么您需要精确范围。然后我不理解编写重用的意义。另外,我认为scope
参数没有链接到reuse
参数,它只是内部使用的范围的名称。看到了吗?如果我不需要使用,那么什么作用域.reuse\u variable()是有用的?如果你在同一个作用域中声明两次相同的变量,就像你在本文档中看到的一样,这似乎是有用的:(但是为什么你要这样做?我不知道…)它不起作用=>ValueError:reuse=True不能在没有名称的情况下使用\u或\u scope
我已经修复了你的代码,现在它起作用了。如果我不需要在这里使用scope.reuse\u variables()
的话,你能告诉我什么时候应该使用它吗?我想我们是在同一时间编辑的。很抱歉,我不知道scope.reuse_variables()
的实际用例(我几乎是tensorflow的初学者)。考虑把它作为一个新的问题,我会去做。谢谢