预备知识及Torch基础
本节归纳总结一些常用的Torch及Tensor操作。参考torch文档时最好看英文文档,中文的文档有的参数都没写全,还需要改进
数据操作
在深度学习中,样本一般会拥有多维的特征,使用张量(Tensor)来表示样本。对于张量的简单介绍,可以看我前面的文章矩阵基础。我们主要使用Pytorch框架来进行代码的演示,在Torch中Tensor可以支持GPU运算,且支持自动微分。
Tensor一般存储在内存中,并采⽤基于CPU的计算,若需要使用GPU运算需要额外指定。
下面结合Torch文档及书中内容对常用的Tensor操作做总结:
Tensor创建
一个张量tensor可以从Python的list或序列构建。
使用torch.Tensor()可以构建一个张量,默认会构建Float32类型的张量。
从python List构建torch
可以看到torch.Tensor()会将Tensor全部改为默认类型
1 | num = [1,2,3,4] |
要将⼤小为1的张量转换为Python标量,我们可以调⽤item函数或Python的内置函数。
1 | a = torch.tensor([3.5]) |
从numpy创建
我们使用Tensor()函数转换numpy 的 array时,在CPU或GPU上执⾏操作的时候,如果Python的NumPy包也希望使⽤相同的内存块执⾏其他操作,不需要停下计算来等它。但使用from_numpy()函数时需要注意这点
1 | import numpy as np |
其他的一些常用创建Tensor函数
1 | torch.eye(3) # 创建一个对角线为1,其余位置为0的二维Tensor |
Tensor的索引、切片、连接、换位
在实际的使用中,我们会经常用到Tensor的一些运算。
连接操作
在给定维度上对输入的张量序列seq 进行连接操作
这里对Tensor的维度做个简易的解释。通过Tensor.shape可以得到Tensor的size,size中有几个数字,该Tensor就是几维。通过第0维cat,则是将第0维组合起来。size(2,3)和size(2,3)组合第0维得到size(4,3)。
注意:按照dim维cat时,必须除了该维度其余维度完全一致才可cat
1 | # torch.cat(inputs, dimension=0) → Tensor |
stack函数
切片操作
torch.chunk 将Tensor分n块
torch.split 将Tensor按照每个为n进行划分
chunk()
torch.chunk(tensor, chunks, dim=0)
在给定维度(轴)上将输入张量进行分块
-
tensor (Tensor) – 待分块的输入张量
-
chunks (int) – 分块的个数
-
dim (int) – 沿着此维度进行分块
注意:
使用chunk尽量让它可以整除
如果不能整分,会按照该维度个数除dim数向上取整去分每块,直到分完。
(官网没看到解释,点进去源码不是Python的)
是使用6/4和5/3试出的结果。dim=4并不一定会分出4个tensor
1 | a = torch.arange(8).reshape(2,4) |
split()
1 | torch.split(tensor, split_size, dim=0) |
将输入张量分割成相等形状的chunks(如果可分)。 如果沿指定维的张量形状大小不能被split_size
整分, 则最后一个分块会小于其它分块。这个没有疑问
参数:
- tensor (Tensor) – 待分割张量
- split_size (int) – 单个分块的形状大小
- dim (int) – 沿着此维进行分割
1 | a = torch.arange(12).reshape(2,6) |
squeeze和unsqueeze
在训练神经网络时,我们经常用到这两个函数,因为需要对data进行batch_size的改造。这两个操作并不会改变元素的数目(因为是去除张量中形状为1的),只会改变维度。
1 | torch.squeeze(input, dim=None, out=None) # squeeze是将该维度=1的挤压掉 |
将输入张量形状中的1
去除并返回。 如果输入是形如(A×1×B×1×C×1×D)(A×1×B×1×C×1×D),那么输出形状就为: (A×B×C×D)(A×B×C×D)
当给定dim
时,那么挤压操作只在给定维度上。例如,输入形状为: (A×1×B)(A×1×B), squeeze(input, 0)
将会保持张量不变,只有用 squeeze(input, 1)
,形状会变成 (A×B)(A×B)。
注意: 返回张量与输入张量共享内存,所以改变其中一个的内容会改变另一个。
参数:
- input (Tensor) – 输入张量
- dim (int, optional) – 如果给定,则
input
只会在给定维度挤压 - out (Tensor, optional) – 输出张量
1 | a = torch.ones((1,2,3,1,1,5)) |
我们这里使用最简单的Tensor进行辅助理解:
1 | a = torch.ones(size=(1,1)) |
Tensor中只有1个值,a=[[1]],b=[1], c=1,值没变,但每次维度都会降1
转置
torch.t 只能转置2维张量,转置其0,1维度。等价于transpose(input, 0, 1)。如果维度不等于2则抛出异常。也可以使用tensor.T
1 | torch.transpose(input, dim0, dim1, out=None) → Tensor |
返回输入矩阵input
的转置。交换维度dim0
和dim1
。 输出张量与输入张量共享内存,所以改变其中一个会导致另外一个也被修改。
参数:
- input (Tensor) – 输入张量
- dim0 (int) – 转置的第一维
- dim1 (int) – 转置的第二维
1 | a = torch.arange(6).reshape(2,3) |
索引
gather函数
引用
- Torch官方文档
- Pytorch | tensor 切分方法
- 图解gather函数