在Keras中继续分配具有不同常数张量的变量时会发生什么?

时间:2019-11-16 06:44:02

标签: python tensorflow keras

环境:Keras 2.2.5,TensorFlow 1.12.0后端

我在终端中键入以下代码,注意到分配的变量名称中的数字一直在增加。由于tf 1.x使用静态图,因此我怀疑在此过程中创建的张量是否存在,直到我使用K.clear_session()重置默认图为止。我的猜测正确吗?还是垃圾收集器自动破坏了张量?

>>> import keras.backend as K
>>> a = K.constant(1.0)
>>> a = K.constant(2.0)
>>> a
<tf.Tensor 'Const_1:0' shape=() dtype=float32>
>>> b = K.constant(2.2)
>>> b
<tf.Tensor 'Const_2:0' shape=() dtype=float32>
>>> a = K.constant(222.1)
>>> a
<tf.Tensor 'Const_3:0' shape=() dtype=float32>
>>> a = K.constant(222.1)
>>> a
<tf.Tensor 'Const_4:0' shape=() dtype=float32>

2 个答案:

答案 0 :(得分:1)

  

在此过程中创建的张量将一直存在,直到我使用K.clear_session()重置默认图为止。

这在Tensorflow中是正确的,每个变量名将是唯一的。

示例:

b = K.constant(1)
print(b)
b = K.constant(1)
print(b)
K.clear_session()
b = K.constant(1)
print(b)
# output
# Tensor("Const:0", shape=(), dtype=float32)
# Tensor("Const_1:0", shape=(), dtype=float32)
# Tensor("Const:0", shape=(), dtype=float32)

尽管您可以在不同的范围内使用相同的变量名。

例子

with tf.variable_scope("scope1"):
    a = K.constant(1)
    print(a)
with tf.variable_scope("scope2"):
    a = K.constant([1,2])
    print(a)
# output
# Tensor("scope1/Const:0", shape=(), dtype=float32)
# Tensor("scope2/Const:0", shape=(2,), dtype=float32)
  

垃圾收集器会自动破坏张量吗?

没有Python垃圾收集器不会删除TensorFlow变量。您必须手动清除会话。

答案 1 :(得分:1)

您的猜测是正确的;张量是永久,直到会话被清除。简单的演示:

import tensorflow as tf
import keras.backend as K

a = K.constant(1.0)
print(a)      # Tensor("Const:0", shape=(), dtype=float32)
print(a.name) # Const:0
del a

a = K.constant(1.0)
print(a)      # Tensor("Const_1:0", shape=(), dtype=float32)

尽管del a,新张量的名称仍然增加:Const_1:0。但是,如果会话通过K.constant简单地“存储”(例如缓存)了第一次创建的内容,即使删除了先前的张量,它也会增加 name 的值怎么办?不,可以验证:

print(tf.get_default_graph().get_tensor_by_name("Const:0"))
# Tensor("Const:0", shape=(), dtype=float32)

它仍然存在。与常规Python对象不同,后者在引用计数达到零后将被删除,而Tensor对象则保持不变(图形设置了自己的引用)。要完全删除张量(和所有其他张量),您将需要两个命令:

K.clear_session()  # clear Keras graph
tf.compat.v1.reset_default_graph()  # clear TF graph

(有时是 ,但最好同时使用两者)。现在尝试访问张量:

print(tf.get_default_graph().get_tensor_by_name("Const:0"))
# KeyError: "The name 'Const:0' refers to a Tensor which does not exist. 
# The operation, 'Const', does not exist in the graph."

创建一个新的

a = K.constant(1.0)
print(a)  # Tensor("Const:0", shape=(), dtype=float32)