精华内容
下载资源
问答
  • vue中的scope使用详解

    2020-11-30 07:58:54
    注意:scope=”它可以取任意字符串”; 上面已经说了 scope获取到的是一个对象,是什么意思呢?我们先来看一个简单的demo就可以明白了~ 如下模板页面: <!DOCTYPE html> <html> <head> <title&...
  • 今天小编就为大家分享一篇vue template中slot-scope/scope的使用方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 主要介绍了maven依赖关系中的<scope>provided</scope>使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 在 Element UI Table 的官网上,有一个“筛选”功能,里面可以利用 slot-scope,给表格记录打标签。 关键代码为: <template slot-scope=scope> <el type=scope.row.tag>{{scope.row.tag}} 这里首先利用 slot-...
  • vue里面使用element-ui表格组件时候报错 slot-scope未定义。 原创文章 20获赞 9访问量 7105 关注 私信 展开阅读全文 作者:hi 宋
  • J-Scope V6.11

    2018-11-24 08:56:57
    J-Scope是SEGGER公司推出的,可以在目标MCU运行时,实时分析数据并图形化显示的软件。可以使用标准的SWD接口。 J-Scope可以像示波器一样显示多个变量的值,通过读取一个ELF文件,允许选择一定数量的变量可视化。你...
  • 软件介绍: J-Scope能够在MCU运行时实时分析数据并图形化显示数据,...安装后可以像示波器一样显示多个变量的值,通过读取一个ELF文件,通过J-Scope可以简单的将目标MCU连接到J-Link,并启动J-Scope实时分析数据。
  • 主要介绍了AngularJS全局scope与Isolate scope通信用法,结合格式分析了全局scope和directive本地scope相关功能、通信用法与相关注意事项,需要的朋友可以参考下
  • 项目范围说明书(Project Scope Statement)适用于各个行业的范围说明书,中英文对照标题
  • 论文写作Scope图片编辑-论文写作-Scope图片编辑.doc 论文的写作过程中常常要用到仿真结果的处理,而默认的Scope输出图像并没有菜单栏,所以需要在Command Windows中输入下面两条指令,将Scope的菜单栏显示出来,...
  • 对初次使用VisualScope虚拟示波器的人员有很大帮助,使用方法在例程内容里有详细的说明.
  • VisualScope(已破解)

    热门讨论 2013-04-22 10:58:19
    VisualScope经测试破解可用,串口可换,波特率可自己设置
  • 破解版Visualscope,包含其使用方法,飞思卡尔直立方案
  • 1. variable_scope的使用 首先,使用variable_scope可以很方便的管理get_varibale。 如何确定 get_variable 的 prefixed name? 1.1 variable scope是可以嵌套的: import tensorflow as tf with tf.variable_...

    1. variable_scope的使用

    首先,使用variable_scope可以很方便的管理get_varibale。

    如何确定 get_variable 的 prefixed name?

    1.1 variable scope是可以嵌套的:
    import tensorflow as tf
    
    with tf.variable_scope("tet1"):
        var3 = tf.get_variable("var3",shape=[2],dtype=tf.float32)
        print (var3.name)
        with tf.variable_scope("tet2"):
            var4 = tf.get_variable("var4",shape=[2],dtype=tf.float32)
            print (var4.name)

    输出:

    tet1/var3:0
    tet1/tet2/var4:0

    可以看到变量嵌套命名,类似于查找文件时一个完整的路径。

    1.2 get_varibale.name 以创建变量的 scope 作为名字的prefix

    示例1:

    import tensorflow as tf
    
    def te2():
        with tf.variable_scope("te2"):
            var2 = tf.get_variable("var2",shape=[2], dtype=tf.float32)
            print ('var2.name:',var2.name)
            def te1():
                with tf.variable_scope("te1"):
                    var1 = tf.get_variable("var1", shape=[2], dtype=tf.float32)
                return var1
            return te1() #在scope te2 内调用的
    
    res = te2()
    print ('res.name:',res.name)

    输出:

    var2.name: te2/var2:0
    res.name: te2/te1/var1:0

    示例2:

    import tensorflow as tf
    
    def te2():
        with tf.variable_scope("te2"):
            var2 = tf.get_variable("var2",shape=[2], dtype=tf.float32)
            print ('var2.name:',var2.name)
            def te1():
                with tf.variable_scope("te1"):
                    var1 = tf.get_variable("var1", shape=[2], dtype=tf.float32)
                return var1
        return te1() #在scope te2 外调用的
    
    res = te2()
    print ('res.name:',res.name)

    输出:

    var2.name: te2/var2:0
    res.name: te1/var1:0
    1.3 tf.variable_scope(“name”) 与 tf.variable_scope(scope)的区别
    import tensorflow as tf
    
    with tf.variable_scope("scope"):
        print (tf.get_variable("w",shape=[1]))#这个变量的name是 scope/w
        with tf.variable_scope("scope"):
           # 这个变量的name是 scope/scope/w,这两个变量的名字是不一样的,所以不会产生冲突
           print( tf.get_variable("w", shape=[1]) )
    
    print('........................................')
    
    with tf.variable_scope("yin"):
        print(tf.get_variable("w",shape=[1]))
        scope = tf.get_variable_scope()#这个变量的name是 yin/w
        print('scope:',scope)
        with tf.variable_scope(scope):#这种方式设置的scope,是用的外部的scope
            print(tf.get_variable("w", shape=[1]))#这个变量的name也是 yin/w,两个变量的名字一样,会报错
    <tf.Variable 'scope/w:0' shape=(1,) dtype=float32_ref>
    <tf.Variable 'scope/scope/w:0' shape=(1,) dtype=float32_ref>
    ........................................
    <tf.Variable 'yin/w:0' shape=(1,) dtype=float32_ref>
    scope: <tensorflow.python.ops.variable_scope.VariableScope object at 0x12060cd68>
    Traceback (most recent call last):
    
      File "<ipython-input-1-cb0c968e524c>", line 1, in <module>
        runfile('/Users/lilong/Desktop/tensorflow_test/tensorflow_8/variable_use.py', wdir='/Users/lilong/Desktop/tensorflow_test/tensorflow_8')
        ....
        ....
        ValueError: Variable yin/w already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:
        ...
    1.4 共享变量

    共享变量的前提是,变量的名字是一样的,变量的名字是由变量名和其scope前缀一起构成, tf.get_variable_scope().reuse_variables() 是允许共享当前scope下的所有变量。reused_variables可以看同一个节点。

    tf.get_variable_scope() :获取当前scope
    tf.get_variable_scope().reuse_variables():共享变量

    import tensorflow as tf
    
    with tf.variable_scope("level1"):
        print(tf.get_variable("w",shape=[1]))
        scope = tf.get_variable_scope()
        print('scope:',scope)
        with tf.variable_scope("level2"):
            print(tf.get_variable("w", shape=[1]))
    
    print('...................')
    
    with tf.variable_scope("level1", reuse=True): #即使嵌套的variable_scope也会被reuse
        print(tf.get_variable("w",shape=[1]))
        scope = tf.get_variable_scope()
        print('scope:',scope)
        with tf.variable_scope("level2"):
            print(tf.get_variable("w", shape=[1]))

    输出:

    <tf.Variable 'level1/w:0' shape=(1,) dtype=float32_ref>
    scope: <tensorflow.python.ops.variable_scope.VariableScope object at 0x12b470b00>
    <tf.Variable 'level1/level2/w:0' shape=(1,) dtype=float32_ref>
    ...................
    <tf.Variable 'level1/w:0' shape=(1,) dtype=float32_ref>
    scope: <tensorflow.python.ops.variable_scope.VariableScope object at 0x12b470940>
    <tf.Variable 'level1/level2/w:0' shape=(1,) dtype=float32_ref>
    1.5 tf.variable_scope有时也会处理命名冲突
    import tensorflow as tf
    
    def test(name=None):
        # 可以看出,如果只是使用default_name这个属性来创建variable_scope的时候,会处理命名冲突
        with tf.variable_scope(name, default_name="scope") as scope:
            w = tf.get_variable("w", shape=[2, 10])
    
    test()
    test()
    ws = tf.trainable_variables()
    for w in ws:
        print(w.name)

    输出:

    scope/w:0
    scope_1/w:0

    2 name_scope的使用

    2.1 在tensorflow中,有两个scope, 一个是name_scope一个是variable_scope,下面通过简单的示例说明:

    示例1:

    import tensorflow as tf
    
    with tf.name_scope("hello") as name_scope:
        arr1 = tf.get_variable("arr1", shape=[2,10],dtype=tf.float32)
        print ('h1:',name_scope)
        print ('h2:',arr1.name)
        print ("scope_name:%s " % tf.get_variable_scope().original_name_scope)

    运行:

    h1: hello/
    h2: arr1:0
    scope_name: 

    示例2:

    import tensorflow as tf;
    
    with tf.variable_scope("hello") as variable_scope:
        arr1 = tf.get_variable("arr1", shape=[2, 10], dtype=tf.float32)
    
        print ('p1:',variable_scope)      # 输出变量命令空间对象
        print ('p2:',variable_scope.name) # 打印出变量空间名字
        print ('p3:',arr1.name)           # 输出变量名:hello/arr1:0
        print ('p4:',tf.get_variable_scope().original_name_scope) # 获得原始命名空间
        print ('p6:',tf.get_variable_scope()) # 获取的就是variable_scope对象
    
        with tf.variable_scope("xixi") as v_scope2:
            print ('p7:',tf.get_variable_scope().original_name_scope)
            print ('p8:',tf.get_variable_scope()) # 获取的就是v _scope2,这是另一个命名空间
    

    输出:

    p1: <tensorflow.python.ops.variable_scope.VariableScope object at 0x12ccd4b38>
    p2: hello
    p3: hello/arr1:0
    p4: hello/
    p6: <tensorflow.python.ops.variable_scope.VariableScope object at 0x12ccd4b38>
    p7: hello/xixi/
    p8: <tensorflow.python.ops.variable_scope.VariableScope object at 0x12ccd4dd8>

    示例3:

    import tensorflow as tf
    
    with tf.name_scope("name1"):
        with tf.variable_scope("var1"):
            w = tf.get_variable("w",shape=[2])
            res = tf.add(w,[3])
    
    print (w.name)
    print (res.name)

    输出:

    var1/w:0
    name1/var1/Add:0

    variable_scopename_scope都会给op的name加上前缀
    这实际上是因为 创建 variable_scope 时内部会创建一个同名的 name_scope
    对比三个个程序可以看出:

    • name_scope对 get_variable()创建的变量 的名字不会有任何影响,而创建的op会被加上前缀.
    • tf.get_variable_scope() 返回的只是 variable_scope,不管 name_scope. 所以以后在使用tf.get_variable_scope().reuse_variables() 时可以不用管name_scope
    2.2 name_scope作用

    name_scope 是给op_name加前缀, variable_scope是给get_variable()创建的变量的名字加前缀

    典型的 TensorFlow 可以有数以千计的节点,如此多而难以一下全部看到,甚至无法使用标准图表工具来展示。为简单起见,我们为op/tensor名划定范围,并且可视化把该信息用于在图表中的节点上定义一个层级,默认情况下, 只有顶层节点会显示。
    下面这个例子使用tf.name_scope在hidden命名域下定义了三个操作:

    import tensorflow as tf
    
    with tf.name_scope('hidden') as scope:
      a = tf.constant(5, name='alpha')
      W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0), name='weights')
      b = tf.Variable(tf.zeros([1]), name='biases')
      print a.name
      print W.name
      print b.name

    输出:

    hidden/alpha 
    hidden/weights 
    hidden/biases 
    2.3 tf.name_scope(None) 有清除name scope的作用
    import tensorflow as tf
    with tf.name_scope("hehe"):
        w1 = tf.Variable(1.0)
        with tf.name_scope(None):
            w2 = tf.Variable(2.0)
    print(w1.name)
    print(w2.name)
    
    #hehe/Variable:0
    #Variable:0

    小小总结:
    1. 使用tf.Variable()的时候,tf.name_scope()和tf.variable_scope() 都会给 Variable 和 op 的 name属性加上前缀。
    2. 使用tf.get_variable()的时候,tf.name_scope()就不会给 tf.get_variable()创建出来的Variable加前缀。但是 tf.Variable() 创建出来的就会受到 name_scope 的影响

    参考:
    https://blog.csdn.net/u012436149/article/details/53018924/
    https://blog.csdn.net/u012436149/article/details/53081454

    展开全文
  • name_scope与variable_scope 详解

    千次阅读 2018-01-04 09:15:55
    name_scope 与 variable_scope详解[参考文献]:1.scope 命名方法2.name&variable scope3.tf.variable_scope和tf.name_scope的用法1.scope是干什么的顾名思义“scope”的意思是“范围”,那么name_scope和variable_...

    name_scope 与 variable_scope详解


    [参考文献]:

    1.scope 命名方法

    2.name&variable scope

    3.tf.variable_scope和tf.name_scope的用法


    1.scope是干什么的

    顾名思义“scope”的意思是“范围”,那么name_scope和variable_scope就是针对name所做的范围定义。典型的 TensorFlow 可以有数以千计的节点,在构建各op的过程中,命名要做到不重复,那么在编写程序的时候就要特别注意,例如“x”、“y”、”W”、”B”甚至“weight”等经常使用的变量/常量命名就很可能会重复,否则就要增加一个字符串来表示不同的op所属,例如在x前加train成为train_x,在x前加scan成为scan_x等等,一方面表明此变量、常量所属“范围”的标识,这个name_scope和variable_scope就是干这个事情的,另一方面是从name上保证此变量命名的唯一性。有了这个scope的存在,其中描述的变量和常量就会在机器当中自动给添加前缀描述,作为对各个变量、常量的区分。在这里的编程和以前使用C、C++不同之处就是,C/C++当中的变量名实际相当于我们这里的XXX.name()而不是XXX,计算机区分的是XXX.name()。简单说,有了scope,那么在tensorflow当中就是用op/tensor名来划定范围,实现对变量或者常量名的唯一性定义,避免冲突。

    2.scope是怎么干的

    接下来我们要分析的问题是:究竟name_scope()和variable_scope()对可以产生变量的tf.get_variable()和tf.Variable()会有什么不同?为了一探究竟,接下来做一些测试:

    2.1 tf.name_scope对tf.get_variable()的影响

    import tensorflow as tf
    
    with tf.name_scope("a_name_scope") as myscope:
        initializer = tf.constant_initializer(value=1)
        var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # var1:0
        print(sess.run(var1))   # [ 1.]
    
    var1:0
    [ 1.]
    

    [结论]:

    name_scope()没有对 tf.get_variable()产生的变量增加“范围”。于是,如果再有相同的变量名生成,即便name_scope使用了新的名字“a_name_scope_new”,仍旧会破坏“唯一性”,从而导致出错“该变量已经定义过了!”,试验一下:

    with tf.name_scope("a_name_scope_new") as myscope:
        initializer = tf.constant_initializer(value=1)
        var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    ---------------------------------------------------------------------------
    
    ValueError: Variable var1 already exists, disallowed. Did you mean to set reuse=True in VarScope? 
    

    【结论】:

    果然出错了!“Variable var1 already exists, disallowed.”,说明name_scope没有对get_variable()增加“范围”。那我现在还想生成一个新的变量var2而且要让其内容与var1相同怎么办?

    with tf.name_scope("a_name_scope") as myscope:
        #initializer = tf.constant_initializer(value=1)
        var2 = tf.get_variable(name='var2', dtype=tf.float32, initializer=var1)
        #var2=var1
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # var2:0
        print(sess.run(var2))   # [ 1.]
    var1:0
    [ 1.]
    var2:0
    [ 1.]
    

    【结论】:

    看结果,的确生成了新的变量var2。如果我不想生成新的变量var2,而只想做个变量的名称更改怎么办?注意,这里就和C、C++有不同了。
    
    with tf.name_scope("a_name_scope") as myscope:
        var3=var1
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # var1:0
        print(sess.run(var1))   # [ 1.]
        print(var3.name)        # var1:0
        print(sess.run(var3))   # [ 1.]
    var1:0
    [ 1.]
    var1:0
    [ 1.]
    

    【结论】:

    虽然有一个变量var3,但是其name和值都是与var1相同的,计算机认的是name,认为这两个是完全一样的,并不是新建,只是引用,我们可以理解为是C语言中的指针,指针的名字可以千奇百怪,但是其指向的地址内容才是其真正的归属。所以,这个变量var3你可以随时设置,不会引起重复性、唯一性的错误——“Variable var1 already exists, disallowed.”。
    

    变量的名称只是指针名,变量的name是地址

    with tf.name_scope("a_name_scope") as myscope:
        var3=var1

    【结论】:

    的确没有引起错误提示。
    

    2.2 variable_scope对get_variable的影响

    那么接着分析,既然name_scope对get_variable没有增加“范围”,那variable_scope呢?
    
    with tf.variable_scope("a_variable_scope") as myscope:
        initializer = tf.constant_initializer(value=1)
        var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # a_variable_scope/var1:0
        print(sess.run(var1))   # [ 1.]
    a_variable_scope/var1:0
    [ 1.]
    

    【结论】:variable_scope对get_variable有命名的影响

    看到var1指向的内容被新建了,其name变成了“a_variable_scope/var1:0”,也就是说对计算机而言这已经是一个新的内容了,需要一个新的内存来存储,这个和之前的var1.name = var1:0已经不是一个东西了.同时,我们想要找到之前的var1的name已经是不能够了,这个完全就是C/C++指针的意思,指针指向了一个新的内存,如果不使用一个新的指针指向旧的地址,那么就会导致旧地址的内容无法检索了。验证一下:
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # a_variable_scope/var1:0
        print(sess.run(var1))   # [ 1.]
        print(var3.name)        # var1:0
        print(sess.run(var3))   # [ 1.]
    a_variable_scope/var1:0
    [ 1.]
    var1:0
    [ 1.]
    

    【结论】: 变量名就是指针,变量的name属性是地址

    var3是前面对旧的var1的内容的指针,虽然在前面var1指向了新建的内容(a_variable_scope/var1:0),但是原有内容的指针给了var3,所以现在仍旧可以通过指针找到旧地址内容。前面看到了,使用variable_scope能够产生新的变量,即增加了“范围”标识的变量,那么这个能否再次执行产生新的变量呢?也就是说,新产生的name为(a_variable_scope/var1:0)的地址能否再次被新建?
    
    with tf.variable_scope("a_variable_scope") as myscope:
        initializer = tf.constant_initializer(value=1)
        var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    ---------------------------------------------------------------------------
    
    ValueError                                Traceback (most recent call last)
    ValueError: Variable a_variable_scope/var1 already exists, disallowed. Did you mean to set reuse=True in VarScope? 
    

    【结论】:get_variable取值的唯一性仍旧需要保证

    可见虽然variable_scope可以增加name“范围”,但是get_variable取值的唯一性仍旧需要维护,否则就会出错,你是不可以任性新建的。那我现在就是想重用此变量,我就是想更改一个变量名而已,行吗?当然行,之前我们就采用了直接变量名赋值就行了“var3=var1”,这样变量名改为了var3,但是其name仍旧是var1的name,从c理解就是,指针随便建,地址唯一不变,街道名你随便改,可是街道你不能随便拆改。那还有一种材料中介绍的方法,就是使用reuse_variables(),但是一旦重用的对象本身不存在就会报错。这里说的对象不是“指针”,而是指针地址,而且是带有variable_scope指定的“范围”的指针地址。
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # a_variable_scope/var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # var2:0
        print(sess.run(var2))   # [ 1.]
        print(var3.name)        # var1:0
        print(sess.run(var3))   # [ 1.]
    a_variable_scope/var1:0
    [ 1.]
    var2:0
    [ 1.]
    var1:0
    [ 1.]
    

    【分析】:

    看看上面三个变量,如果在 tf.variable_scope(“a_variable_scope”)下则会增加“范围”——(a_variable_scope),显然,var1是已存在的对象,而var2虽然也是有已有的地址,但是如果在 tf.variable_scope当中使用get_variable来获取则会新建一个name为:(a_variable_scope/var2:0),所以var2不能当做是已有地址的变量来被重用,否则会出错。var1是可以被重用的,因为他的确是一个已有的范围内的地址。

    with tf.variable_scope("a_variable_scope") as myscope:
        initializer = tf.constant_initializer(value=1)
        myscope.reuse_variables()
        var2 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # a_variable_scope/var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # a_variable_scope/var1:0
        print(sess.run(var2))   # [ 1.]
    
    a_variable_scope/var1:0
    [ 1.]
    a_variable_scope/var1:0
    [ 1.]
    

    **【结论】:**var1被var2重用了

    with tf.variable_scope("a_variable_scope") as myscope:
        initializer = tf.constant_initializer(value=1)
        myscope.reuse_variables()
        var2 = tf.get_variable(name='var2', shape=[1], dtype=tf.float32, initializer=initializer)    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # a_variable_scope/var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # a_variable_scope/var1:0
        print(sess.run(var2))   # [ 1.]
    ---------------------------------------------------------------------------
    
    ValueError                                Traceback (most recent call last)
    

    ValueError: Variable a_variable_scope/var2 does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=None in VarScope?

    【结论】:

    虽然var2经过重用了,但是其name是var1的,也就是(a_variable_scope/var1:0),而不是(a_variable_scope/var2:0),所以一旦重用则会因为没有这个地址而报错!同时,重用操作“myscope.reuse_variables()”在with范围内都是生效的,所以导致如果想如之前一般新建一个变量都会报错,如下:
    
    with tf.variable_scope("a_variable_scope") as myscope:
        initializer = tf.constant_initializer(value=1)
        myscope.reuse_variables()
        var2 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)    
        var7= tf.get_variable(name='var7', shape=[1], dtype=tf.float32, initializer=initializer)    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # a_variable_scope/var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # a_variable_scope/var1:0
        print(sess.run(var2))   # [ 1.]
        print(var7.name)        # a_variable_scope/var1:0
        print(sess.run(var7))   # [ 1.]
    ---------------------------------------------------------------------------
    
    ValueError                                Traceback (most recent call last)
    
    ValueError: Variable a_variable_scope/var7 does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=None in VarScope?
    

    【结论】:

    在上面var1被var2重用,这个是正确的,但是紧接着想重新新建一个就会立马报错的,说明这个重用操作“myscope.reuse_variables()”在with范围内都是生效的。如果name_scope下使用reuse_variables()则会报错。
    
    with tf.name_scope("a_name_scope") as myscope:
        initializer = tf.constant_initializer(value=1)
        myscope.reuse_variables()
        var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    
    
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # var1:0
        print(sess.run(var1))   # [ 1.]
    ---------------------------------------------------------------------------
    
    AttributeError                            Traceback (most recent call last)
    AttributeError: 'str' object has no attribute 'reuse_variables'
    

    2.3 name_scope()对variable的影响

    with tf.name_scope("a_name_scope") as myscope:    
        var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # a_name_scope/var2:0
        print(sess.run(var2))   # [ 2.]
    a_variable_scope/var1:0
    [ 1.]
    a_name_scope_5/var2:0
    [ 2.]
    

    【结论】:

    很棒!name_scope对variable有效,新增了“范围”名。那这个范围名是否与get_variable一样有唯一性?
    
    with tf.name_scope("a_name_scope") as myscope:    
        var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # a_name_scope/var2:0
        print(sess.run(var2))   # [ 2.]
    a_variable_scope/var1:0
    [ 1.]
    a_name_scope_6/var2:0
    [ 2.]
    

    【结论】:

    从上面结果看,唯一性仍旧保证了,原因是自动的将var2.name从(a_name_scope_1/var2:0)变为了(a_name_scope_2/var2:0).这里使用了“变为”这个词实际是错误的,因为根本不是变为,而是新建了一个name 为(a_name_scope_2/var2:0)的变量,这个变量和前面的那个变量的名都为var2但是name属性却是不同的。
    

    2.4 variable_scope对variable的影响

    with tf.variable_scope("my_variable_scope") as myscope:    
        var2 = tf.Variable(name='var2', initial_value=[initializer.value], dtype=tf.float32)
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # a_name_scope/var2:0
        print(sess.run(var2))   # [ 2.]
    a_variable_scope/var1:0
    [ 1.]
    my_variable_scope/var2:0
    [ 1.]
    

    【结论】:

    variable_scope对variable有效,而且从下面的运行结果看,唯一性可以得到保证,新建了一个新的变量,这点和name_scope一致。
    
    with tf.variable_scope("my_variable_scope") as myscope:    
        var2 = tf.Variable(name='var2', initial_value=[initializer.value], dtype=tf.float32)
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name)        # var1:0
        print(sess.run(var1))   # [ 1.]
        print(var2.name)        # a_name_scope/var2:0
        print(sess.run(var2))   # [ 2.]
    a_variable_scope/var1:0
    [ 1.]
    my_variable_scope_1/var2:0
    [ 1.]
    

    总结:

    [1]. name_scope 对 get_variable新建变量的name属性无影响;对variable新建变量的name属性增加了“范围”标识。

    [2]. variable_scope对get_variable新建变量的name属性和variable新建变量的name属性都增加了“范围”标识。

    [3]. get_variable新建变量如果遇见重复的name则会因为重复而报错。

    [4]. variable新建的变量如果遇见重复的name则会自动修改前缀,以避免重复出现。

    展开全文
  • javac中作用域的实现-scope

    千次阅读 2018-10-23 17:39:34
    本文我们来介绍一下javac中关于作业域的实现-Scope.该类表示Java程序中的可见性区域。Scope类是符号的容器,它提供了对给定名称的符号的有效访问。以哈希表的形式实现,具有“open addressing”和“double hashing”...

    说明

    本文我们来介绍一下javac中关于作业域的实现-Scope.该类表示Java程序中的可见性区域。Scope类是符号的容器,它提供了对给定名称的符号的有效访问。以哈希表的形式实现,具有“open addressing”和“double hashing”。作用域可以嵌套;作用域的下一个字段指向它的下一个外部范围。嵌套作用域可以共享它们的哈希表.

    该类有以下的子类:

    子类名功能
    CompoundScope代表一个类作用域添加了跟踪相关类作用域变化的能力.这允许客户端直接(因为新成员已经添加/移除到此作用域)或间接(即,因为新成员已经添加/移除到父类的 scope中)了解类作用域是否已经改变。
    DelegatedScope一个空的范围,不能放置任何东西。用于变量初始化器的作用域
    ErrorScope代表一个错误的scope
    ImportScope代表import 语句导入的scope
    StarImportScope代表static import 语句导入的scope

    接下来我们就来看一下这部分的实现

    解析

    Entry

    既然Scope是一个哈希表,那么我们就来看一下hash表中的entry是如何实现的.该类的字段如下:

    // 引用的symbol,当且仅当 this == sentinel 时 sym == null
    public Symbol sym;
    
    // 拥有同样hashcode的Entry,或者是哨兵
    private Entry shadowed;
    
    // 在同一个scope中的下一个Entry
    public Entry sibling;
    
    /** .
     *  当且仅当 this == sentinel 时 scope == null.
     *  当这个entry是在import scope中,那么这个scope就是这个entry所对应的scope(被导入的scope)
     */
    public Scope scope;
    

    构造器如下:

    public Entry(Symbol sym, Entry shadowed, Entry sibling, Scope scope) {
                this.sym = sym;
                this.shadowed = shadowed;
                this.sibling = sibling;
                this.scope = scope;
    }
    

    方法如下:

    1. next --> 返回与该条目名称相同的下一个条目,如果在该范围内未找到,则向外(即父scope)继续查找。方法如下:

      public Entry next() {
          return shadowed;
      }	
      
    2. 获得符合条件的下一个Entry.方法如下:

      public Entry next(Filter<Symbol> sf) {
          if (shadowed.sym == null || sf.accepts(shadowed.sym)) return shadowed;
          else return shadowed.next(sf);
      }
      

      其中,Filter–>作为布尔判断的简单过滤器。如果提供的元素与筛选器匹配,方法accepts将返回true。如下:

      public interface Filter<T> {
      /**
        * 如果元素满足滤波器所施加的约束,则为true
       */
      boolean accepts(T t);
      }
      
    3. isStaticallyImported -->判断该entry是否是静态导入的.如下:

      public boolean isStaticallyImported() {
              return false;
      

    }
    ```

    1. getOrigin–> origin仅用于import scope中。对于其他的scope entry来说,enclosing type 是可以用的.如下:

      public Scope getOrigin() {
              return scope;
      }
      

    Scope

    该类的字段如下:

    // 分享当前Scope的hash table的数量
    private int shared;
    
    // 下一个包围着的Scope(与此范围可以共享一个哈希表)
    public Scope next;
    
    // 当前scope所对应的Symbol
    public Symbol owner;
    
    // hash 表
    Entry[] table;
    
    // hash code 的掩码,该值总是等于table.length - 1
    int hashMask;
    
    // 一个线性列表,它还包含所有出现在相反顺序的条目(即以后的条目被推到顶部)。
    public Entry elems;
    
    // 在当前作用域中的元素的数量,包括已经被删除的element--> 哨兵
    int nelems = 0;
    
    // 当保存在该scope中的ScopeListener,当该scope中有结构变化时会进行唤醒的Listener。
    List<ScopeListener> listeners = List.nil();
    
    // 用来标识没有找打在当前作用域,同时用来表示删除的元素
    private static final Entry sentinel = new Entry(null, null, null, null);
    
    // 表初始的大小,初始大小为16
    private static final int INITIAL_SIZE = 0x10;
    
    // 代表一个空的scope
    public static final Scope emptyScope = new Scope(null, null, new Entry[]{});
    
    
    static final Filter<Symbol> noFilter = new Filter<Symbol>() {
        public boolean accepts(Symbol s) {
            return true;
        }
    };
        
    

    其中ScopeListener如下:

    public interface ScopeListener {
        public void symbolAdded(Symbol sym, Scope s);
        public void symbolRemoved(Symbol sym, Scope s);
    }
    

    Scope的构造器如下:

    // table的长度必须是2的指数倍
    private Scope(Scope next, Symbol owner, Entry[] table) {
        this.next = next;
        Assert.check(emptyScope == null || owner != null);
        this.owner = owner;
        this.table = table;
        this.hashMask = table.length - 1;
    }
    
    // 用于dup(复制)和dupUnshared(不共享的复制)的构造器
    private Scope(Scope next, Symbol owner, Entry[] table, int nelems) {
        this(next, owner, table);
        this.nelems = nelems;
    }
    
    // 创建一个scope,指定的owner,作为新创建的scope的下一个,同时有一个新的table,其长度为16
    public Scope(Symbol owner) {
        this(null, owner, new Entry[INITIAL_SIZE]);
    }
    

    接下来是各种操作,我们来看一下:

    1. dup 操作 --> 创建一个新的scope,其拥有同样的owner,新创建的scope和当前使用同一个table。

       public Scope dup() {
          return dup(this.owner);
      }
      
    2. dup 操作 在这个范围内构建一个新的范围,拥有新的拥有者,它与外部范围共享它的表。如果范围访问是堆栈式的,以避免分配新的表.

      public Scope dup(Symbol newOwner) {
          Scope result = new Scope(this, newOwner, this.table, this.nelems);
          shared++;
          return result;
      }
      
    3. dup 操作, 但是不共享table.

       public Scope dupUnshared() {
          return new Scope(this, this.owner, this.table.clone(), this.nelems);
      }
      
    4. 删除当前scope中的所有元素.

      public Scope leave() {
          Assert.check(shared == 0);
          if (table != next.table) return next; // 如果当前的table和下一个table不是共享的,则直接返回下一个scope
          // 如果是共享的,则在table中删除本scope中的东西
          while (elems != null) {
              int hash = getIndex(elems.sym.name);
              Entry e = table[hash];
              Assert.check(e == elems, elems.sym);
              table[hash] = elems.shadowed;
              elems = elems.sibling;
          }
          Assert.check(next.shared > 0);
          next.shared--;
          next.nelems = nelems;
          // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
          // new Error().printStackTrace(System.out);
          return next;
      }
      
    5. 扩容操作.

      private void dble() {
          Assert.check(shared == 0);
          Entry[] oldtable = table;
          Entry[] newtable = new Entry[oldtable.length * 2];
          for (Scope s = this; s != null; s = s.next) {
              if (s.table == oldtable) {
                  Assert.check(s == this || s.shared != 0);
                  s.table = newtable;
                  s.hashMask = newtable.length - 1;
              }
          }
          
          // 将原先scope中的元素加入到new table中
          int n = 0;
          for (int i = oldtable.length; --i >= 0; ) {
              Entry e = oldtable[i];
              if (e != null && e != sentinel) {
                  table[getIndex(e.sym.name)] = e;
                  n++;
              }
          }
          // We don't need to update nelems for shared inherited scopes,
          // since that gets handled by leave().
          nelems = n;
      }
      
    6. 插入操作,将指定的Symbol插入到当前scope中.

      public void enter(Symbol sym) {
          Assert.check(shared == 0);
          enter(sym, this);
      }
      
    7. 插入操作,将指定的Symbol插入到指定的scope中.

      public void enter(Symbol sym, Scope s) {
          enter(sym, s, s, false);
      }
      
    8. 插入操作。将指定的symbol插入到当前的scope.但是标识它是来自Scope s的,通过origin获取的.origin,staticallyImported 这两个参数是用在 import scope的

      public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
          Assert.check(shared == 0);
          if (nelems * 3 >= hashMask * 2) // 如果nelems * 3 >= hashMask * 2 则进行扩容一倍的处理
              dble();
          int hash = getIndex(sym.name); // 获取Symbol在当前scope中的操作
          Entry old = table[hash];
          if (old == null) {// 如果Symbol在当前scope中不存在,则其为sentinel,并增加nelems
              old = sentinel;
              nelems++;
          }
          // 创建Entry 添加到table中
          Entry e = makeEntry(sym, old, elems, s, origin, staticallyImported);
          table[hash] = e;
          elems = e;
      
          // 唤醒ScopeListener
          for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
              l.head.symbolAdded(sym, this);
          }
      }
      
      Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin, boolean staticallyImported) {
          return new Entry(sym, shadowed, sibling, scope);
      }
      

      那么此时有2种情况:

      1. symbol在当前scope中不存在,则此时需要创建一个Entry,其中Entry的shadowed指向哨兵, sibling指向当前的elems.创建完之后,在将elems 赋值为新创建的elems.如图:

        1
        可以从图中看出,新创建的Entry在链表中处于第一个,而sentinel则是在最后一个,这也就是为什么说elems是一个线性列表,它还包含所有出现在相反顺序的条目(即以后的条目被推到顶部)

      2. symbol所对应的hash值在当前的scope中已经有了,则此时处理的情况如下:

    2

    1. 删除操作.

       public void remove(Symbol sym) {
          Assert.check(shared == 0);
          Entry e = lookup(sym.name); // 在当前scope中查找
          if (e.scope == null) return;// 如果e为sentinel,则不进行后续处理
      
          //  从表中和shadowed list 中删除e
          int i = getIndex(sym.name);
          Entry te = table[i];
          if (te == e)
              table[i] = e.shadowed;
          else while (true) {
              if (te.shadowed == e) {
                  te.shadowed = e.shadowed;
                  break;
              }
              te = te.shadowed;
          }
      
          // 从elems中和sibling list中删除e
          te = elems;
          if (te == e)
              elems = e.sibling;
          else while (true) {
              if (te.sibling == e) {
                  te.sibling = e.sibling;
                  break;
              }
              te = te.sibling;
          }
      
          // 唤醒ScopeListener
          for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
              l.head.symbolRemoved(sym, this);
          }
      }
      

      从前面的两个图中可以看出, Entry 维护着shadowed和sibling,因此在删除时需要分别做处理

    2. 插入操作,如果不存在,才插入.

      public void enterIfAbsent(Symbol sym) {
          Assert.check(shared == 0);
          Entry e = lookup(sym.name);
          while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
          if (e.scope != this) enter(sym);
      }
      
    3. 判断指定的symbol是否在当前scope中存在.

      public boolean includes(Symbol c) {
          for (Scope.Entry e = lookup(c.name);
               e.scope == this;
               e = e.next()) {
              if (e.sym == c) return true;
          }
          return false;
      }
      
    4. 过滤操作.

      public Entry lookup(Name name) {
          return lookup(name, noFilter);
      }
      
      public Entry lookup(Name name, Filter<Symbol> sf) {
          Entry e = table[getIndex(name)];
          if (e == null || e == sentinel) // 如果Name在当前scope中不存在的话,或者e是sentinel,则返回sentinel
              return sentinel;
          while (e.scope != null && (e.sym.name != name || !sf.accepts(e.sym)))
              e = e.shadowed;
          return e;
      }
      
    5. 查找下标操作:

      int getIndex (Name name) {
          int h = name.hashCode();
          int i = h & hashMask;
          // The expression below is always odd, so it is guaranteed
          // to be mutually prime with table.length, a power of 2. 下面的表达式总是奇数,因为保证它与表的长度(2的幂)相互素数。
          // 双重散列法(Double Hashing) 必须使 h1(key) 的值和 m 互素,才能使发生冲突的同义词地址均匀地分布在整个表中,否则可能造成同义词地址的循环计算。
          int x = hashMask - ((h + (h >> 16)) << 1);
          int d = -1; // Index of a deleted item. 已删除项目的索引
          for (;;) {
              Entry e = table[i];
              if (e == null)
                  return d >= 0 ? d : i;
              if (e == sentinel) {
                  // We have to keep searching even if we see a deleted item.
                  // However, remember the index in case we fail to find the name. 我们必须继续搜索,即使我们看到一个被删除的项目。但是,如果我们找不到名称,请记住索引
                  if (d < 0)
                      d = i;
              } else if (e.sym.name == name)
                  return i;
              i = (i + x) & hashMask;
          }
      }
      

      那么什么是Double Hashing呢? 百度中的解释是这样的:

      该方法是开放地址法中最好的方法之一,它的探查序列是:
      hi=(h(key)+i*h1(key))%m 0≤i≤m-1 //即di=i*h1(key)
      即探查序列为:d=h(key),(d+h1(key))%m,(d+2h1(key))%m,…,等。
      该方法使用了两个散列函数h(key)和h1(key),故也称为双散列函数探查法。
      定义 h1(key) 的方法较多,但无论采用什么方法定义,都必须使 h1(key) 的值和 m 互素,才能使发生冲突的同义词地址均匀地分布在整个表中,否则可能造成同义词地址的循环计算。

    展开全文
  • tf.name_scope() #主要是方便参数变量的“ 分组 ”和 “ 管理 ”,主要是结合tf.Variable()一起使用 tf.variable_scope() #一方面也是可以实现变量的“ 分组 ”和“ 管理 ”,主要是结合tf.get_variable()一起使用 ...

    一、概要

    tf.name_scope()      #主要是方便参数变量的“ 分组 ”和 “ 管理 ”,主要是结合tf.Variable()一起使用

    tf.variable_scope()  #一方面也是可以实现变量的“ 分组 ”和“ 管理 ”,主要是结合tf.get_variable()一起使用

    tf.Variable()             #创建一个全新的变量,由于tf.Variable() 每次都在创建新对象,所有reuse=True 和它并没有什么关系。                                   对   于get_variable(),来说,如果已经创建的变量对象,就把那个对象返回,如果没有创建变量对象的                                       话,  就创建一个新的

    tf.get_variable()      #创建共享变量

    二、tf.name_scope()的使用

    1、tf.name_scope()结合tf.Variable() 的使用

    import tensorflow as tf
    
    with tf.name_scope('left_add'):
        a_add_left=tf.Variable(initial_value=10,name='a_add')
        b_add_left=tf.Variable(initial_value=20,name='b_add')
        c_result=tf.add(a_add_left,b_add_left,name='c_result')   #同名变量
    
    print(c_result.name)
    print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
    
    with tf.name_scope('left_add'):    
        a_add_right=tf.Variable(initial_value=30,name='a_add')
        b_add_right=tf.Variable(initial_value=40,name='b_add')
        c_result=tf.add(a_add_right,b_add_right,name='c_result') #同名变量
    
    print(c_result.name)
    print('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
    
    
    with tf.Session() as sess:
        writer=tf.summary.FileWriter('name_scope_graph',graph=sess.graph)

    运行结果为:

    left_add/c_result:0
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    left_add_1/c_result:0
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    结论:

    (1)因为name_scope的主要作用就是变量的分类与管理,即使两个name_scopede名称一样,依然没有关系,会默认为后面的增加一个序号1、2、3、。。。。依次为:eft_add 、eft_add_1、eft_add_2、eft_add_3、eft_add_4.

    (2)因为name_scope会相当于给每个区域制定一个完全不同的名字(即使名字相同,但后缀不同),所以不同的name_scope里面定义名称相同的变量完全不会有问题,因为每一个name_scope里面的变量名称会添加name_scope的名称作为前缀,如上的left_add/c_result:0  和  left_add_1/c_result:0

    如果将上面的第二个name_scope改为如下:

    with tf.name_scope('left_add/'):  #添加一个斜杠,表示name_scope名称不再逐渐递增,按原样显示

    此时显示的结果为:

    left_add/c_result:0
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    left_add/c_result_1:0
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    结论:

    (1)当name_scope按照原名称显示的时候,不同name_scope里面的同名变量又会采用“ 逐渐递增 ”的形式,如c_result_1 、c_result_2、c_result_3、c_result_3. 即总是会保证每个变量的唯一性,即不管是name_scope相同还是变量名相同,都是不会报错的。

    (2)因为name_scope的作用主要就是变量的分类管理,在编程时最好不要将每个name_scope的名称设置为相同,否则就是去了“ 分类管理 ”本身的初衷。

    2、tf.name_scope()结合tf.get_variable() 的使用

    前面的使用tf.Variable()无论是在同一个name_scope中定义同名变量,还是在不同的name_scope中定义同名变量,都不会出错,因为tf.Variable()创建的是以全新的变量,不是共享的,故而名称会以序号的形式“ 逐渐递增 ”,但是与tf.get_variable() 的使用就不一样了,因为tf.get_variable() 时创建的 共享变量。

    (1)在name_scope中使用tf.get_variable() 创建不同名的变量,如下:

    import tensorflow as tf
    
    with tf.name_scope('name_scope_1'):
        var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
        var2 = tf.get_variable(name='var2', shape=[1], dtype=tf.float32)  #不同名
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name, sess.run(var1))
        print(var2.name, sess.run(var2))

    输出结果为:

    var1:0 [-1.5012715]
    var2:0 [-0.37785244]

    以为本来名称就不同,故而不会错误。而且我们发现,他不显示name_scope的前缀了。

    (2)在name_scope中使用tf.get_variable() 创建同名的变量,如下:

    import tensorflow as tf
    
    with tf.name_scope('name_scope_1'):
        var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
        var2 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)  #同名
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        print(var1.name, sess.run(var1))
        print(var2.name, sess.run(var2))

    运行结果:Variable var1 already exists, disallowed.

    总结:可以在name_scope创建同名的非共享变量,但是不能创建同名的共享变量。如果要创建同名的共享变量,该怎么办呢?

                则使用tf.get_variable()和tf.variable_scope()相结合

    三、tf.variable_scope()的使用

    如下面的代码:

    
    import tensorflow as tf
    
    with tf.variable_scope('variable_scope') as scope:
        var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
        print(var1.name)
    
        scope.reuse_variables()  # 设置共享变量
    
        var1 = tf.get_variable(name='var1')
        print(var1.name)
    
        var2 = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32)
        print(var2.name)
    
        var2 = tf.Variable(initial_value=[2.], name='var2', dtype=tf.float32)
        print(var2.name)

    打印结果如下:

    variable_scope/var1:0
    variable_scope/var1:0
    variable_scope/var2:0
    variable_scope/var2_1:0

    结论:从上面的例子可以看出,在同一个variable_scope里面,可以丁一两个两个完全同名的变量var1,即使变量名称和属性name的名称完全一样,依然不会出错,因为使用tf.get_variable()创建的是共享变量。当然使用tf.Vriable()自然没有问题,因为它创建的本身就是完全不一样的变量,依然会遵循前面的变量名按顺序逐渐递增的形式。

    (1)使用同名变量是要进行相关的设置的。下面会有几种方式:

          方式一:scope.reuse_variables()   # 设置共享变量

          方式二:

    with tf.variable_scope('foo') as foo_scope:
        v = tf.get_variable('v', [1])
    with tf.variable_scope('foo', reuse=True):  #设置相同名称的foo,
        v1 = tf.get_variable('v')
    assert v1 == v

          方式三:

    with tf.variable_scope('foo') as foo_scope:
        v = tf.get_variable('v', [1])
    with tf.variable_scope(foo_scope, reuse=True):  #直接指定前面的那个variable_scope
        v1 = tf.get_variable('v')
    assert v1 == v

    四、总结

    不管是在name_scope还是在variable_scope里面,tf.Variable()的作用都是一样的;但是tf.get_variable()并不是不能在name_scope里面使用,创建非同名变量(注意这里的非同名指的是name指定的名称不一样)依然是可以的,只是不能创建同名变量;要创建共享变量,需要将variable_scope和tf.get_variable()结合起来使用。如下:

    tf.get_variable()可以重新使用一个已经存在的同名变量或者重新创建一个新的变量。比如:

    a = tf.get_variable(name='v', shape=[1])

    在Python中这个变量保存为a,而在TensorFlow中这个变量保存为v。如果进一步定义变量b

    b = tf.get_variable(name='v', shape=[1])
    # ValueError: Variable v already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:
    

    出现这个错误的原因在于,在使用TensorFlow中一个已经定义的变量时,需要申明reuse。为了重复使用tf.get_variable()定义的变量,必须在variable_scope中声明reuse

    with tf.variable_scope('one'):
        a = tf.get_variable('v', [2])
    with tf.variable_scope('one', reuse=True):
        c = tf.get_variable('v', [2])

    即创建名称name同为 “v” 的变量,需要使用tf.variable_scope(reuse=True),而且需要指定reuse参数为True。

     

    展开全文
  • 如何部署WeaveScope

    千次阅读 2018-11-16 15:53:42
    Weave Scope这个项目会自动生成容器之间的关系图,方便理解容器之间的关系,也方便监控容器化和微服务化的应用。 可以实时了解Docker容器的状态。 一、 wget https://git.io/scope 此时提示错误: ERROR: cannot...
  • Maven中optional和scope元素的使用,你弄明白了?

    千次阅读 多人点赞 2020-12-02 07:10:23
    在梳理项目的过程中发现很多开发同学对Maven依赖文件的配置并不了解,特别是对Maven的optional元素和scope元素的使用也非常随意。这就会导致发布的jar包或war包非常“胖”、编译速度慢,而且还很容易生产jar冲突等...
  • 前言:整理name_scope与variable_scope是因为自己在学习的过程中碰到的一些疑惑,后来看书和网上的一些解释。故这里做一些学习记录。 1、大体的认识 tf.name_scope()和tf.variable_scope()是两个作用域,一般与两...
  • scope参数错误或没有scope权限

    千次阅读 2020-11-24 18:11:26
    4.scope参数顺序不对 经过验证,确定是服务号,参数也正确,但是在查看网页授权回调域名的时候发现没有回调。再次发现后得出的结论是网页授权回调没有域名填写。 然后设置了网页授权回调域名 ...
  • tf.name_scope用法

    千次阅读 2020-08-28 09:57:33
    tf.name_scope:用于定义Python op的上下文管理器。 tf.name_scope( name ) 此上下文管理器将推送名称范围,这将使在其中添加的所有操作的名称带有前缀。 例如,定义一个新的Python opmy_op: def my_op(a, b...
  • Maven scope与 Gradle scope

    2020-09-24 13:03:27
    Maven与Gradle依赖项scope Maven和Gradle对依赖项的scope有所不同。在Maven世界中,一个依赖项有6种scope而gradle的scope 一直在优化调整优化。 maven scope属性 依赖范围控制哪些依赖在哪些classpath 中可用,哪些...
  • JavaScript中scope介绍

    万次阅读 多人点赞 2017-11-18 11:26:16
    摘要: 这篇文章旨在帮助那些在听说过诸如域(scope),闭包(closure),关键字this,命名空间(namespace),函数域(function scope),全局域(global scope),词法作用域(lexical scope)以及公共域和私有域...
  • 微信开放平台:Scope 参数错误或没有 Scope 权限微信开放平台:Scope 参数错误或没有 Scope 权限背景名词参考问题展示排查过程1:Scope参数错了?2:权限不够?结束: 微信开放平台:Scope 参数错误或没有 Scope ...
  • VUE的插槽(slot和slot-scope

    万次阅读 多人点赞 2019-05-23 11:59:58
    在之前的获取当前行数据中,最终的方案是使用了slot-scope="scope"的方式获取了当前行的数据,当时对slot-scope是个什么东东不了解。这两天查看了好多资料,有点明白了这个插槽是个什么东西。但是理解的不深,可能有...
  • 充分理解 name_scope 和 variable_scope

    千次阅读 2018-01-23 16:10:17
    之前写过一个例子了: TensorFlow入门(四) name / variable_scope 的使用 但是当时其实还对 name / variable_scope 不是非常理解。 * 起因:在运行 RNN LSTM 实例代码的时候出现 ValueError。 *  在 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 683,185
精华内容 273,274
关键字:

scope