zoukankan      html  css  js  c++  java
  • tf.Variable、tf.get_variable、tf.variable_scope、tf.name_scope、random、initializer

    转自:tensorflow学习笔记(二十三):variable与get_variable

       TF.VARIABLE、TF.GET_VARIABLE、TF.VARIABLE_SCOPE以及TF.NAME_SCOPE关系

    tf.Variable与tf.get_variable()

    tf.Variable(initial_value=None, trainable=True, collections=None, validate_shape=True, 
    caching_device=None, name=None, variable_def=None, dtype=None, expected_shape=None, 
    import_scope=None)
    tf.get_variable(name, shape=None, dtype=None, initializer=None, regularizer=None, 
    trainable=True, collections=None, caching_device=None, partitioner=None, validate_shape=True, 
    custom_getter=None)

     

    区别

    使用tf.Variable时,如果检测到命名冲突,系统会自己处理。使用tf.get_variable()时,系统不会处理冲突,而会报错

    import tensorflow as tf
    w_1 = tf.Variable(3,name="w_1")
    w_2 = tf.Variable(1,name="w_1")
    print w_1.name
    print w_2.name
    #输出
    #w_1:0
    #w_1_1:0
    import tensorflow as tf
    
    w_1 = tf.get_variable(name="w_1",initializer=1)
    w_2 = tf.get_variable(name="w_1",initializer=2)
    #错误信息
    #ValueError: Variable w_1 already exists, disallowed. Did
    #you mean to set reuse=True in VarScope?

    基于这两个函数的特性,当我们需要共享变量的时候,需要使用tf.get_variable()。在其他情况下,这两个的用法是一样的

    get_variable()与Variable的实质区别

    来看下面一段代码:

    import tensorflow as tf
    
    with tf.variable_scope("scope1"):
      w1 = tf.get_variable("w1", shape=[])
      w2 = tf.Variable(0.0, name="w2")
    with tf.variable_scope("scope1", reuse=True):
      w1_p = tf.get_variable("w1", shape=[])
      w2_p = tf.Variable(1.0, name="w2")
    
    print(w1 is w1_p, w2 is w2_p)
    #输出
    #True False


    看到这,就可以明白官网上说的参数复用的真面目了。由于tf.Variable() 每次都在创建新对象,所有reuse=True 和它并没有什么关系。

    对于get_variable(),来说,如果已经创建的变量对象,就把那个对象返回,如果没有创建变量对象的话,就创建一个新的。

    random Tensor

    可用于赋值给tf.Variable()的第一个参数

    tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
    
    tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
    
    tf.random_uniform(shape, minval=0, maxval=None, dtype=tf.float32, seed=None, name=None)
    
    tf.random_shuffle(value, seed=None, name=None)
    
    tf.random_crop(value, size, seed=None, name=None)
    
    tf.multinomial(logits, num_samples, seed=None, name=None)
    
    tf.random_gamma(shape, alpha, beta=None, dtype=tf.float32, seed=None, name=None)
    
    tf.set_random_seed(seed)

    constant value tensor

    tf.zeros(shape, dtype=tf.float32, name=None)
    
    tf.zeros_like(tensor, dtype=None, name=None)
    
    tf.ones(shape, dtype=tf.float32, name=None)
    
    tf.ones_like(tensor, dtype=None, name=None)
    
    tf.fill(dims, value, name=None)
    
    tf.constant(value, dtype=None, shape=None, name='Const')

    initializer

    tf.constant_initializer(value=0, dtype=tf.float32)
    tf.random_normal_initializer(mean=0.0, stddev=1.0, seed=None, dtype=tf.float32)
    tf.truncated_normal_initializer(mean=0.0, stddev=1.0, seed=None, dtype=tf.float32)
    tf.random_uniform_initializer(minval=0, maxval=None, seed=None, dtype=tf.float32)
    tf.uniform_unit_scaling_initializer(factor=1.0, seed=None, dtype=tf.float32)
    tf.zeros_initializer(shape, dtype=tf.float32, partition_info=None)
    tf.ones_initializer(dtype=tf.float32, partition_info=None)
    tf.orthogonal_initializer(gain=1.0, dtype=tf.float32, seed=None)

    tf.Variable与tf.get_variable

    当tf.get_variable用于变量创建时,和tf.Variable的功能基本等价。

    #以下两个定义是等价的
    v = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
    v = tf.Variable(tf.constant(1.0, shape=[1], name='v')

    tf.get_varialbe和tf.Variable最大的区别在于:tf.Variable的变量名是一个可选项,通过name=’v’的形式给出。但是tf.get_variable必须指定变量名。

    tf.get_variable与tf.variable_scope

    上面已经提到过了:TensorFlow中通过变量名获取变量的机制主要是通过tf.get_variable和tf.variable_scope实现的。在这里,我主要解释下大家深恶痛绝的reuse问题。 
    其实只要记住一件事情就ok了:当reuse为False或者None时(这也是默认值),同一个tf.variable_scope下面的变量名不能相同;当reuse为True时,tf.variable_scope只能获取已经创建过的变量。 
    下面我们通过代码来看下:

    #reuse=False时会报错的情况:
    with tf.variable_scope('foo'):
        v = tf.get_variable('v',[1],initializer=tf.constant_initializer(1.0))
     
    with tf.variable_scope('foo'):
        v1 = tf.get_variable('v',[1])

    在这种情况下会报错:Variable foo/v already exists, disallowed.Did you mean to set reuse=True in Varscope? 
    其原因就是在命名空间foo中创建了相同的变量。如果我要在foo下创建一个变量v1,其name=‘v’,只需要将reuse设置为Ture就ok了。将上面第二部分代码修改为:

    with tf.variable_scope('foo', reuse=True):
        v1 = tf.get_variable('v',[1])
        print(v1.name)      #结果为foo/v

    当reuse已经设置为True时,tf.variable_scope只能获取已经创建过的变量。这个时候,在命名空间bar中创建name=‘v’的变量v3,将会报错:Variable bar/v dose not exists, diallowed. Did you mean to set reuse=None in VarScope?

    with tf.variable_scope('bar', reuse=True):
        v3 = tf.get_variable('v',[1])

    简而言之,reuse=False时,tf.variable_scope创建变量;reuse=True时,tf.variable_scope获取变量

    tf.variable_scope与tf.name_scope

    除了tf.variable_scope,tf.name_scope函数也提供了命名空间管理的功能。这两个函数在大部分情况下是等价的,唯一的区别是在使用tf.get_variable函数时。 
    tf.get_variable函数不受tf.name_scope的影响。 
    我们从代码看下这句话的具体意思。 
    首先是tf.variable_scope:

    with tf.variable_scope('foo'):
        a = tf.get_variable('bar',[1])
        print(a.name)#结果为foo/bar:0

    再看tf.name_scope:

    with tf.name_scope('a'):
        a=tf.Variable([1])
        print(a.name)#结果为a/Variable:0
     
        b=tf.get_variable('b',[1])
        print(b.name)#结果为b:0

    从这个结果中,我们能很清晰地看到,tf.get_variable创建的变量并不是a/b:0,而是b:0。这就表示了在tf.name_scope函数下,tf.get_variable不受其约束。

    我的尝试

    import tensorflow as tf
    
    tf.reset_default_graph()
    
    with tf.variable_scope('v_scope') as scope1:
        Weights1 = tf.get_variable('Weights', shape=[2,3])
    #    bias1 = tf.get_variable('bias', shape=[3])
    
    
    with tf.variable_scope('v_scope', reuse=True) as scope2:
        Weights2 = tf.get_variable('Weights')
    
    print Weights1.name
    print Weights2.name
    v_scope/Weights:0
    v_scope/Weights:0

    通过测试也发现,如果把上述的Weights1和Weights2同时放入一个variable_scope(reuse=True)当中,既创建又获取会报错:

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

  • 相关阅读:
    【转】CUDA5/CentOS6.4
    【转】centos 6.4 samba 安装配置
    【转】Install MATLAB 2013a on CentOS 6.4 x64 with mode silent
    【转】Getting xrdp to work on CentOS 6.4
    【VLFeat】使用matlab版本计算HOG
    Unofficial Windows Binaries for Python Extension Packages
    March 06th, 2018 Week 10th Tuesday
    March 05th, 2018 Week 10th Monday
    March 04th, 2018 Week 10th Sunday
    March 03rd, 2018 Week 9th Saturday
  • 原文地址:https://www.cnblogs.com/exciting/p/10701852.html
Copyright © 2011-2022 走看看