张量、算子
- 张量(Tensor):深度学习中表示和存储数据的主要形式。在动手实践机器学习之前,需要熟悉张量的概念、性质和运算规则,以及了解飞桨中张量的各种API。
- 算子(Operator):构建神经网络模型的基础组件。每个算子有前向和反向计算过程,前向计算对应一个数学函数,而反向计算对应这个数学函数的梯度计算。有了算子,我们就可以很方便地通过算子来搭建复杂的神经网络模型,而不需要手工计算梯度。
1.2 张量
在深度学习的实践中,我们通常使用向量或矩阵运算来提高计算效率。比如w1x1+w2x2+⋯+wNxNw1x1+w2x2+⋯+wNxN的计算可以用w⊤xw⊤x来代替(其中w=[w1w2⋯wN]⊤,x=[x1x2⋯xN]⊤w=[w1w2⋯wN]⊤,x=[x1x2⋯xN]⊤),这样可以充分利用计算机的并行计算能力,特别是利用GPU来实现高效矩阵运算。
在深度学习框架中,数据经常用张量(Tensor)的形式来存储。张量是矩阵的扩展与延伸,可以认为是高阶的矩阵。1阶张量为向量,2阶张量为矩阵。如果你对Numpy熟悉,那么张量是类似于Numpy的多维数组(ndarray)的概念,可以具有任意多的维度。
张量的大小可以用形状(shape)来描述。比如一个三维张量的形状是 [2,2,5][2,2,5],表示每一维(也称为轴(axis))的元素的数量,即第0轴上元素数量是2,第1轴上元素数量是2,第2轴上的元素数量为5。
张量中元素的类型可以是布尔型数据、整数、浮点数或者复数,但同一张量中所有元素的数据类型均相同。因此我们可以给张量定义一个数据类型(dtype)来表示其元素的类型。
1.2.1 创建张量
创建一个张量可以有多种方式,如:指定数据创建、指定形状创建、指定区间创建等。
1.2.1.1 指定数据创建张量
通过给定Python列表数据,可以创建任意维度的张量。
(1)通过指定的Python列表数据[2.0, 3.0, 4.0],创建一个一维张量。
# 导入PaddlePaddle
import paddle
# 创建一维Tensor
ndim_1_Tensor = paddle.to_tensor([2.0, 3.0, 4.0])
print(ndim_1_Tensor)
Tensor(shape=[3], dtype=float32, place=CPUPlace, stop_gradient=True,
[2., 3., 4.])
(2)通过指定的Python列表数据来创建类似矩阵(matrix)的二维张量。
# 创建二维Tensor
ndim_2_Tensor = paddle.to_tensor([[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]])
print(ndim_2_Tensor)
Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
[[1., 2., 3.],
[4., 5., 6.]])
(3)同样地,还可以创建维度为3、4...N等更复杂的多维张量。
# 创建多维Tensor
ndim_3_Tensor = paddle.to_tensor([[[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]],
[[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]]])
print(ndim_3_Tensor)
Tensor(shape=[2, 2, 5], dtype=int64, place=CPUPlace, stop_gradient=True,
[[[1 , 2 , 3 , 4 , 5 ],
[6 , 7 , 8 , 9 , 10]],
[[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]]])
需要注意的是,张量在任何一个维度上的元素数量必须相等。下面尝试定义一个在同一维度上元素数量不等的张量。
# 尝试定义在不同维度上元素数量不等的Tensor
ndim_2_Tensor = paddle.to_tensor([[1.0, 2.0],
[4.0, 5.0, 6.0]])
输出结果为:
ValueError:
Faild to convert input data to a regular ndarray :
- Usually this means the input data contains nested lists with different lengths.
从输出结果看,这种定义情况会抛出异常,提示在任何维度上的元素数量必须相等。
1.2.1.2 指定形状创建
如果要创建一个指定形状、元素数据相同的张量,可以使用paddle.zeros
、paddle.ones
、paddle.full
等API。
m, n = 2, 3
# 使用paddle.zeros创建数据全为0,形状为[m, n]的Tensor
zeros_Tensor = paddle.zeros([m, n])
# 使用paddle.ones创建数据全为1,形状为[m, n]的Tensor
ones_Tensor = paddle.ones([m, n])
# 使用paddle.full创建数据全为指定值,形状为[m, n]的Tensor,这里我们指定数据为10
full_Tensor = paddle.full([m, n], 10)
print('zeros Tensor: ', zeros_Tensor)
print('ones Tensor: ', ones_Tensor)
print('full Tensor: ', full_Tensor)
zeros Tensor: Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
[[0., 0., 0.],
[0., 0., 0.]])
ones Tensor: Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
[[1., 1., 1.],
[1., 1., 1.]])
full Tensor: Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
[[10., 10., 10.],
[10., 10., 10.]])
1.2.1.3 指定区间创建
如果要在指定区间内创建张量,可以使用paddle.arange
、paddle.linspace
等API。
# 使用paddle.arange创建以步长step均匀分隔数值区间[start, end)的一维Tensor
arange