如何理解TensorFlow中的tensor
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何理解TensorFlow中的tensor相关的知识,希望对你有一定的参考价值。
参考技术A 基本使用使用 TensorFlow, 你必须明白 TensorFlow:
使用图 (graph) 来表示计算任务。
在被称之为 会话 (Session) 的上下文 (context) 中执行图。
使用 tensor 表示数据。
通过 变量 (Variable) 维护状态。
使用 feed 和 fetch 可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据。
综述
TensorFlow 是一个编程系统, 使用图来表示计算任务。 图中的节点被称之为 op
(operation 的缩写)。 一个 op 获得 0 个或多个 Tensor, 执行计算,
产生 0 个或多个 Tensor. 每个 Tensor 是一个类型化的多维数组。
例如, 你可以将一小组图像集表示为一个四维浮点数数组,
这四个维度分别是 [batch, height, width, channels].
一个 TensorFlow 图描述了计算的过程。 为了进行计算, 图必须在 会话 里被启动。
会话 将图的 op 分发到诸如 CPU 或 GPU 之类的 设备 上, 同时提供执行 op 的方法。
这些方法执行后, 将产生的 tensor 返回。 在 Python 语言中, 返回的 tensor 是
numpy ndarray 对象; 在 C 和 C++ 语言中, 返回的 tensor 是
tensorflow::Tensor 实例。
计算图
TensorFlow 程序通常被组织成一个构建阶段和一个执行阶段。 在构建阶段, op 的执行步骤
被描述成一个图。 在执行阶段, 使用会话执行执行图中的 op.
例如, 通常在构建阶段创建一个图来表示和训练神经网络, 然后在执行阶段反复执行图中的训练 op.
TensorFlow 支持 C, C++, Python 编程语言。 目前, TensorFlow 的 Python 库更加易用,
它提供了大量的辅助函数来简化构建图的工作, 这些函数尚未被 C 和 C++ 库支持。
三种语言的会话库 (session libraries) 是一致的。
构建图
构建图的第一步, 是创建源 op (source op)。 源 op 不需要任何输入, 例如 常量 (Constant)。 源 op 的输出被传递给其它 op 做运算。
Python 库中, op 构造器的返回值代表被构造出的 op 的输出, 这些返回值可以传递给其它
op 构造器作为输入。
TensorFlow Python 库有一个默认图 (default graph), op 构造器可以为其增加节点。 这个默认图对
许多程序来说已经足够用了。 阅读 Graph 类 文档
如何理解 TensorFlow 中的静态形状和动态形状?
【中文标题】如何理解 TensorFlow 中的静态形状和动态形状?【英文标题】:How to understand static shape and dynamic shape in TensorFlow? 【发布时间】:2016-09-02 22:25:55 【问题描述】:在TensorFlow FAQ 中,它说:
在 TensorFlow 中,张量同时具有静态(推断)形状和 动态(真实)形状。静态形状可以使用 tf.Tensor.get_shape() 方法:这个形状是从 用于创建张量的操作,可能是部分操作 完全的。如果静态形状未完全定义,则动态形状 可以通过评估 tf.shape(t) 来确定张量 t 的大小。
但我仍然不能完全理解静态形状和动态形状之间的关系。有没有例子表明它们之间的差异?谢谢。
【问题讨论】:
【参考方案1】:有时张量的形状取决于在运行时计算的值。我们来看下面的例子,其中x
被定义为一个有四个元素的tf.placeholder()
向量:
x = tf.placeholder(tf.int32, shape=[4])
print x.get_shape()
# ==> '(4,)'
x.get_shape()
的值是x
的静态形状,(4,
) 表示它是一个长度为 4 的向量。现在让我们将tf.unique()
操作应用于x
y, _ = tf.unique(x)
print y.get_shape()
# ==> '(?,)'
(?,)
表示y
是一个未知长度的向量。为什么不为人知? tf.unique(x)
返回来自x
的唯一值,而x
的值是未知的,因为它是tf.placeholder()
,所以在你输入它之前它没有值。让我们看看如果你输入两个不同的值会发生什么:
sess = tf.Session()
print sess.run(y, feed_dict=x: [0, 1, 2, 3]).shape
# ==> '(4,)'
print sess.run(y, feed_dict=x: [0, 0, 0, 0]).shape
# ==> '(1,)'
希望这清楚地表明张量可以具有不同的静态和动态形状。动态形状始终是完全定义的——它没有?
尺寸——但静态形状可以不那么具体。这就是让 TensorFlow 支持像 tf.unique()
和 tf.dynamic_partition()
这样的操作的原因,它们可以具有可变大小的输出,并用于高级应用程序。
最后,tf.shape()
op 可用于获取张量的动态形状并将其用于 TensorFlow 计算:
z = tf.shape(y)
print sess.run(z, feed_dict=x: [0, 1, 2, 3])
# ==> [4]
print sess.run(z, feed_dict=x: [0, 0, 0, 0])
# ==> [1]
这是显示两者的示意图:
【讨论】:
我可以使用带有可学习层的动态形状吗?如果我使用较小的输入,权重会怎样? 通常需要静态知道可学习参数的形状,但输入可以具有可变的批量大小。【参考方案2】:在上面的答案中定义得很好,投票赞成。我经历了更多的观察,所以我想分享一下。
tf.Tensor.get_shape(),可用于使用创建它的操作来推断输出,这意味着我们可以在不使用 sess.run()(运行操作)的情况下推断它,正如名称所暗示的,静态形状. 例如,
c=tf.random_uniform([1,3,1,1])
是一个 tf.Tensor,我们想在代码中的任何一步知道它的形状,在运行图之前,所以我们可以使用
c.get_shape()
tf.Tensor.get_shape 不能动态(sess.run())的原因是因为输出类型 TensorShape 代替 tf.tensor,输出 TensorShape 限制了 sess.run() 的使用。
sess.run(c.get_shape())
如果我们这样做,我们会收到一个错误,即 TensorShape 的类型无效,它必须是张量/操作或字符串。
另一方面,动态形状需要通过 sess.run() 运行操作来获取形状
sess.run(tf.shape(c))
输出:数组([1, 3, 1, 1])
或
sess.run(c).shape
(1, 3, 1, 1) # 元组
希望它有助于澄清 tensorflow 概念。
【讨论】:
【参考方案3】:Tensorflow 2.0 兼容答案:提及 mrry 在他的答案中指定的代码,在 Tensorflow Version 2.x (> 2.0)
中,为了社区的利益。
# Installing the Tensorflow Version 2.1
!pip install tensorflow==2.1
# If we don't Disable the Eager Execution, usage of Placeholder results in RunTimeError
tf.compat.v1.disable_eager_execution()
x = tf.compat.v1.placeholder(tf.int32, shape=[4])
print(x.get_shape())
# ==> 4
y, _ = tf.unique(x)
print(y.get_shape())
# ==> (None,)
sess = tf.compat.v1.Session()
print(sess.run(y, feed_dict=x: [0, 1, 2, 3]).shape)
# ==> '(4,)'
print(sess.run(y, feed_dict=x: [0, 0, 0, 0]).shape)
# ==> '(1,)'
z = tf.shape(y)
print(sess.run(z, feed_dict=x: [0, 1, 2, 3]))
# ==> [4]
print(sess.run(z, feed_dict=x: [0, 0, 0, 0]))
# ==> [1]
【讨论】:
有没有办法在 tensorflow 2.0 和 tf.keras中有 inferred shape 和 dynamic shape >以上是关于如何理解TensorFlow中的tensor的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 Tensorflow 2.0 中的“OperatorNotAllowedInGraphError”错误
TensorFlow SparseCategoricalCrossentropy 是如何工作的?
python/numpy/tensorflow中,对矩阵行列操作,下标是怎么回事儿?
[转] 理解CheckPoint及其在Tensorflow & Keras & Pytorch中的使用
“不推荐使用类型的同义词;在 numpy 的未来版本中,它将被理解为 (type, (1,)) / '(1,)type'。” TensorFlow 中的问题