关于tensorflow中的scope的命名及使用方法

相信大家在学习和使用tensorflow的过程中肯定会遇到过关于scope的一些问题,scope是一种给变量命名的方法,它会让变量命名变得简单,同时也常用于reusing variable 代码中,下面将会给大家讲解一下tensorflow中两种定义scope的方法,来帮助大家更好的理解和使用scope。

前言:scope的命名方式分为两种,tf.name_scope( )和tf.variable_scope( ),生成变量的途径也有两种:一种是 tf.get_variable( )需要提前定义一个initiallizer; 另一种是 tf.Variable( ).

一、在tf.name_scope() 的框架下使用这两种方式

首先我们先展示一段代码:

import tensorflow as tf

with tf.name_scope("a_name_scope"):
    initializer = tf.constant_initializer(value=1)
    var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
    var21 = tf.Variable(name='var2', initial_value=[2.1], dtype=tf.float32)
    var22 = tf.Variable(name='var2', initial_value=[2.2], dtype=tf.float32)


with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print(var1.name)        # var1:0
    print(sess.run(var1))   # [ 1.]
    print(var2.name)        # a_name_scope/var2:0
    print(sess.run(var2))   # [ 2.]
    print(var21.name)       # a_name_scope/var2_1:0
    print(sess.run(var21))  # [ 2.0999999]
    print(var22.name)       # a_name_scope/var2_2:0
    print(sess.run(var22))  # [ 2.20000005]

在session下我们分别打印出各个变量的名字和值,打印出来的结果显示在每一句代码后面的#注释部分。仔细观察上面的结果我们不难看出,在tf.name_scope( )这种框架下,如果使用tf.get_variable( )这种途径创建的变量,其名字是不受scope的名字所影响的。接下来用tf.Variable( )这种方式创建的变量,输出时会将scope的名字一起输出(即在scope这个变量下创建的变量),而且他们都有自己的变量名字并且相同,程序没有报错但也没数输出三个相同名字的,那是因为在创建变量时,会检测是否该变量的名字已经存在,如果存在则改变其名字,因此才会输出2_1和2_2。

二、在tf.variable_scope() 的框架下使用这两种方式

with tf.variable_scope("a_variable_scope") as scope:
    initializer = tf.constant_initializer(value=3)
    var3 = tf.get_variable(name='var3', shape=[1], dtype=tf.float32, initializer=initializer)
    var4 = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
    var5 = tf.Variable(name='var4', initial_value=[5], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var3.name)            # a_variable_scope/var3:0
    print(sess.run(var3))       # [ 3.]
    print(var4.name)            # a_variable_scope/var4:0
    print(sess.run(var4))       # [ 4.]

可以看出,在tf.variable_scope( )这种框架下,两种产生变量的途径创建的变量在输出时都会把scope变量的名字一起输出。
在有的时候程序中需要我们重复使用之前定义过的变量,那我们应该怎么办呢,那么我们就可以使用tensorflow中的scope.reuse_variables()。

with tf.variable_scope("a_variable_scope") as scope:
    initializer = tf.constant_initializer(value=3)
    var3 = tf.get_variable(name='var3', shape=[1], dtype=tf.float32, initializer=initializer)
    scope.reuse_variables()
    var3_reuse = tf.get_variable(name='var3',)
    var4 = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
    var4_reuse = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var3.name)            # a_variable_scope/var3:0
    print(sess.run(var3))       # [ 3.]
    print(var3_reuse.name)      # a_variable_scope/var3:0
    print(sess.run(var3_reuse)) # [ 3.]
    print(var4.name)            # a_variable_scope/var4:0
    print(sess.run(var4))       # [ 4.]
    print(var4_reuse.name)      # a_variable_scope/var4_1:0
    print(sess.run(var4_reuse)) # [ 4.]

从上面可以看到,如果想要达到重复利用变量的效果, 我们就要使用 tf.variable_scope(), 并搭配 tf.get_variable() 这种方式产生和提取变量. 不像 tf.Variable() 每次都会产生新的变量, tf.get_variable() 如果遇到了同样名字的变量时, 它会单纯的提取这个同样名字的变量(避免产生新变量). 而在重复使用的时候, 一定要在代码中强调 scope.reuse_variables(), 否则系统将会报错, 以为你只是单纯的不小心重复使用到了一个变量。
简单来看:

  1. 使用tf.Variable()的时候,tf.name_scope()和tf.variable_scope() 都会给 Variable 和 op 的 name属性加上前缀。
  2. 使用tf.get_variable()的时候,tf.name_scope()就不会给 tf.get_variable()创建出来的Variable加前缀。

个人觉得name_scope的作用在于封装一大堆操作让生成的数据流图具有层次化,方便navigate。variable_scope则是一个更加值得注意的东西。它控制着变量的分级命名。变量命名很重要如果变量名冲突是要报错的,还有就是它控制变量共享,你可以指定控制在某一个scope下所有的变量共享。name_scope是作用在操作上的,操作如果命名冲突没关系,tf会自动帮你加一个后缀,无关紧要。如果你希望好调试,那就为操作命个名。

通过上面的学习,相信各位同学能够很好的理解scope的命名方法了吧,那么就赶紧去实战吧!!!

你可能感兴趣的:(Machine,Learning)