zoukankan      html  css  js  c++  java
  • tf.name_scope()和tf.variable_scope() (转)

    网络层中变量存在两个问题:

    1. 随着层数的增多,导致变量名的增多;
    2. 在调用函数的时候,会重复生成变量,但他们存储的都是一样的变量。

     

    tf.variable不能解决这个问题。

    变量作用域使用tf.variable_scope和tf.get_variable完美解决了上边的这个问题。

    1. 网络层数很多,但一般结构就那么几种。我们使用tf.get_variable方法,变量会在前边加上作用域,类似于文件系统中的“/”。
    2. tf.get_variable在第二次使用某个变量时,可以用reuse=True来共享之前定义过的变量。

    ------总结自《深入理解tensorflow架构设计与实现原理》

    tf.name_scope()和tf.variable_scope()是两个作用域,一般与两个创建/调用变量的函数tf.variable() 和tf.get_variable()搭配使用。

    tf.name_scope和 variable_scope也是个作为上下文管理器的角色,下文管理器:意思就是,在这个管理器下做的事情,会被这个管理器管着。

    一.name_scope 和 variable_scope的用途:
    name_scope 和 variable_scope 主要是因为 变量共享 的需求。

    变量共享主要涉及两个函数:tf.variable() 和tf.get_variable();即就是必须要在tf.variable_scope的作用域下使用tf.get_variable()函数。这里用tf.get_variable( ) 而不用tf.Variable( ),是因为前者拥有一个变量检查机制,会检测已经存在的变量是否设置为共享变量,如果已经存在的变量没有设置为共享变量,TensorFlow 运行到第二个拥有相同名字的变量的时候,就会报错。

    两个创建变量的方式。如果使用tf.Variable() 的话每次都会新建变量。但是大多数时候我们是希望重用一些变量,所以就用到了get_variable(),它会去搜索变量名,有就直接用,没有再新建。名字域。既然用到变量名了,就涉及到了名字域的概念。通过不同的域来区别变量名,毕竟让我们给所有变量都取不同名字还是很辛苦。这就是为什么会有scope 的概念。name_scope 作用于操作,variable_scope 可以通过设置reuse 标志以及初始化方式来影响域下的变量,因为想要达到变量共享的效果, 就要在 tf.variable_scope()的作用域下使用 tf.get_variable() 这种方式产生和提取变量. 不像 tf.Variable() 每次都会产生新的变量, tf.get_variable() 如果遇到了已经存在名字的变量时, 它会单纯的提取这个同样名字的变量,如果不存在名字的变量再创建.

    举例:

    with tf.variable_scope('V1',reuse=True):  
        a1 = tf.get_variable(name='a1', shape=[1], initializer=tf.constant_initializer(1))  
        a2 = tf.Variable(tf.random_normal(shape=[2,3], mean=0, stddev=1), name='a2')  
    with tf.variable_scope('V2',reuse=True):  
        a3 = tf.get_variable(name='a1', shape=[1],initializer=tf.constant_initializer(1))  
        a4 = tf.Variable(tf.random_normal(shape=[2,3], mean=0, stddev=1), name='a2')  
        
    with tf.Session() as sess:  
        sess.run(tf.initialize_all_variables())  
        print (a1.name)  
        print (a2.name)   
        print (a3.name)   
        print (a4.name) 

    输出:

    V1/a1:0
    V1_14/a2:0
    V2/a1:0
    V2_2/a2:0  在tf.name_scope()中则没有resuse这个参数,无法实现这种操作。

    二.TensorFlow中name scope和variable scope区别
    TF中有两种作用域类型
    命名域 (name scope),通过tf.name_scope 或 tf.op_scope创建;
    变量域 (variable scope),通过tf.variable_scope 或 tf.variable_op_scope创建;
    这两种作用域,对于使用tf.Variable()方式创建的变量,具有相同的效果,都会在变量名称前面,加上域名称。

    对于通过tf.get_variable()方式创建的变量,只有variable scope名称会加到变量名称前面,而name scope不会作为前缀。例如 print(v1.name) # var1:0

    例子:

    with tf.name_scope("my_name_scope"):
        v1 = tf.get_variable("var1", [1], dtype=tf.float32) 
        v2 = tf.Variable(1, name="var2", dtype=tf.float32)
        a = tf.add(v1, v2)
        print(v1.name)
        print(v2.name) 
        print(a.name)

    输出:

    var1:0
    my_name_scope/var2:0
    my_name_scope/Add:0

    小结:name_scope不会作为tf.get_variable变量的前缀,但是会作为tf.Variable的前缀。

    with tf.variable_scope("my_variable_scope"):
        v1 = tf.get_variable("var1", [1], dtype=tf.float32)
        v2 = tf.Variable(1, name="var2", dtype=tf.float32)
        a = tf.add(v1, v2)
        print(v1.name) 
        print(v2.name)
        print(a.name) 

    输出:

    my_variable_scope/var1:0
    my_variable_scope/var2:0
    

    my_variable_scope/Add:0

    小结:在variable_scope的作用域下,tf.get_variable()和tf.Variable()都加了scope_name前缀。因此,在tf.variable_scope的作用域下,通过get_variable()可以使用已经创建的变量,实现了变量的共享。

    原文链接:https://blog.csdn.net/weixin_38698649/article/details/80099822

  • 相关阅读:
    财务对账系统设计
    工作中快速成长的10个技巧
    越来越火的"中台"是什么
    基于token的多平台身份认证架构设计
    了解Scala 宏
    Scala反射(一)
    一文学会Scala
    Scala 隐式转换及应用
    如何看MySql执行计划explain(或desc)
    sun.misc.Unsafe 详解
  • 原文地址:https://www.cnblogs.com/shixisheng/p/9831526.html
Copyright © 2011-2022 走看看