如何理解TensorFlow中name与variable scope的区别

tf中的命名空间

最近在模型的搭建中遇到tf中变量的共享空间相关问题,故记之。
出于变量共享与传递的考虑,TensorFlow中引入了变量(或者叫 域)命名空间的机制。
此测试环境在TensorFlow1.X下:import tensorflow as tf

在命名空间中创建变量有以下两种方式:

  • tf.Variable:每次调用此函数的时候都会创建一个新的变量,如果该变量名称已存在,则会在该变量名称后添加一个后缀。
  • tf.get_variable:以该名称创建新变量,若已存在,则检索该名称的变量并获取其引用。

实例一

Script:

with tf.variable_scope("embeddin") as embedding_scope:

    testing2 = tf.Variable(tf.random_uniform((7, 10), -1.0, 1.0), name='testing2')

    testing3 = tf.get_variable(name='testing3', shape=[7, 10],initializer=tf.constant_initializer(1))
    
with tf.name_scope("optimization"):

    testing = tf.Variable(tf.random_uniform((7, 10), -1.0, 1.0), name='testing')

    testing1 = tf.get_variable(name='testing1', shape=[7, 10],initializer=tf.constant_initializer(1))

Output of variable:


>>> testing2

>>> testing3

>>> testing

>>> testing1

实例一说明在tf.name_scope中调用tf.get_variable产生的变量在调用上是不受域空间的限制的,也就是为全局变量;其余情况皆为作用域变量。

实例二

Script:

1.将实例一当中的testing3改为testing2

testing3 = tf.get_variable(name='testing2', shape=[7, 10],initializer=tf.constant_initializer(1))

2.将实例一当中的testing1改为testing

testing1 = tf.get_variable(name='testing', shape=[7, 10],initializer=tf.constant_initializer(1))

Output of variable:


>>> testing2

>>> testing3

>>> testing

>>> testing1

实例二结论:

  • 前两个output说明如果想在TensorFlow中想通过tf.get_variable获取一个变量的引用,以上方式行不通的(详见实例三)。而是会创建一个以($var_name)_1 命名的该变量的副本。
  • 后两个output再一次验证了实例一中的结论:即就是创建出以该名称命名的一个全局变量和一个作用域变量。

实例三

Script:

with tf.variable_scope("embeddin",reuse=True) as embedding_scope:

    testing2 = tf.Variable(tf.random_uniform((7, 10), -1.0, 1.0), name='testing2')

    testing3 = tf.get_variable(name='testing2', shape=[7, 10],initializer=tf.constant_initializer(1))

Output of variable:

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

此错误说明了tf.Variable创建的变量不能被share,而tf.get_variable()却可以。
以上!大家如果觉得有用的话,支持一下哦~

你可能感兴趣的:(tensorflow)