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(),更加方便