2016-11-29 114 views
11

首先,我知道有一个相关问题已被问到hereTensorFlow变量和TensorFlow张量之间的实现差异

但是,这个问题是关于实现和内部。 我在读报纸“A Tour of TensorFlow”。以下两点是从那里报价:

1.

张量本身并不在内存中保留或存储值,但提供 只有一个接口,用于检索由张量参考值。

这表明对我来说张量是一个对象,它只是存储指向操作结果的指针,并且在检索张量的结果或值时,它只是取消引用该指针。

2.

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

在此我感到困惑,因为我认为,基于前面的观点,张量器只是简单地存储一个指针。如果它们只是指针,它们也可以是可变的。

准确地说这是我的问题:

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

回答

34

在解释张量和变量之间的区别,我们应该得到准确的这个词是什么“张量”在TensorFlow的上下文中表示:

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

    在此上下文中,“符号结果”比指向操作结果的指针更复杂。它更类似于函数对象,它在被调用时(即传递给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的解释,这个词的“把手”在几个不同的方式,这是从TensorFlow如何使用期限略有不同使用。本文使用“符号句柄”来指代对象,而“持久可变句柄”指的是对象tf.Variable。 TensorFlow代码库使用“句柄”来引用有状态对象的名称(如tf.FIFOQueuetf.TensorArray),该名称可以在不复制所有值的情况下传递(即)。

  3. 是我关于内部的张量的初始假设是正确的?

    你的假设最为接近的(C++)tensorflow::Tensor对象的定义。 (Python)tf.Tensor对象更为复杂,因为它指的是计算值的函数,而不是值本身。

  4. 是什么张量和可变的本质内部实行区别?

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

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

    为什么他们声明不同,为什么这种差异对TensorFlow至关重要?

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

+0

这是一个非常翔实的解释和感谢它。 如果我理解正确,张量的只读状态很有用,因为它们用于表示对模型的最终状态不感兴趣的中间操作。 这就是为什么我们将卷积参数的内核存储为tf.Variable,以便稍后可以在更新期间写入并稍后存储的原因? – Ujjwal