Python TensorFlow 中 Variable 和 get_variable 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37098546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:51:16  来源:igfitidea点击:

Difference between Variable and get_variable in TensorFlow

pythontensorflow

提问by Lifu Huang

As far as I know, Variableis the default operation for making a variable, and get_variableis mainly used for weight sharing.

据我所知,Variable是创建变量的默认操作,get_variable主要用于权重共享。

On the one hand, there are some people suggesting using get_variableinstead of the primitive Variableoperation whenever you need a variable. On the other hand, I merely see any use of get_variablein TensorFlow's official documents and demos.

一方面,有些人建议在需要变量时使用get_variable而不是原始Variable操作。另一方面,我只get_variable在 TensorFlow 的官方文档和演示中看到任何使用。

Thus I want to know some rules of thumb on how to correctly use these two mechanisms. Are there any "standard" principles?

因此我想知道一些关于如何正确使用这两种机制的经验法则。是否有任何“标准”原则?

采纳答案by Lukasz Kaiser

I'd recommend to always use tf.get_variable(...)-- it will make it way easier to refactor your code if you need to share variables at any time, e.g. in a multi-gpu setting (see the multi-gpu CIFAR example). There is no downside to it.

我建议始终使用tf.get_variable(...)——如果您需要随时共享变量,例如在多 GPU 设置中(请参阅多 GPU CIFAR 示例),它将使重构代码变得更加容易。它没有任何缺点。

Pure tf.Variableis lower-level; at some point tf.get_variable()did not exist so some code still uses the low-level way.

tf.Variable是低级的;在某些时候tf.get_variable()不存在所以一些代码仍然使用低级方式。

回答by Sung Kim

tf.Variable is a class, and there are several ways to create tf.Variable including tf.Variable.__init__and tf.get_variable.

tf.Variable 是一个类,有多种创建 tf.Variable 的方法,包括tf.Variable.__init__tf.get_variable

tf.Variable.__init__: Creates a new variable with initial_value.

tf.Variable.__init__: 创建一个具有initial_value的新变量。

W = tf.Variable(<initial-value>, name=<optional-name>)

tf.get_variable: Gets an existing variable with these parameters or creates a new one. You can also use initializer.

tf.get_variable: 使用这些参数获取现有变量或创建一个新变量。您也可以使用初始化程序。

W = tf.get_variable(name, shape=None, dtype=tf.float32, initializer=None,
       regularizer=None, trainable=True, collections=None)

It's very useful to use initializers such as xavier_initializer:

使用初始化器非常有用,例如xavier_initializer

W = tf.get_variable("W", shape=[784, 256],
       initializer=tf.contrib.layers.xavier_initializer())

More information here.

更多信息在这里

回答by Jadiel de Armas

I can find two main differences between one and the other:

我可以找到一个和另一个之间的两个主要区别:

  1. First is that tf.Variablewill always create a new variable, whereas tf.get_variablegets an existingvariable with specified parameters from the graph, and if it doesn't exist, creates a new one.

  2. tf.Variablerequires that an initial value be specified.

  1. 首先,它tf.Variable总是会创建一个新变量,而从图中tf.get_variable获取具有指定参数的现有变量,如果它不存在,则创建一个新变量。

  2. tf.Variable要求指定初始值。

It is important to clarify that the function tf.get_variableprefixes the name with the current variable scope to perform reuse checks. For example:

重要的是要澄清该函数tf.get_variable在名称前加上当前变量范围以执行重用检查,这一点很重要。例如:

with tf.variable_scope("one"):
    a = tf.get_variable("v", [1]) #a.name == "one/v:0"
with tf.variable_scope("one"):
    b = tf.get_variable("v", [1]) #ValueError: Variable one/v already exists
with tf.variable_scope("one", reuse = True):
    c = tf.get_variable("v", [1]) #c.name == "one/v:0"

with tf.variable_scope("two"):
    d = tf.get_variable("v", [1]) #d.name == "two/v:0"
    e = tf.Variable(1, name = "v", expected_shape = [1]) #e.name == "two/v_1:0"

assert(a is c)  #Assertion is true, they refer to the same object.
assert(a is d)  #AssertionError: they are different objects
assert(d is e)  #AssertionError: they are different objects

The last assertion error is interesting: Two variables with the same name under the same scope are supposed to be the same variable. But if you test the names of variables dand eyou will realize that Tensorflow changed the name of variable e:

最后一个断言错误很有趣:同一个作用域下的两个同名变量应该是同一个变量。但是,如果你测试变量的名字de你会发现,Tensorflow改变变量的名称e

d.name   #d.name == "two/v:0"
e.name   #e.name == "two/v_1:0"

回答by Lerner Zhang

Another difference lies in that one is in ('variable_store',)collection but the other is not.

另一个区别在于,一个在('variable_store',)收藏中,而另一个不在。

Please see the source code:

请查看源代码

def _get_default_variable_store():
  store = ops.get_collection(_VARSTORE_KEY)
  if store:
    return store[0]
  store = _VariableStore()
  ops.add_to_collection(_VARSTORE_KEY, store)
  return store

Let me illustrate that:

让我举例说明:

import tensorflow as tf
from tensorflow.python.framework import ops

embedding_1 = tf.Variable(tf.constant(1.0, shape=[30522, 1024]), name="word_embeddings_1", dtype=tf.float32) 
embedding_2 = tf.get_variable("word_embeddings_2", shape=[30522, 1024])

graph = tf.get_default_graph()
collections = graph.collections

for c in collections:
    stores = ops.get_collection(c)
    print('collection %s: ' % str(c))
    for k, store in enumerate(stores):
        try:
            print('\t%d: %s' % (k, str(store._vars)))
        except:
            print('\t%d: %s' % (k, str(store)))
    print('')

The output:

输出:

collection ('__variable_store',): 0: {'word_embeddings_2': <tf.Variable 'word_embeddings_2:0' shape=(30522, 1024) dtype=float32_ref>}

collection ('__variable_store',): 0: {'word_embeddings_2': <tf.Variable 'word_embeddings_2:0' shape=(30522, 1024) dtype=float32_ref>}