PyTorch简单笔记
张量(tensor)基础
构造张量
- 可以从
list
构造,用[]
访问和修改,下标访问直接得到的是PyTorch Scalar
- 有
.dim()
,.shape
方法,.item()
可以将PyTorch scalar
转换为普通的python scalar
1 | # Create a two-dimensional tensor |
内置的构造
torch.zeros
: Creates a tensor of all zerostorch.ones
: Creates a tensor of all onestorch.rand
: Creates a tensor with uniform random numberstorch.eye
: 创建一个单位张量torch.empty
: 使用无用数据进行填充torch.full
: 所有元素相同的张量- 以及其他的选择 in the documentation
数据类型
- large set of numeric datatypes
- tensor的
.dtype
属性可以查看类型,也可以指定类型 - 也可以使用
.to()
,.float()
之类的方法进行类型转换
1 | # Force a particular datatype |
- 构造一些与已有tensor相同类型的tensor
1 | x0 = torch.eye(3, dtype=torch.float64) # Shape (3, 3), dtype torch.float64 |
tensor索引
切片索引
- tensor支持
[start:stop:step]
式的索引 - 切片得到的是原tensor的一个view,改变切片也会改变原tensor,规避方法是采用
.clone()
1 | # Create the following rank 2 tensor with shape (3, 4) |
似乎采用
a[[1], :]
可以得到一个新的tensor而非原tensor的view,同时形式和a[1:2, :]
类似
- 支持
a[1:3, 2: 4] = 2
形式的赋值
整型索引
使用索引数组得到全新的tensor
a[idx0, idx1]
相当于1
2
3
4
5
6torch.tensor([
a[idx0[0], idx1[0]],
a[idx0[1], idx1[1]],
...,
a[idx0[N - 1], idx1[N - 1]]
])
布尔tensor索引
- 使用一个
torch.bool
类型的mask进行索引
1 | a = torch.tensor([[1,2], [3, 4], [5, 6]]) |
改变形状
View
.view()
可以将tensor重塑形状,并返回该tensor的一个view.view(-1)
会令-1的维度大小保持和原来相同
似乎是按行展开重塑的
交换维度
.t()
直接进行转置.transpose()
选择任意两个维度进行交换.permute()
重新将维度进行排序
1 | # Create a tensor of shape (2, 3, 4) |
Contiguous
- 一串改变tensor形状的操作连在一起可能会导致奇妙的错误,这是由于内部实现导致的
- 可以通过
.reshape()
代替.view()
或者在.view()
之前添加.contiguous()
来规避问题
1 | x0 = torch.randn(2, 3, 4) |
张量运算
逐元素运算
- 有重载的
+ - * / **
,并且也有对应的方法 .sqrt()
,.sin()
之类的方法,可以参考in the documentation
Reduction operation
- 有
.sum()
,.min()
,.max()
,.mean()
,之类的函数,完整的列表in the documentation
1 | x = torch.tensor([[1, 2, 3], |
dim
参数描述要沿着哪个维度做缩减,也就是说做完缩减这个维度会删除- 如果
keepdim=True
,就会仍然保留这个维度,且该维度的值为1
1 | # Create a tensor of shape (128, 10, 3, 64, 64) |
矩阵运算
torch.dot
: 向量内积torch.mm
: 矩阵乘矩阵torch.mv
: 矩阵乘向量torch.addmm
/torch.addmv
: 矩阵乘矩阵/向量后再加一个偏置(bias)torch.bmm
/torch.baddmm
: 三维张量乘法torch.matmul
: 通用的张量乘法,表现像numpy的np.dot
- 完整的函数列表in the documentation
Vectorization
- 尽量避免显式地使用循环,而是调用Pytorch的运算来隐式完成循环操作,这通常会快得多,这种代码风格称为vectorization
广播
广播的规则如下
- 把低维度的张量扩展成高维度的,新增的维度大小为1
- 如果两个张量在某维度上大小相同或者某个张量在该维度大小为1,称它们在这个维度上是可比较的
- 当两个张量在所有维度都可比较时,可以进行广播
- 广播之后,两个张量每个维度的大小都是最大的那个
- 如果一个张量在某维度大小是1,另外一个大于1,广播的表现则是将前者沿着该维度进行复制
- 详尽解释在documentation
第一步中的添加维度似乎是从头(第0维)插入进去
广播通常隐式进行,但也有显式的方法
torch.broadcast_tensors
Out-of-place vs in-place
大多数PyTorch运算被分成两类
Out-of-place operators: 返回一个新的tensor,大多数PyTorch运算表现如此
In-place operators: 修改并返回输入的tensor。带下划线的实例方法 (比如
add_()
)是in-place的。在torch
命名空间内的运算可以用out=
参数使其in-place
通常应该避免使用in-place因为他们在自动求导计算梯度的时候可能会出问题
GPU加速
- tensor有
device
属性用来表征tensor储存在哪里,CPU还是CUDA(for Nvidia GPUs) .to()
方法可以转换tensor的device
属性,也可以用.cuda()
和.cpu()
,更加方便