tf中的命名空间
最近在模型的搭建中遇到tf中变量的共享空间相关问题,故记之。
出于变量共享与传递的考虑,TensorFlow中引入了变量(或者叫 域)命名空间的机制。
此测试环境在TensorFlow1.X下:import tensorflow as tf
- name scope:通过调用tf.name_scope产生
- variable scope:通过调用tf.variable_scope产生
在命名空间中创建变量有以下两种方式:
- 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()
却可以。
以上!大家如果觉得有用的话,支持一下哦~