• tf.name_scope() 和 tf.variable_scope()


    尽管tensorflow支持 name_scope 和 Variable,但更推荐使用 variable_scope 和 get_variable,这么做方便进行变量名称管理和实现权值变量共享

    1 tf.name_scope()

    with tf.name_scope('ns1') as ns:
        ns_v1 = tf.Variable(initial_value=[1.0], name='v')
        ns_gv1 = tf.get_variable(name='v', shape=[2,3])
        ns_v2 = tf.Variable(initial_value=[1.0], name='v')
    
    print('ns_v1', ns_v1)
    print('ns_gv1', ns_gv1)
    print('ns_v2', ns_v2)
    
    ns_v1 <tf.Variable 'ns1/v:0' shape=(1,) dtype=float32_ref>
    ns_gv1 <tf.Variable 'v:0' shape=(2, 3) dtype=float32_ref>
    ns_v2 <tf.Variable 'ns1/v_1:0' shape=(1,) dtype=float32_ref>
    

    结果:在 tf.name_scope() 里边:

    • 使用 tf.Variable() 创建的变量,会自动地在 name 前面加上 scope name
    • 使用 tf.get_variable() 创建的变量,并不受 name_scope 的影响

    2 tf.variable_scope()

    with tf.variable_scope('vs1') as vs:
        vs_v1 = tf.Variable(initial_value=[1.0], name='v')
        vs_gv1 = tf.get_variable(name='v', shape=[2,3])
    
    print('vs_v1', vs_v1)
    print('vs_gv1', vs_gv1)
    
    vs_v1 <tf.Variable 'vs1/v:0' shape=(1,) dtype=float32_ref>
    vs_gv1 <tf.Variable 'vs1/v_1:0' shape=(2, 3) dtype=float32_ref>
    

    可以看到 tf.variable_scope 和 tf.name_scope 的区别:

    使用 tf.Variable() 和使用 tf.get_variable() 创建的变量,都会自动地在 name 前面加上 variable scope name

    3 reuse 实现变量共享

    在开始之前,先来看看 python 中怎么判断两个变量指向的对象是不是一样的。我们直接使用 is 关键字来判断就行了,注意不能使用 == 来判断,和 java, C++ 中不同,python 中的 == 只是判断左右两边的内容是否一致,而不是判断左右两边是不是同一个对象。

    a = [1,2,3]
    b = [1,2,3]
    c = a
    print('a is b: ', a is b)
    print('a is c: ', a is c)
    
    c[0] = 555  # 修改 c,a也会变化:因为 a 和 c 指向同一个对象
    b[1] = 666  # 修改 b, a不受影响:因为 a 和 b 指向两个不同的对象
    print('a:', a)
    print('b:', b)
    print('c:', c)
    a is b:  False
    a is c:  True
    a: [555, 2, 3]
    b: [1, 666, 3]
    c: [555, 2, 3]
    

    上面的结果显示,a 和 c 是指向内存中的同一个对象的,如果修改c的内容,a 也会一起变。而 b 虽然和 a 的内容一模一样,但是他们并不是一个对象,如果修改 b 的内容,并不会影响到 a。

    在 TensorFlow 中,我们是通过变量的 name 来区别不同的对象。 tf.variable_scope() 中的 reuse 就是是我们为了实现变量的共享。

    在上面,我们已经创建了一个 variable_scope 它的 name='vs1';在 'vs1' 里边,我们创建了一个变量:name='v'.

    with tf.variable_scope('vs1') as vs:
        vs_gv2 = tf.get_variable(name='v2', shape=[2,3])
        
    print('vs_gv2', vs_gv2)
    
    with tf.variable_scope('vs1', reuse=True) as vs:
        vs_gv3 = tf.get_variable(name='v', shape=[2,3])
        
    print('vs_gv3', vs_gv3)
    print('vs_gv3 is vs_gv1: ', vs_gv3 is vs_gv1)
    
    vs_gv2 <tf.Variable 'vs1/v2:0' shape=(2, 3) dtype=float32_ref>
    vs_gv3 <tf.Variable 'vs1/v_1:0' shape=(2, 3) dtype=float32_ref>
    vs_gv3 is vs_gv1:  True
    

    上面发现了没有,当我们要在同一个 variable_scope 下面‘定义’一个已经存在的变量 name='v' 的时候,需要设置 reuse=True,实际上两次‘定义’指向同一个内存对象。

    4 实例

    def fc(X, out_size):
        in_size = X.shape[1]
        W = tf.get_variable('weight', shape=[in_size, out_size], initializer=tf.truncated_normal_initializer())
        b = tf.get_variable('bias', shape=[out_size],initializer=tf.zeros_initializer())
        h_fc = tf.nn.relu(tf.nn.xw_plus_b(X,W,b), name='relu')
        return h_fc
    
    batch_size = 128
    feature_size = 50
    fc1_size = 64
    fc2_size = 32
    
    X_input = tf.placeholder(dtype=tf.float32, shape=[batch_size, feature_size], name='X_input')
    
    with tf.variable_scope('fc1') as vs:
        h_fc1 = fc(X_input, out_size=fc1_size)
    with tf.variable_scope('fc2') as vs:
        h_fc2 = fc(h_fc1, out_size=fc2_size)
    
    all_vars = tf.global_variables()
    for i in range(len(all_vars)):
        print('var {}:'. format(i), all_vars[i])
    
    var 0: <tf.Variable 'fc1/weight:0' shape=(50, 64) dtype=float32_ref>
    var 1: <tf.Variable 'fc1/bias:0' shape=(64,) dtype=float32_ref>
    var 2: <tf.Variable 'fc2/weight:0' shape=(64, 32) dtype=float32_ref>
    var 3: <tf.Variable 'fc2/bias:0' shape=(32,) dtype=float32_ref>
    

    在神经网络的结构定义的时候,我们应该养成比较好的习惯,在定义每个层的时候都放在一个 tf.variable_scope() 里边。

    在定义整个模型的时候,也应该把整个模型放在一个 tf.variable_scope('your_model_name') 里边,这样做有个好处就是后期你想要微调某些层或者把多个小模型联合成一个大模型的时候都可以很轻松地实现。

    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    jqGrid学习笔记(二)
    jqGrid学习笔记(一)
    MVC 无法将类型“System.Collections.Generic.List<AnonymousType#1>”隐式转换为“System.Collections.Generic.IList<Mvc3Modeltest.Models.Movie>”。存在一个显式转换(是否缺少强制转换?))
    在页面中使用Ajax.ActionLink 的一些用法
    如何在web.config中存储自定义对象
    ASP.NET_4.0_与_Entity_Framework_4-第四篇-Entity_Framework在三层架构中的使用
    ASP.NET 4.0 与 Entity Framework 4-第三篇-使用Entity Framework调用存储过程
    ASP.NET 4.0 与 Entity Framework 4-第二篇-使用Entity Framework 进行CRUD操作
    ASP.NET_4.0_与_Entity_Framework_4-第一篇-采用Model-First_开发方式创建数据库
    String.Format数字格式化输出 {0:N2} {0:D2} {0:C2}
  • 原文地址:https://www.cnblogs.com/popodynasty/p/15102772.html
Copyright © 2020-2023  润新知