TensorFlow 中定义变量、函数和数值计算时的名称更新方式分为两种:命名空间和作用域。
命名空间
命名空间就是不同模块或功能下定义的变量、函数和数值计算之间彼此隔离的空间。
TensorFlow 中使用 tf.name_scope
定义命名空间,其语法为:
with tf.name_scope(name):
# 定义变量、函数及数值计算
其中 name
是命名空间的名字。
在命名空间之内定义的变量、函数和数值计算都会自动在名字前加上 name/
的前缀,表示属于该命名空间。例如:
with tf.name_scope('layer_1'):
weights = tf.Variable(tf.random_normal([784, 256]))
biases = tf.Variable(tf.zeros([256]))
with tf.name_scope('layer_2'):
weights = tf.Variable(tf.random_normal([256, 10]))
biases = tf.Variable(tf.zeros([10]))
其中第一个变量名字为 'layer_1/Variable'
,第二个变量名字为 'layer_2/Variable'
,它们都属于不同的命名空间。
作用域
作用域是一个更加通用的概念,可以对 TensorFlow 中所有的名称进行控制。不同于命名空间,作用域可以嵌套且不会自动加前缀。
TensorFlow 中使用 tf.variable_scope
定义作用域,其语法为:
with tf.variable_scope(name):
# 定义变量、函数及数值计算
其中 name
是作用域的名字。如果作用域已经存在,那么作用域下的所有变量、函数和数值计算都会共享该作用域。
举个例子,我们将上面的代码改为使用作用域:
with tf.variable_scope('layer_1'):
weights = tf.get_variable('weights', shape=[784, 256], initializer=tf.random_normal_initializer())
biases = tf.get_variable('biases', shape=[256], initializer=tf.zeros_initializer())
with tf.variable_scope('layer_2'):
weights = tf.get_variable('weights', shape=[256, 10], initializer=tf.random_normal_initializer())
biases = tf.get_variable('biases', shape=[10], initializer=tf.zeros_initializer())
其中,使用 tf.get_variable
定义变量时,需要指定变量的名字和形状(可以通过初始化来推导出来),并指定初始化方式。如果作用域下已经有同名的变量,那么该变量会与已有的变量共享变量的值,因此它们的名字是相同的,但仍然可以通过 trainable_variables
方法获取到不同的变量对象。
示例
为了更好地理解命名空间和作用域的区别,我们可以考虑一个代码示例。该示例中会定义两个神经网络,每个网络各自定义了一个相同名字的隐藏层变量。
import tensorflow as tf
# 定义第一个神经网络
with tf.name_scope('network_1'):
with tf.name_scope('layer_1'):
weights = tf.Variable(tf.random_normal([784, 256]), name='weights')
biases = tf.Variable(tf.zeros([256]), name='biases')
with tf.name_scope('layer_2'):
weights = tf.Variable(tf.random_normal([256, 10]), name='weights')
biases = tf.Variable(tf.zeros([10]), name='biases')
# 定义第二个神经网络
with tf.variable_scope('network_2'):
with tf.variable_scope('layer_1'):
weights = tf.get_variable('weights', shape=[784, 256], initializer=tf.random_normal_initializer())
biases = tf.get_variable('biases', shape=[256], initializer=tf.zeros_initializer())
with tf.variable_scope('layer_2'):
weights = tf.get_variable('weights', shape=[256, 10], initializer=tf.random_normal_initializer())
biases = tf.get_variable('biases', shape=[10], initializer=tf.zeros_initializer())
# 输出变量
print('Network 1 Variables')
for var in tf.trainable_variables(scope='network_1'):
print(var.name)
print('Network 2 Variables')
for var in tf.trainable_variables(scope='network_2'):
print(var.name)
输出结果为:
Network 1 Variables
network_1/layer_1/weights:0
network_1/layer_1/biases:0
network_1/layer_2/weights:0
network_1/layer_2/biases:0
Network 2 Variables
network_2/layer_1/weights:0
network_2/layer_1/biases:0
network_2/layer_2/weights:0
network_2/layer_2/biases:0
从输出结果可以看出,第一个神经网络中的变量名字都带有 network_1
前缀,第二个神经网络中的变量名字则没有前缀。原因在于,命名空间会自动加前缀,而作用域不会。此外,同样的变量名字,在作用域中会被认为是同一变量,而在命名空间中则不会。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Tensorflow 定义变量,函数,数值计算等名字的更新方式 - Python技术站