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
Difference between Variable and get_variable in TensorFlow
提问by Lifu Huang
As far as I know, Variable
is the default operation for making a variable, and get_variable
is mainly used for weight sharing.
据我所知,Variable
是创建变量的默认操作,get_variable
主要用于权重共享。
On the one hand, there are some people suggesting using get_variable
instead of the primitive Variable
operation whenever you need a variable. On the other hand, I merely see any use of get_variable
in 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.Variable
is 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:
我可以找到一个和另一个之间的两个主要区别:
First is that
tf.Variable
will always create a new variable, whereastf.get_variable
gets an existingvariable with specified parameters from the graph, and if it doesn't exist, creates a new one.tf.Variable
requires that an initial value be specified.
首先,它
tf.Variable
总是会创建一个新变量,而从图中tf.get_variable
获取具有指定参数的现有变量,如果它不存在,则创建一个新变量。tf.Variable
要求指定初始值。
It is important to clarify that the function tf.get_variable
prefixes 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 d
and e
you will realize that Tensorflow changed the name of variable e
:
最后一个断言错误很有趣:同一个作用域下的两个同名变量应该是同一个变量。但是,如果你测试变量的名字d
和e
你会发现,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>}