tensorflow基础学习——变量管理—tf.variable_scope()

本文介绍TensorFlow中的变量管理,包括tf.get_variable与tf.Variable的区别,如何避免变量复用错误,以及如何在复杂神经网络中使用变量提高代码可读性。
部署运行你感兴趣的模型镜像

变量管理即是当神经网络参数在网络结构更加复杂的时候,参数更加多的时候,来用一个更好的方式来管理网络神经的参数,tensorflow提供他送过名称来创建或者获取一个变量名的机制,通过这个机制,在不同函数中可以直接通过变量的名字来使用变量,而不需要将变量通过参数的形式来传递。
在创建变量的时候采用的“tf.get_variable()与tf.Variable()”等价,下面两种表达方式是等价的:

#下面两种方式是等价的
v=tf.get_variable("v",shape=[1],initializer=tf.constant_initializer(1.0))
v=tf.Variable(tf.constant(1.0,shape=[1]),name="v")

tf.get_ variable 函数与tf.Variable 函数最大的区别在于指定变量名称的参数。对于tf.Variable 函数, 变量名称是一个可选的参数,通过name= ~”的形式给出。但是对于tf.get_ variable 函数,变量名称是一个必填的参数。tf.get_variable 会根据这个名字去创建或者获取变量。在以上样例程序中, tf.get_variable 首先会试图去创建一个名字为v 的参数,如果创建失败(比如已经有同名的参数),那么这个程序就会报错。这是为了避免无意识的变量复用造成的错误。比如在定义神经网络参数时,第一层网络的权重已经叫weights 了,那么在创建第二层神经网络时,如果参数名仍然叫weights ,就会触发变量重用的错误。否则两层神经网络共用一个权重会出现一些比较难以发现的错误。如果需要通过tf.get_ variable 获取一个已经创建的变量,需要通过tf. variable_ scope 函数来生成一个上下文管理器,并明确指定在这个上下文管理器中, tf.get_variable 将直接获取己经生成的变量。下面给出了一段代码说明如何通过tf. variable_ scope 函数来控制tf.get_variable 函数获取己经创建过的变量。

#在名字为foo的命名空间中创建名字为v的变量
with tf.variable_scope("foo"):
  v=tf.get_variable(
    "v",[1],initializer=tf.constant_initializer(1.0)
  ) 
#因为在命名空间里foo中的已经存在名字变量为v的变量了,所以会出现报错
with tf.variable_scope("foo",reuse=True):
  v=tf.get_variable(
    "v",[1]
  )

#在生成上下文管理器时,将参数reuse设置为true。这样tf.get_variable函数将直接
#获取已经申明的变量
with tf.variable_scope("foo",reuse=True):
  v1=tf.get_variable(
    "v",[1]
  )
  print(v==v1)#输出为true
#命名空间为bar中没有创建变量v,则下列代码会报错:
with tf.variable_scope("bar",reuse=True):
   v=tf.get_variable(
    "v",[1]
  )   

tf.variable_scope函数嵌套时:
为指定reuse时,reuse为false,当有指定时,为指定值,镶嵌管理器的reuse值与外层保持一致。

with tf.get_variable_scope("root"):
  #可以通过tf.get_variable_scope().reuse函数来获取当前文的
   #reuse值
  print(tf.get_variable_scope().reuse)
   #输出当前的false,即最外层reuse是false
  with tf.variable_scope("foo",reuse=True):
  #新建一个上下文管理器,且指定reuse=true
    print(tf.get_variable_scope().reuse) #输出为TRUE
    with tf.variable_scope("bar"):
    #嵌套一个上下文管理器,不指定reuse,
    #此时该管理器的值与外层保持一致
      print(tf.get_variable_scope().reuse)
      #当退出reuse=true的层后,最外层的reuse仍然为false
  print(tf.get_variable_scope().reuse)  

用在mnist的数据集中:

def inference(input_tensor,reuse=False):
  #定义第一层神经网络的前向传播过程
  with tf.Variable_scope('layer1',reuse=reuse):
  #根据传进来的reuse来判断是否创建变量还是使用已经
  # 创建好的,
    weights=tf.get_variable("weights",[INPUT_NODE,LAYER1NODE],
    initializer=tf.truncated_normal_initializer(stddev=0.1))  
    biases=tf.get_variable("biases",[LAYER1_NODE],
    initializer=tf.constant_initializer(0.0))   
    layer1=tf.nn.relu(tf.matmul(input_tensor,weights)+biases)    
    #类似定义第二层的神经网络的变量与前向传播过程   
    with tf.Variable_scope('layer2',reuse=reuse):
    #根据传进来的reuse来判断是否创建变量还是使用已经
    # 创建好的,
      weights=tf.get_variable("weights",[INPUT_NODE,LAYER1NODE],
      initializer=tf.truncated_normal_initializer(stddev=0.1))  
      biases=tf.get_variable("biases",[LAYER1_NODE],
      initializer=tf.constant_initializer(0.0))   
      layer2=tf.matmul(input_tensor,weights)+biases
      #返回最后的传播结果
      return layer2
x=tf.placeholder(tf.float32,[None,INPUT_NODE],name='x-input')
y=inference(x)

使用上述的代码可以不再需要将所有的变量都作为参数都传递到函数中去了,当神经网络更加复杂的时候,参数更多的时候,使用这种变量可以大大提高程序的可读性。

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.15

TensorFlow-v2.15

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

### TensorFlow 中 `tf.name_scope` 的行为 在 TensorFlow 中,`tf.name_scope` 主要用于为操作(operations)和变量variables)生成一个命名空间。它不会直接影响变量的存储空间分配,而是通过在变量名称前添加前缀来组织图中的节点[^3]。 如果使用 `tf.Variable()` 创建变量,并且这些变量位于不同的 `tf.name_scope` 下,则即使变量具有相同的名称,它们也会被分配到不同的存储空间。这是因为 `tf.name_scope` 会在变量名称前加上作用域名称,从而使得每个变量的实际名称变得唯一。 以下是一个示例代码,展示 `tf.name_scope` 对变量名称的影响: ```python import tensorflow as tf with tf.name_scope('scope1'): var1 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a2') with tf.name_scope('scope2'): var2 = tf.Variable(tf.random_normal(shape=[2, 3], mean=0, stddev=1), name='a2') with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print(var1.name) # 输出:scope1/a2:0 print(var2.name) # 输出:scope2/a2:0 ``` 从上述代码可以看出,尽管两个变量都命名为 `a2`,但由于它们分别位于 `scope1` 和 `scope2` 下,实际生成的变量名称分别为 `scope1/a2:0` 和 `scope2/a2:0`,因此它们会被分配到独立的存储空间[^3]。 需要注意的是,`tf.name_scope` 不会管理变量的复用逻辑。如果需要实现变量共享或更复杂的变量管理功能,则应使用 `tf.variable_scope` 配合 `reuse` 参数[^1]。 ### 总结 - 在 `tf.name_scope` 下,即使变量具有相同的名称,它们也不会共享存储空间,而是会新开辟存储空间。 - 这是因为 `tf.name_scope` 会为变量名称添加前缀,从而确保变量名称唯一。 - 如果需要实现变量共享或更精细的变量管理,应使用 `tf.variable_scope`。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值