Answers:
我建议始终使用tf.get_variable(...)
-如果您需要随时共享变量,例如在multi-gpu设置中(请参见multi-gpu CIFAR示例),它将使您更轻松地重构代码。没有不利的一面。
纯tf.Variable
是低级的。在某些时候tf.get_variable()
不存在,因此某些代码仍使用低级方式。
tf.Variable
为tf.get_variable
。那就是当我想用numpy数组初始化变量时,我找不到像使用那样干净而有效的方法tf.Variable
。您如何解决?谢谢。
tf.Variable是一个类,有多种创建tf.Variable的方法,包括tf.Variable.__init__
和tf.get_variable
。
tf.Variable.__init__
:创建一个带有initial_value的新变量。
W = tf.Variable(<initial-value>, name=<optional-name>)
tf.get_variable
:获取具有这些参数的现有变量或创建一个新变量。您也可以使用初始化程序。
W = tf.get_variable(name, shape=None, dtype=tf.float32, initializer=None,
regularizer=None, trainable=True, collections=None)
使用初始化器如xavier_initializer
:
W = tf.get_variable("W", shape=[784, 256],
initializer=tf.contrib.layers.xavier_initializer())
更多信息在这里。
Variable
实际上是指使用__init__
。既然get_variable
是如此方便,我不知道为什么最TensorFlow代码,我看到使用Variable
的替代get_variable
。在它们之间进行选择时,是否有任何约定或因素要考虑。谢谢!
tf.Variable()
我们可以将其初始化为截断正态分布中的随机值。这是我的例子w1 = tf.Variable(tf.truncated_normal([5, 50], stddev = 0.01), name = 'w1')
。这相当于什么?我如何告诉我我要截断法线?我应该做w1 = tf.get_variable(name = 'w1', shape = [5,50], initializer = tf.truncated_normal, regularizer = tf.nn.l2_loss)
吗?
tf.truncated_normal_initializer()
用来获得所需的结果。
我可以发现彼此之间的两个主要区别:
首先,tf.Variable
它将始终创建一个新变量,而从图中tf.get_variable
获取具有指定参数的现有变量,如果不存在,则创建一个新变量。
tf.Variable
要求指定一个初始值。
重要的是要阐明该函数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
最后一个断言错误很有趣:在相同范围内具有相同名称的两个变量应该是相同变量。但是,如果你测试变量的名字d
和e
你会发现,Tensorflow改变变量的名称e
:
d.name #d.name == "two/v:0"
e.name #e.name == "two/v_1:0"
d.name
和e.name
,我刚刚在张量图命名操作中遇到了这个TensorFlow文档,该文档对此进行了解释:If the default graph already contained an operation named "answer", the TensorFlow would append "_1", "_2", and so on to the name, in order to make it unique.
另一个不同之处在于 ('variable_store',)
集合中,而另一个不在。
请查看源代码:
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
让我说明一下:
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('')
输出:
collection ('__variable_store',): 0: {'word_embeddings_2': <tf.Variable 'word_embeddings_2:0' shape=(30522, 1024) dtype=float32_ref>}