TensorFlow Variable和TensorFlow Tensor之间的实现差异

时间:2016-11-29 13:06:37

标签: tensorflow

首先,我知道有人提出了一个相关的问题here

然而,这个问题是关于实施和内部的。 我正在阅读论文“A Tour of TensorFlow”。从那里引用以下两点:

1

  

张量本身不会在内存中保存或存储值,但提供   只是一个用于检索张量引用的值的接口。

这告诉我,Tensor是一个简单地将指针存储到操作结果的对象,并且在检索张量的结果或值时,它只是取消引用该指针。

2

  

变量可以描述为存储张量的内存缓冲区的持久,可变句柄。因此,变量的特征在于某种形状和固定类型。

在此我感到困惑,因为我认为,基于前一点,Tensors只存储一个指针。如果它们只是指针,它们也可能是可变的。

准确地说,这些是我的问题:

  1. “内存缓冲区”是什么意思?
  2. “句柄”是什么意思?
  3. 我对张量内部的初步假设是正确的吗?
  4. 张量和变量之间的基本内部实现差异是什么?为什么它们的声明不同?为什么这种差异对TensorFlow来说至关重要?

1 个答案:

答案 0 :(得分:46)

在解释张量和变量之间的区别之前,我们应该准确地说明“张量”这个词在TensorFlow的背景下意味着什么:

  • Python API 中,tf.Tensor对象表示TensorFlow操作的符号结果。例如,在表达式t = tf.matmul(x, y)中,t是一个tf.Tensor对象,表示乘以xy的结果(它们本身可能是其他的符号结果)操作,具体值,如NumPy数组或变量)。

    在此上下文中,“符号结果”比指向操作结果的指针更复杂。它更类似于一个函数对象,当被调用(即传递给tf.Session.run())时,将运行必要的计算以产生该操作的结果,并将其作为具体值返回给您(例如NumPy数组)

  • C ++ API 中,tensorflow::Tensor对象表示多维数组的具体值。例如,MatMul内核将两个二维tensorflow::Tensor对象作为输入,并生成一个二维tensorflow::Tensor对象作为其输出。

这种区别有点令人困惑,如果我们重新开始,我们可能会选择不同的名称(在其他语言API中,我们更喜欢名称Output表示符号结果,Tensor表示具体值)

变量存在类似的区别。在Python API中,tf.Variable是变量的符号表示,它具有创建读取变量当前值的操作的方法,并为其赋值。在C ++实现中,tensorflow::Var对象是共享的可变tensorflow::Tensor对象的包装器。

有了这样的背景,我们可以解决您的具体问题:

  1. “内存缓冲区”是什么意思?

    内存缓冲区只是一个已分配有TensorFlow分配器的连续内存区域。 tensorflow::Tensor个对象包含指向内存缓冲区的指针,该缓冲区保存该张量的值。缓冲区可以在主机存储器中(即可从CPU访问)或设备存储器(例如只能从GPU访问),TensorFlow具有在这些存储空间之间移动数据的操作。

  2. “句柄”的含义是什么?

    the paper的解释中,“handle”一词以两种不同的方式使用,这与TensorFlow使用该术语的方式略有不同。本文使用“符号句柄”来引用tf.Tensor对象,使用“持久性,可变句柄”来引用tf.Variable对象。 TensorFlow代码库使用“句柄”来引用有状态对象的名称(如tf.FIFOQueuetf.TensorArray),可以在不复制所有值的情况下传递(即call-by-reference

  3. 我对张量内部的初步假设是正确的吗?

    您的假设与(C ++)tensorflow::Tensor对象的定义最匹配。 (Python)tf.Tensor对象更复杂,因为它引用了一个计算值的函数,而不是值本身。

  4. 张量和变量之间的基本内部实现差异是什么?

    在C ++中,tensorflow::Tensortensorflow::Var非常相似;唯一不同的是,tensorflow::Var还有一个mutex,可用于在变量更新时锁定变量。

    在Python中,本质区别在于tf.Tensor是作为数据流图实现的,它是只读的(即通过调用tf.Session.run())。可以读取tf.Variable(即通过评估其读取操作)并写入(例如通过运行分配操作)。

    为什么它们的声明不同?为什么这种差异对于TensorFlow来说至关重要?

    张量和变量用于不同的目的。张量(tf.Tensor个对象)可以表示数学表达式的复杂组合,如神经网络中的损失函数或符号渐变。变量表示随时间更新的状态,如训练期间的权重矩阵和卷积滤波器。虽然原则上你可以表示没有变量的模型的演化状态,但你最终会得到一个非常大的(并且重复的)数学表达式,因此变量提供了一种方便的方法来实现模型的状态,例如 - 分享与其他机器进行并行训练。