TensorFlow的variable_scope和name_scope详细介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_29957455/article/details/81783543

TensorFlow中有两个作用域(scope),分别是name_scope和variable_scope。variable_scope主要是给variable_name(变量名)增加前缀,还可以给op_name(运算名称)增加前缀,而name_scope是,op_name(运算名称)增加前缀。接下来回详细介绍两者的区别和联系。

一、variable_scope的使用

tf.get_variable函数通过所给的名称创建或者获取一个变量

1、variable_scope的使用

    with tf.variable_scope("foo") as scope:
        v = tf.get_variable("v",[1])
    print(v.name)
    #foo/v:0

tf.variable_scope有一个参数reuse默认None,当reuse为None或False时,表示在该作用域下tf.get_variable函数只能创建变量,如果创建两个相同名字的变量就会报错:ValueError: Variable foo/v already exists

    with tf.variable_scope("foo") as scope:
        v = tf.get_variable("v",[1])
        v1 = tf.get_variable("v",[1])
    print(v.name)

将reuse参数设置为True时,作用域可以共享变量,两个变量相等

    with tf.variable_scope("foo",reuse=True):
        v1 = tf.get_variable("v",[1])
        v2 = tf.get_variable("v",[1])
    print(v1.name,v2.name,v1 == v2)
    #foo/v:0 foo/v:0 True

2、获取变量的作用域

    with tf.variable_scope("foo") as foo_scope:
        v = tf.get_variable("v",[1])
    with tf.variable_scope(foo_scope):
        w = tf.get_variable("w",[1])
    print(v.name,w.name)
    #foo/v:0 foo/w:0

如果在开启一个变量的作用域之前预先定义一个作用域,则会跳过当前变量的作用域,使用预先定义的作用域

    with tf.variable_scope("bar"):
        with tf.variable_scope("baz") as other_scope:
            print(other_scope.name)
            #bar/baz
            #使用预先定义的作用域
            with tf.variable_scope(foo_scope) as foo_scope2:
                print(foo_scope2.name)
                #foo

3、变量作用域的初始化

在定义变量的作用域的时候,可以给该作用域下的变量默认定义一个初始化器,在这个作用域下的子作用域或变量都可以继承或者重写父作用域的初始化值。

    sess = tf.Session()
    #为该作用域下的变量定义一个初始化器,默认变量值为0.4
    with tf.variable_scope("foo",initializer=tf.constant_initializer(0.4)):
        #使用默认值
        v = tf.get_variable("v",[1])
        #重写作用域的初始化值
        w = tf.get_variable("w",[1],initializer=tf.constant_initializer(0.5))
        #子作用域,默认使用父作用域的初始化器
        with tf.variable_scope("bar"):
            v1 = tf.get_variable("v1",[1])
        #子作用域,重写父作用域的初始化值
        with tf.variable_scope("baz",initializer=tf.constant_initializer(0.6)):
            v2 = tf.get_variable("v2",[1])
    init = tf.global_variables_initializer()
    sess.run(init)
    print(sess.run(v),sess.run(w),sess.run(v1),sess.run(v2))
    #[0.4] [0.5] [0.4] [0.6]
    sess.close()

4、在variable_scope下的op_name

    with tf.variable_scope("foo"):
        x = 1.0 + tf.get_variable("v",[1])
        print(x.op.name)
        #foo/add

在variable_scope下也会为op_name增加一个前缀

二、name_scope的使用

name_scope下的作用域会影响op_name,但不会影响get_variable创建的变量,会影响通过Variable()创建的变量

    with tf.variable_scope("foo"):
        with tf.name_scope("bar"):
            v = tf.get_variable("v",[1])
            w = tf.Variable(tf.zeros([1]),name="w")
            z = 1.0 + v
    print(v.name,w.name,z.op.name)
    #foo/v:0 foo/bar/w:0 foo/bar/add

猜你喜欢

转载自blog.csdn.net/sinat_29957455/article/details/81783543