从TensorFlow
的名字就可以看出,它是由Tensor
和Flow
两个部分组成,就可以看出它们的重要性。在TensorFlow
中所有的数据都是通过张量的形式来表示,你可以把一个张量想象成一个n维的数组或列表.一个张量有一个静态类型和动态类型的维数。张量可以在图中的节点之间流通。
目录
- 一 概念
-
- 1.1 名字
- 1.2 维度(阶)
- 1.3 类型
- 二 使用
-
- 2.1 中间计算结果的引用
- 2.2 获得计算结果
一 概念
一个张量主要保存了三个属性:名字(name),维度(shape) 和 类型(type)。
1.1 名字
名字是张量的唯一标识符,它同样给出张量是如何计算出来的。计算图上每一个节点代表一个计算,计算的结果就保存在张量之中,所以张量和计算图上节点所代表的计算结果是对应的。这样张量的命名就可以通过node:src_output
的形式来给出,其中node
为节点的名称,src_output
表示当前张量来自节点的的第一个输出。比如add:0
表示计算节点add
输出的一个结果(编号从0开始)。
1.2 维度(阶)
阶是用来描述张量的维度信息,张量的阶和矩阵的阶并不是同一个概念.张量的阶(有时是关于如顺序或度数或者是n维)是张量维数的一个数量描述.比如,下面的张量(使用Python中list定义的)就是2阶.
t = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
你可以认为一个二阶张量就是我们平常所说的矩阵,一阶张量可以认为是一个向量.对于一个二阶张量你可以用语句t[i, j]来访问其中的任何元素.而对于三阶张量你可以用’t[i, j, k]'来访问其中的任何元素.
阶 | 数学实例 | 备注 | Python例子 |
---|---|---|---|
0 | 标量(scalar) | 只有大小 | s = 483 |
1 | 向量 (vector) | 有大小和方向 | v = [1.1, 2.2, 3.3] |
2 | 矩阵(matrix) | 数据表 | m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] |
3 | 3阶张量 | 数据立体 | t = [ [[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]] ] |
n | n阶 | 自己想想看 | … |
形状
TensorFlow文档中使用了三种记号来方便地描述张量的维度:阶,形状以及维数.下表展示了他们之间的关系:
阶 | 形状 | 维数 | 实例 |
---|---|---|---|
0 | [ ] | 0-D | 一个 0维张量. 一个纯量. |
1 | [ D0] | 1-D | 一个1维张量的形式[5]. |
2 | [ D0,D1] | 2-D | 一个2维张量的形式[3, 4]. |
3 | [ D0,D1,D2] | 3-D | 一个3维张量的形式 [1, 4, 3]. |
n | [ D0,D1,…Dn] | n-D | 一个n维张量的形式 [D0, D1, … Dn]. |
形状可以通过Python中的整数列表或元祖(int list或tuples)来表示,也或者用TensorShape class.
1.3 类型
除了维度,Tensors有一个数据类型属性.你可以为一个张量指定下列数据类型中的任意一个类型:
数据类型 | Python类型 | 描述 |
---|---|---|
DT_FLOAT | tf.float32 | 32 位浮点数. |
DT_DOUBLE | tf.float64 | 64 位浮点数. |
DT_INT64 | tf.int64 | 64 位有符号整型. |
DT_INT32 | tf.int32 | 32 位有符号整型. |
DT_INT16 | tf.int16 | 16 位有符号整型. |
DT_INT8 | tf.int8 | 8 位有符号整型. |
DT_STRING | tf.string | 可变长度的字节数组.每一个张量元素都是一个字节数组. |
DT_BOOL | tf.bool | 布尔型. |
DT_COMPLEX64 | tf.complex64 | 由两个32位浮点数组成的复数:实数和虚数. |
DT_QINT32 | tf.qint32 | 用于量化Ops的32位有符号整型. |
DT_QINT8 | tf.qint8 | 用于量化Ops的8位有符号整型. |
DT_QUINT8 | tf.quint8 | 用于量化Ops的8位无符号整型. |
二 使用
张量的使用主要分为两大类,第一类是对中间计算结果的引用,第二类是用来获得计算结果。
2.1 中间计算结果的引用
当一个计算包含很多中间结果时,使用张量可以大大提高代码的可读性。以下为使用张量和不使用张量记录中间结果来完成向量相加功能大代码对比。
# 使用张量记录中间结果
a = tf.constant([1.0, 2.0], name = "a")
b = tf.constant([1.0, 2.0], name = "b")
result = a + b# 直接计算向量的和,这样可读性比较差
result = tf.constant([1.0, 2.0], name = "a") + tf.constant([1.0, 2.0], name = "b")
a和b就是对常量生成这个运算结果的引用,这样在做加法时就可以直接使用这两个变量,而不需要再去生成这些常量。当计算的复杂度增加时(比如再构建深层神经网络时)通过张量来引用计算的中间结果可以使代码的可阅读性大大提高。
同时,通过张量来存储中间结果可以方便获取中间结果。比如在卷积神经网络中,卷积层或者池化层可能改变张量的维度,通过result.get_shape
函数来获取结果张量的维度信息可以免去人工计算的麻烦。
2.2 获得计算结果
当计算图构造完成之后,张量可以用来获得计算结果,也就使得到真实的数字。虽然张量本身没有存储具体的数字,但通过会话(session)就可以得到这些具体的数字。