从功能的角度上看,张量可以被简单理解为多维数组。其中零阶张量表示标量( scalar ),也就是一个数,第一阶张量为向量(vector), 也就是一维数组;第n阶张量可以理解为一个n维数组。但张量在 TensorFlow 中的实现并不是直接采用数组的形式,它只是对 TensorFlow 中运算结果的引用。在张量中并没有真正保存数字,它保存的是如何得到这些数字的计算过程。
维度描述了张量的维度信息。
例子:
[1 2
3 4]的shape为[2,2]。
b.ndim #返回维数,维数类型为整数
tf.rank(b) #返回维数,维数类型为list
数值类型的张量是 TensorFlow 的主要数据载体,根据维度数来区分,可分为:
标量(Scalar)。单个的实数,如 1.2, 3.4 等,维度(Dimension)数为 0,shape 为[ ]。
向量(Vector)。个实数的有序集合,通过中括号包裹,如[1.2],[1.2,3.4]等,维度数为 1,长度不定,shape 为[]。
矩阵(Matrix)。行列实数的有序集合,如[[1,2],[3,4]],维度数为 2,每个维度上的长度不定,shape 为[, ],shape可以理解为“几行几列”。
张量(Tensor)。所有维度数dim > 2的数组统称为张量。在 TensorFlow 中间,为了表达方便,一般把标量、向量、矩阵也统称为张量,不作区分。
id 是 TensorFlow 中内部索引对象的编号。
device 是tensor所在设备的名字。
aa = tf.constant(1.2) # 创建标量
与标量不同,向量的定义须通过 List 容器传给 tf.constant()函数。例如,创建一个元素的向量:
a = tf.constant([1.2]) # 创建一个元素的向量
a = tf.constant([[1,2],[3,4]]) # 创建 2 行 2 列的矩阵
a = tf.constant([[[1,2],[3,4]],[[5,6],[7,8]]]) # 创建 3 维张量
a = tf.constant('Hello, Deep Learning.') # 创建字符串
a = tf.constant(True) # 创建布尔类型标量
a = tf.constant([True, False]) # 创建布尔类型向量
对于数值类型的张量,可以保存为不同字节长度的精度,如浮点数 3.14 既可以保存为16 位(Bit)长度,也可以保存为 32 位甚至 64 位的精度。位越长,精度越高,同时占用的内存空间也就越大。常用的精度类型有 tf.int16、tf.int32、tf.int64、tf.float16、tf.float32、tf.float64 等,其中 tf.float64 即为 tf.double。
对于大部分深度学习算法,一般使用 tf.int32 和 tf.float32 可满足大部分场合的运算精度要求,部分对精度要求较高的算法,如强化学习某些算法,可以选择使用 tf.int64 和tf.float64 精度保存张量。
在创建张量时,可以指定张量的保存精度:
tf.constant(123456789, dtype=tf.int16)
读取精度:
print('before:',a.dtype) # 读取原有张量的数值精度
数值精度转换:
tf.cast(aa,dtype=tf.float32)
为了区分需要计算梯度信息的张量与不需要计算梯度信息的张量,TensorFlow 增加了一种专门的数据类型来支持梯度信息的记录:tf.Variable。tf.Variable 类型在普通的张量类
型基础上添加了 name,trainable 等属性来支持计算图的构建。
通过 tf.Variable()函数可以将普通张量转换为待优化张量,例如:
a = tf.constant([-1, 0, 1, 2]) # 创建 TF 张量
aa = tf.Variable(a) # 转换为 Variable 类型
aa.name, aa.trainable # Variable 类型张量的属性
Out[20]:
('Variable:0', True)
其中张量的 name 和 trainable 属性是 Variable 特有的属性,name 属性用于命名计算图中的变量,这套命名体系是 TensorFlow 内部维护的,一般不需要用户关注 name 属性;trainable属性表征当前张量是否需要被优化,创建 Variable 对象时是默认启用优化标志,可以设置trainable=False 来设置张量不需要优化。除了通过普通张量方式创建 Variable,也可以直接创建,例如:
tf.cast(aa,dtype=tf.float32)
Numpy Array 数组和 Python List 列表是 Python 程序中间非常重要的数据载体容器,很 多数据都是通过 Python 语言将数据加载至 Array 或者 List 容器,再转换到 Tensor 类型,通过 TensorFlow 运算处理后导出到 Array 或者 List 容器,方便其他模块调用。
通过 tf.convert_to_tensor 函数可以创建新 Tensor,并将保存在 Python List 对象或者Numpy Array 对象中的数据导入到新 Tensor 中,例如:
tf.convert_to_tensor([1,2.]) # 从列表创建张量
tf.convert_to_tensor(np.array([[1,2.],[3,4]])) # 从数组中创建张量
需要注意的是,Numpy 浮点数数组默认使用 64 位精度保存数据,转换到 Tensor 类型时精度为 tf.float64,可以在需要的时候将其转换为 tf.float32 类型。实际上,tf.constant()和 tf.convert_to_tensor()都能够自动的把 Numpy 数组或者 Python 列表数据类型转化为 Tensor 类型。
通过 tf.zeros()和 tf.ones()即可创建任意形状,且内容全 0 或全 1 的张量。例如,创建为 0 和为 1 的标量:
In [24]: tf.zeros([]),tf.ones([]) # 创建全 0,全 1 的标量
Out[24]:
(<tf.Tensor: id=90, shape=(), dtype=float32, numpy=0.0>,
<tf.Tensor: id=91, shape=(), dtype=float32, numpy=1.0>)
tf.zeros()和 tf.ones()的参数为shape
通过 tf.zeros_like, tf.ones_like 可以方便地新建与某个张量 shape 一致,且内容为全 0 或 全 1 的张量。例如,创建与张量形状一样的全 0 张量:
In [28]: a = tf.ones([2,3]) # 创建一个矩阵
tf.zeros_like(a) # 创建一个与a形状相同,但是全0的新矩阵
Out[28]:
<tf.Tensor: id=113, shape=(2, 3), dtype=float32, numpy=
array([[0., 0., 0.],
[0., 0., 0.]], dtype=float32)>
通过 tf.fill(shape, value)可以创建全为自定义数值 value 的张量,形状由 shape 参数指定。例如,创建所有元素为 99 的矩阵:
In [32]:tf.fill([2,2], 99) # 创建 2 行 2 列,元素全为 99 的矩阵
fill(shape, value)中的shape中的值必须相等,如例子中2=2
通过 tf.random.normal(shape, mean=0.0, stddev=1.0)可以创建形状为 shape,均值为mean,标准差为 stddev 的正态分布。例如,创建均值为 0,标准差为 1
的正态分布:
In [33]: tf.random.normal([2,2]) # 创建标准正态分布的张量
In [34]: tf.random.normal([2,2], mean=1,stddev=2) # 创建正态分布的张量
通过 tf.random.uniform(shape, minval=0, maxval=None, dtype=tf.float32)可以创建采样自[minval, maxval)区间的均匀分布的张量。例如创建采样自区间[0,1),shape 为[2,2]的矩阵:
In [35]: tf.random.uniform([2,2]) # 创建采样自[0,1)均匀分布的矩阵
在循环计算或者对张量进行索引时,经常需要创建一段连续的整型序列,可以通过tf.range()函数实现。通过 tf.range(start, limit, delta=1)可以创建[start,limit),步长为 delta 的序列,不包含limit 本身:。例如,创建 0~10,步长为 1 的整型序列:
In [38]: tf.range(10) # 0~10,不包含 10
Out[38]:
<tf.Tensor: id=180, shape=(10,), dtype=int32, numpy=array([0, 1, 2, 3, 4, 5,
6, 7, 8, 9])>
tf.convert_to_tensor([1,2.]) # 从列表创建张量
tf.convert_to_tensor(np.array([[1,2.],[3,4]])) # 从数组中创建张量
标量的一些典型用途是误差值的表示、各种测量指标的表示,比如准确度(Accuracy,简称 acc),精度(Precision)和召回率(Recall)等。
向量是一种非常常见的数据载体,如在全连接层和卷积神经网络层中,偏置张量就使用向量来表示。
矩阵也是非常常见的张量类型,比如全连接层的批量输入张量的形状为[, in],其中表示输入样本的个数,即 Batch Size,in表示输入特征的长度。
三维的张量一个典型应用是表示序列信号,它的格式是 = [, sequence len, feature len]。其中表示序列信号的数量,sequence len 表示序列信号在时间维度上的采样点数或步数, feature len 表示每个点的特征长度。
四维张量在卷积神经网络中应用非常广泛,它用于保存特征图(Feature maps)数据,格式一般定义为[, ℎ, w, ],其中表示输入样本的数量,ℎ/w分别表示特征图的高/宽,表示特征图的通道数,部分深度学习框架也会使用[, , ℎ, w]格式的特征图张量,
1.TensorFlow 实战Google深度学习框架 第2版 ,郑泽宇
2.《TensorFlow深度学习》