1.Tensor的创建与维度查看
查看Tensor中的元素总个数,可使用Tensor.numel()或者Tensor.nelement()函数,两者等价。
2.Tensor的组合与分块
组合操作是指将不同的Tensor叠加起来,主要有torch.cat()和torch.stack()两个函数。cat即concatenate的意思,是指沿着已有的数据的某一维度进行拼接,操作后数据的总维数不变,在进行拼接时,除了拼接的维度之外,其他维度必须相同。而torch.stack()函数指新增维度,并按照指定的维度进行叠加。
# 创建两个2×2的Tensor
>>> a=torch.Tensor([[1,2],[3,4]])
>>> a
tensor([[ 1., 2.],
[ 3., 4.]])
>>> b = torch.Tensor([[5,6], [7,8]])
>>> b
tensor([[ 5., 6.],
[ 7., 8.]])
# 以第一维进行拼接,则变成4×2的矩阵
>>> torch.cat([a,b], 0)
tensor([[ 1., 2.],
[ 3., 4.],
[ 5., 6.],
[ 7., 8.]])
# 以第二维进行拼接,则变成2x4的矩阵
>>> torch.cat([a,b], 1)
tensor([[ 1., 2., 5., 6.],
[ 3., 4., 7., 8.]])
# 以第0维进行stack,叠加的基本单位为序列本身,即a与b,因此输出[a, b],输出维度为2×2×2
>>> torch.stack([a,b], 0)
tensor([[[ 1., 2.],
[ 3., 4.]],
[[ 5., 6.],
[ 7., 8.]]])
# 以第1维进行stack,叠加的基本单位为每一行,输出维度为2×2×2
>>> torch.stack([a,b], 1)
tensor([[[ 1., 2.],
[ 5., 6.]],
[[ 3., 4.],
[ 7., 8.]]])
# 以第2维进行stack,叠加的基本单位为每一行的每一个元素,输出维度为2×2×2
>>> torch.stack([a,b], 2)
tensor([[[ 1., 5.],
[ 2., 6.]],
[[ 3., 7.],
[ 4., 8.]]])
分块则是与组合相反的操作,指将Tensor分割成不同的子Tensor,主要有torch.chunk()与torch.split()两个函数,前者需要指定分块的数量,而后者则需要指定每一块的大小,以整型或者list来表示。
>>> a=torch.Tensor([[1,2,3],[4,5,6]])
>>> a
tensor([[ 1., 2., 3.],
[ 4., 5., 6.]])
# 使用chunk,沿着第0维进行分块,一共分两块,因此分割成两个1×3的Tensor
>>> torch.chunk(a, 2, 0)
(tensor([[ 1., 2., 3.]]), tensor([[ 4., 5., 6.]]))
# 沿着第1维进行分块,因此分割成两个Tensor,当不能整除时,最后一个的维数会小于前面的
# 因此第一个Tensor为2×2,第二个为2×1
>>> torch.chunk(a, 2, 1)
(tensor([[ 1., 2.],
[ 4., 5.]]), tensor([[ 3.],
[ 6.]]))
# 使用split,沿着第0维分块,每一块维度为2,由于第一维维度总共为2,因此相当于没有分割
>>> torch.split(a, 2, 0)
(tensor([[ 1., 2., 3.],
[ 4., 5., 6.]]),)
# 沿着第1维分块,每一块维度为2,因此第一个Tensor为2×2,第二个为2×1
>>> torch.split(a, 2, 1)
(tensor([[ 1., 2.],
[ 4., 5.]]), tensor([[ 3.],
[ 6.]]))
# split也可以根据输入的list进行自动分块,list中的元素代表了每一个块占的维度
>>> torch.split(a, [1,2], 1)
(tensor([[ 1.],
[ 4.]]), tensor([[ 2., 3.],
[ 5., 6.]]))
4Tensor的索引与变形
索引操作与NumPy非常类似,主要包含下标索引、表达式索引、使用torch.where()与Tensor.clamp()的选择性索引。
>>> a = torch.Tensor([[0,1], [2, 3]])
>>> a
tensor([[ 0., 1.],
[ 2., 3.]])
# 根据下标进行索引
>>> a[1]
tensor([ 2., 3.])
>>> a[0,1]
tensor(1.)
# 选择a中大于0的元素,返回和a相同大小的Tensor,符合条件的置1,否则置0
>>> a>0
tensor([[ 0, 1],
[ 1, 1]], dtype=torch.uint8)
# 选择符合条件的元素并返回,等价于torch.masked_select(a, a>0)
>>> a[a>0]
tensor([ 1., 2., 3.])
# 选择非0元素的坐标,并返回
>>> torch.nonzero(a)
tensor([[ 0, 1],
[ 1, 0],
[ 1, 1]])
# torch.where(condition, x, y),满足condition的位置输出x,否则输出y
>>> torch.where(a>1, torch.full_like(a, 1), a)
tensor([[ 0., 1.],
[ 1, 1.]])
# 对Tensor元素进行限制可以使用clamp()函数,示例如下,限制最小值为1,最大值为2
>>> a.clamp(1,2)
tensor([[ 1., 1.],
[ 2., 2.]])
变形操作则是指改变Tensor的维度,以适应在深度学习的计算中,数据维度经常变换的需求,是一种十分重要的操作
4.Tensor的排序与取极值
>>> a=torch.randn(3,3)
>>> a
tensor([[ 1.0179, -1.4278, -0.0456],
[-1.1668, 0.4531, -1.5196],
[-0.1498, -0.2556, -1.4915]])
# 按照第0维即按行排序,每一列进行比较,True代表降序,False代表升序
>>> a.sort(0, True)[0]
tensor([[ 1.0179, 0.4531, -0.0456],
[-0.1498, -0.2556, -1.4915],
[-1.1668, -1.4278, -1.5196]])
>>> a.sort(0, True)[1]
tensor([[ 0, 1, 0],
[ 2, 2, 2],
[ 1, 0, 1]])
# 按照第0维即按行选取最大值,即将每一列的最大值选取出来
>>> a.max(0)
(tensor([ 1.0179, 0.4531, -0.0456]), tensor([ 0, 1, 0]))
5.广播机制
当一对张量满足下面的条件时,它们才是可以被“广播”的。