• tensorflow-作用域


    变量名字由两部分组成:scope/变量name。

    name 参数才是对象的唯一标识。

    1、tf.name_scope()

    Graph中保存着一个属性_name_stack(string类型),_name_stack的值保存着当前的name_scope的名字,在这个图中创建的对象Variable、Operation、Tensor的名字之前都加上了这个前缀。

    #它的主要目的是为了更加方便地管理参数命名。
    # 与 tf.Variable() 结合使用。简化了命名

    with tf.name_scope('conv1') as scope:
          weights1 = tf.Variable([1.0, 2.0], name='weights')
          bias1 = tf.Variable([0.3], name='bias')

    # 下面是在另外一个命名空间来定义变量的

    with tf.name_scope('conv2') as scope:
          weights2 = tf.Variable([4.0, 2.0], name='weights')
          bias2 = tf.Variable([0.33], name='bias')

    # 所以,实际上weights1 和 weights2 这两个引用名指向了不同的空间,不会冲突

    print (weights1.name)
    print (weights2.name)
    
    输出:
    conv1/weights:0 conv2/weights:0

    ********************************************************************

    # 注意,这里的 with 和 python 中其他的 with 是不一样的
    # 执行完 with 里边的语句之后,这个 conv1/ 和 conv2/ 空间还是在内存中的。这时候如果再次执行上面的代码
    # 就会再生成其他命名空间(执行完上面的代码,接着执行这里的,上面的空间还在内存中)

     

    with tf.name_scope('conv1') as scope:
        weights1 = tf.Variable([1.0, 2.0], name='weights')
        bias1 = tf.Variable([0.3], name='bias')
    with tf.name_scope('conv2') as scope:
        weights2 = tf.Variable([4.0, 2.0], name='weights')
        bias2 = tf.Variable([0.33], name='bias')
    print (weights1.name)
    print (weights2.name)
    
    输出:  
    conv1_1/weights:0
    conv2_1/weights:0

     

    注意,tf.Variable再次命名相同变量时(本来又要产生 conv1/weights:0  conv2/weights:0),结果这里产生了(conv1_1/weights:0 conv2_1/weights:0),所以这就是tf.Variable()的一个特性,遇到同名时,产生一个新的,并不共享。

     

     

    2、 tf.variable_scope

    Graph中维护一个collection,这个collection中的 键_VARSCOPE_KEY对应一个 [current_variable_scope_obj],保存着当前的variable_scope。使用 get_variable() 创建变量的时候,就从这个collection 取出 current_variable_scope_obj,通过这个 variable_scope创建变量。

    tf.variable_scope() 主要结合 tf.get_variable() 来使用,实现变量共享。

    如果tf.variable_scope函数使用参数reuse=None或者reuse=False创建上下文管理器,则tf.get_variable函数可以创建新的变量。但不可以创建已经存在的变量即为同名的变量。

    如果tf.variable_scope函数使用参数reuse=True创建上下文管理器,则tf.get_variable函数可以使用已在当前空间定义的变量赋值来创建变量。但不可以使用不存在的变量来创建。

     

    # 这里是正确的打开方式~~~可以看出,name 参数才是对象的唯一标识

    with tf.variable_scope('v_scope') as scope1:
       Weights1 = tf.get_variable('Weights', shape=[2, 3])
       bias1 = tf.get_variable('bias', shape=[3])

    # 下面来共享上面已经定义好的变量
    # note: 在下面的 scope 中的变量必须已经定义过了,才能设置 reuse=True,否则会报错

    with tf.variable_scope('v_scope', reuse=True) as scope2:
       Weights2 = tf.get_variable('Weights')
       Weights3 = tf.get_variable('Weights', [2,3]) #shape如果不同会报错
    print (Weights2.name)
    print (Weights3.name)
    
    输出
    v_scope/Weights:0
    v_scope/Weights:0

    # 可以看到这两个引用名称指向的是同一个内存对象

    *********************************************************************

    # 注意, bias1 的定义方式
    with tf.variable_scope('v_scope') as scope1:
       Weights1 = tf.get_variable('Weights', shape=[2, 3])
       bias1 = tf.Variable([0.52], name='bias')
    # 下面来共享上面已经定义好的变量
    # note: 在下面的 scope 中的get_variable()变量必须已经定义过了,才能设置 reuse=True,否则会报错
    with tf.variable_scope('v_scope', reuse=True) as scope2:
       Weights2 = tf.get_variable('Weights')
       bias2 = tf.Variable([0.53], name='bias')
    print (Weights1.name)
    print (Weights2.name)
    print (bias1.name)
    print (bias2.name)
    
    输出:
    v_scope / Weights:0
    v_scope / Weights:0
    v_scope / bias:0
    v_scope_1 / bias:0

    使用tf.get_variable发现之前有定义好的的该变量,则进行权值共享。

    而bias1 = tf.Variable([0.52], name='bias')发现之前定义好的名字,则重新定一个新的,并没有共享权值。

    tf.get_variable_scope() :获取当前scope

    tf.get_variable_scope().reuse_variables() 共享变量

     

    3、对比

    简单来说name_scope是给Op_name加前缀的,variable_scope是给变量variable_name和Op_name加前缀的.作用域在使用Tensorboard对Graph对象进行可视化的时候很有帮助,作用域会把一些Op划分到较大的语句块当中.使用tensorboard可视化数据流图的时候,每个作用域都对自己的Op进行封装,从而获得更好的可视化效果.

    • 如果在 tf.name_scope() 环境下分别使用 tf.get_variable() 和 tf.Variable(),两者的主要区别在于 

      • tf.get_variable() 创建的变量名不受 name_scope 的影响;
      • tf.get_variable() 创建的变量,name 属性值不可以相同;tf.Variable() 创建变量时,name 属性值允许重复(底层实现时,会自动引入别名机制)
    • 此外 tf.get_variable() 与 tf.Variable() 相比,多了一个 initilizer (初始化子)可选参数; 

      • tf.Variable() 对应地多了一个 initial_value 关键字参数,也即对于 tf.Variable 创建变量的方式,必须显式初始化;

     

    name_scope

     

    with tf.name_scope("ns") as ns:
       b = tf.Variable(1.0, name='b')
       w = tf.get_variable("w", shape=[2,10],dtype=tf.float32)
       a = tf.add(b, [3],name='a')
    print ns
    print b.name
    print w.name
    print a.name
    输出: ns / ns / b:0 w:0 ns / a:0

    *********************************************************************

    with tf.name_scope("ns") as ns:
       with tf.name_scope("ns1") as ns1:
          b1 = tf.Variable(0, name='b1')
          w1 = tf.get_variable("w1", shape=[10], dtype=tf.float32)
          a1 = tf.add(b1, [3], name='a1')
    print ns1
    print b1.name
    print w1.name
    print a1.name
    
    输出:
    ns/ns1/
    ns/ns1/b1:0
    w1:0
    ns/ns1/a1:0

    *********************************************************************

    with tf.name_scope("ns") as ns:
       with tf.variable_scope("vs1") as vs1:
          b2 = tf.Variable(0, name='b2')
          w2 = tf.get_variable("w2", shape=[2])
          a2 = tf.add(b2, [3], name='a2')
    print vs1
    print vs1.name
    print b2.name
    print w2.name
    print a2.name
    
    输出:
    <tensorflow.python.ops.variable_scope.VariableScope object at 0x42fe790>
    vs1
    ns/vs1/b2:0
    vs1/w2:0
    ns/vs1/a2:0

    *********************************************************************

    with tf.name_scope("ns") as ns:
       with tf.name_scope(None) as n1:
          b3 = tf.Variable(2.0, name='b3')
          w3 = tf.get_variable("w3", shape=[2])
          a3 = tf.add(b3, [3], name='a3')
    print n1
    print b3.name
    print w3.name
    print a3.name
    
    输出:
    
    b3:0
    w3:0
    a3:0

     

    variable_scope

     

    注意事项

    1. 在 variable_scope 里面的 variable_scope 会继承上面的 reuse 值,即上面一层开启了 reuse ,则下面的也跟着开启。但是不能人为的设置 reuse 为 false ,只有退出 variable_scope 才能让 reuse 变为 false:

    2、当在某一 variable_scope 内使用别的 scope 的名字时,此时不再受这里的等级关系束缚,直接与使用的 scope 的名字一样:

     

    with tf.variable_scope("vs") as vs:
       b = tf.Variable(1.0, name='b')
       w = tf.get_variable("w", shape=[2, 10], dtype=tf.float32)
       a = tf.add(b, [3], name='a')
    print vs
    print vs.name
    print b.name
    print w.name
    print a.name
    
    输出:
    <tensorflow.python.ops.variable_scope.VariableScope object at 0x46ee610>
    vs
    vs/b:0
    vs/w:0
    vs/a:0

    *********************************************************************

    with tf.variable_scope("vs") as vs:
       with tf.name_scope("ns1") as ns1:
          b1 = tf.Variable(0, name='b1')
          w1 = tf.get_variable("w1", shape=[10], dtype=tf.float32)
          a1 = tf.add(b1, [3], name='a1')
    print ns1
    print b1.name
    print w1.name
    print a1.name
    
    输出:
    vs/ns1/
    vs/ns1/b1:0
    vs/w1:0
    vs/ns1/a1:0

    *********************************************************************

    with tf.variable_scope("vs") as vs:
       with tf.variable_scope("vs1") as vs1:
          b2 = tf.Variable(0, name='b2')
          w2 = tf.get_variable("w2", shape=[2])
          a2 = tf.add(b2, [3], name='a2')
    print vs1
    print vs1.name
    print b2.name
    print w2.name
    print a2.name
    
    输出:
    <tensorflow.python.ops.variable_scope.VariableScope object at 0x4b1e310>
    vs/vs1
    vs/vs1/b2:0
    vs/vs1/w2:0
    vs/vs1/a2:0

    *********************************************************************

    with tf.variable_scope("vs") as vs:
       with tf.name_scope(None) as n1:
          b3 = tf.Variable(2.0, name='b3')
          w3 = tf.get_variable("w3", shape=[2])
          a3 = tf.add(b3, [3], name='a3')
    print n1
    print b3.name
    print w3.name
    print a3.name
    
    输出:
    
    b3:0
    vs/w3:0
    a3:0

     

    总结:

    1、使用tf.Variable()的时候,tf.name_scope()和tf.variable_scope() 都会给 Variable 和 op 的 name属性加上前缀。

    2、使用tf.get_variable()的时候,tf.name_scope()就不会给 tf.get_variable()创建出来的Variable加前缀。

  • 相关阅读:
    四、oracle 用户管理二
    三、oracle 用户管理一
    二、oracle sql*plus常用命令
    数据库的导入导出
    一:oracle系统包—-dbms_output用法
    数据库分类
    Oracle序列号详解
    Windows 下 java(JDK)的安装和环境变量的配置
    win7安装oracle 10g时发生“程序异常终止。发生内部错误”的提示
    对数据库列的操作
  • 原文地址:https://www.cnblogs.com/qjoanven/p/7831348.html
Copyright © 2020-2023  润新知