A1-1 Python与PyTorch基础
课程《Deep Learning for Computer Vision》的作业1-1部分。
PyTorch official tutorials
Tensor相关知识
- 张量 (tensor) 是一种类似于数组的多维数据结构,具有以下性质
- 所有元素数据类型相同
- 通过元组索引,例如对于二维张量,可以通过
(i, j)
索引 - 张量的秩(rank)可以描述其的维度,可通过
x.dim()
获取 - 张量的形状(shape)可以描述每一维的大小,可通过
x.shape
获取
Tensor常用方法
.item()
将PyTorch标量转化为Python标量
张量生成
torch.tensor([])
通过列表生成相应的tensortorch.zeros(*size)
生成一个指定形状的tensor,元素全为0,如x = torch.zeros(1, 2)
torch.ones(*size)
生成一个指定形状的tensor,元素全为1torch.eye(x)
生成一个$x$维的单位矩阵torch.rand(*size)
生成一个指定形状的tensor,元素为$[0,1)$内的随机值torch.full(size, fill_value)
生成一个指定形状的tensor,填充元素为fill_value
torch.arange(start, end, step)
生成一个大小为$\lceil \frac{end-start}{step} \rceil$的一维tensor,元素为$[start, end)$中从start开始,步长为step遍历到的数(与python range()
类似)
上述方法不止这几个参数,比如还可以通过
dtype=...
指定数据类型,更多参数见官方教程
数据类型
如果创建tensor时有混合数据类型,PyTorch 会自动将所有元素转换为同一数据类型,通常是类型转换到更高精度的数据类型。.dtype
获得tensor的数据类型.to(type)
把tensor转换为type
指定的数据类型,例如x.to(torch.float32)
.float() .double() ...
直接把tensor转换为相应的数据类型torch.zeros_like(x)
创建一个与x具有相同形状和数据类型,但所有元素均为0的tensorx.new_zeros(*size)
创建一个与x具有相同类型,大小为size,全为0的tensor
张量索引
可以直接使用中括号索引,如对于二维张量x[0, 1]
,逗号用于分隔不同维度的索引
切片索引
对于每一维,均可以用start:stop:step
的形式进行切片,分割出需要的部分,区间范围为$[start,stop)$,索引可以为负数,表示从后向前数第几个元素
a = torch.tensor([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
,a[1, :]
的结果为tensor([5, 6, 7, 8]) torch.Size([4])
, 而a[1:2, :]
的结果为tensor([[5, 6, 7, 8]]) torch.Size([1, 4])
.clone()
来生成切片后数据的副本。整数索引
tensor也可以通过索引数组进行索引,例如
a = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
idx1 = [0, 1, 2]
idx2 = [0, 0, 2, 1, 1]
那么
a[idx1, idx1] = tensor([1, 6, 11])
a[idx2] = tensor([[ 1, 2, 3, 4],
[ 1, 2, 3, 4],
[ 9, 10, 11, 12],
[ 5, 6, 7, 8],
[ 5, 6, 7, 8]])
即如果使用数组索引,那么数组会遍历其中的每一个值,并组合成一个张量
布尔索引
布尔掩码:一个形状与目标张量相同的布尔型张量,表示对应元素是否满足某个条件。通过布尔掩码可以选择出目标张量中满足某条件的元素。例如:
a = torch.tensor([[1, 2], [3, 4], [5, 6]])
mask = (a > 3)
mask = tensor([[False, False],
[False, True],
[ True, True]])
a[mask] = tensor([4, 5, 6])
a[a <= 3] = 0
reshape操作
.view(*size)
把目标张量重塑为size对应的形式, 例如
x0 = torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]])
x0.view(8) = tensor([1, 2, 3, 4, 5, 6, 7, 8])
x0.view(1, 8) = tensor([[1, 2, 3, 4, 5, 6, 7, 8]])
若在.view()
参数中设置某一维大小设置为-1,则这一维的元素数量可以无限增加,保证输出张量与输入张量有相同的元素数量
.view()
得到的张量也与原张量共享同一片内存空间,修改一个也会同时修改另一个.t()
用于对目标张量作转置,既可以作为torch模块的函数,也可以作为张量实例的方法,如x.t()
和torch.t(x)
均可。
.transpose()
交换张量的两个维度,如把torch.Size([1, 2, 3])
变成torch.Size([1, 3, 2])
, 参数为要交换的两个维度的索引.
.permute()
对张量的维度进行重新排列,参数为对应维度索引按重排后的顺序排列
.view()
前面使用.contiguous()
或用.reshape()
代替.view()
来解决张量计算
Elementwise operations
一些基本的数学函数,如x + y
与torch.add(x, y)
与x.add(y)
相同,可以把两张量对应元素相加,sub, mul, div, pow同理
还有.sqrt().sin().cos()
等,详见文档
Reduction operations
对张量的整体或一部分进行操作。
.sum()
求和。可以通过参数dim=...
指定要求和的维度索引,该索引对应的维度在求和后会消失。
还有.min().max()
等,详见文档。
还有一些操作,如min()
,不止有一个返回值,min()
同时返回最小值和在对应维度中的索引,均为张量类型,可以用col_min_vals, col_min_idxs = x.min(dim=0)
来获取其返回值。
通常情况下,在对tensor的指定维度进行操作后,返回的张量shape中该维会消失,若设置参数keepdim=True
,则不会消失,对应维度会变成一维。
Matrix operations
一些用于计算矩阵和向量积的函数
torch.dot()
计算向量内积torch.mm()
计算两矩阵的积torch.mv()
计算矩阵和向量的积torch.addmm() / torch.addmv()
计算积,可以加上一个biastorch.bmm() / torch.baddmm()
mm和addmm的batch版本,可以批量处理torch.matmul()
更通用的张量乘法函数,会根据输入张量类型自动选择相应的处理方式
Broadcasting
PyTorch的broadcast机制可以让具有不同形状的张量进行运算,在运算时会自动拓展一些张量的结构使它们能够满足计算的要求,例如
x = torch.tensor([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = torch.tensor([1, 0, 1])
y = x + v
此时, v
会自动被拓展为tensor([[1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1]])
在GPU上运行
PyTorch支持使用GPU加速张量操作。与dtype
一样,每个张量也有一个device
属性,来表示它在什么设备上,通常有CPU和GPU。
torch.cuda.is_available()
检查GPU是否可用.to()
还可以更改张量所在的设备,如x.to('cuda')
x.to('cpu')
.cuda() .cpu()
直接更改张量所在设备
在GPU上计算可以快很多!