Tensor
Tensor 可以简单地认为是一个数组,且支持高效的科学计算。
- 基础操作:
- 从接口的角度讲,对tensor可以分为两类:
- torch.function,如torch.add(a,b)
- tensor.function,如a.add(b)
- 这两种功能是等价的。
- 从存储角度讲,可以分为以下两类:
- 不会修改自身的数据,如a.add(b),结果返回一个新的tensor。
- 会修改自身的数据,如a.add_(b),加法的结果扔存储在a中,a被修改了。
- 从接口的角度讲,对tensor可以分为两类:
Tensor和numpy的相互转换。
tensor 和numpy共享内存,所以互相转换的速度非常快。这也意味着,如果其中一个变了,另外一个也会变。
import torch as t a = t.ones(5) # 创建一个tensor() print(a) b = a.numpy() # tensor转为Numpy. print(b) c = t.from_numpy(b) # numpy转为tensor。 print(c)
tensor可通过.cuda方法转为GPU的tensor,从而使用GPU计算。
tensor常用操作
tensor.view方法可以调整tensor的形状,view不会修改自身的数据,返回的tensor与原tensor共享内存。
import torch as t a = t.arange(0, 6) print(a) b = a.view(2, 3) # 当某一维是-1时,会自动计算他的大小。 c = a.view(-1, 3) d = a.view(2, -1) print(b) print(c) print(d) 0 1 2 3 4 5 [torch.FloatTensor of size 6] 0 1 2 3 4 5 [torch.FloatTensor of size 2x3] 0 1 2 3 4 5 [torch.FloatTensor of size 2x3] 0 1 2 3 4 5 [torch.FloatTensor of size 2x3]
resize是另一种可用来调整size的方法,但与view不同,他可以修改原tensor的尺寸。如果超过原理来的尺寸,会自动分配新的内存空间,而如果新尺寸小于原尺寸,则之前的数据依旧会被保存。
import torch as t a = t.arange(2, 3) a.resize_(1, 3) print(a) a.resize_(3, 3) print(a) 2.0000 0.0000 0.0000 [torch.FloatTensor of size 1x3] 2.0000e+00 0.0000e+00 2.0169e-08 -3.6902e+19 4.2039e-45 4.1294e-31 7.3535e-12 4.5855e-41 0.0000e+00 [torch.FloatTensor of size 3x3]
- 索引和numpy类似。
Tensor的数据类型,各数据类型转换,type(new_type)是通用方法。
import torch as t a = t.arange(6).view(2, 3) print(a) b = a.int() print(b) c = a.type(t.IntTensor) print(c) 0 1 2 3 4 5 [torch.FloatTensor of size 2x3] 0 1 2 3 4 5 [torch.IntTensor of size 2x3] 0 1 2 3 4 5 [torch.IntTensor of size 2x3]
逐元素操作(element-wise)
- abs/sqrt/ceil…
clamp(input, min, max) 超过min和max的部分截断。
a = t.arange(6).view(2, 3) print(a) print(a.clamp(2, 3)) print(a.clamp(min=3)) 0 1 2 3 4 5 [torch.FloatTensor of size 2x3] 2 2 2 3 3 3 [torch.FloatTensor of size 2x3] 3 3 3 3 4 5 [torch.FloatTensor of size 2x3]
归并操作:
- mean/sum/median/mode 均值/和/中位数/众数
- norm/dist 范数/距离
- 维数的记忆方法(假设形状是(m,n,k)):
- 如果指定dim=0,输出就是(1,n,k)或者(n,k)
- 如果指定dim=1,输出就是(m,1,k)或者(m,k)
- 如果指定dim=2,输出就是(m,n,1)或者(m,n)
size是否有1取决于参数keepdim,=True会保留1,默认是False。
import torch as t a = t.arange(6).view(2, 3) print(a) print(a.sum(dim=0, keepdim=True)) print(a.sum(dim=0)) 0 1 2 3 4 5 [torch.FloatTensor of size 2x3] 3 5 7 [torch.FloatTensor of size 1x3] 3 5 7 [torch.FloatTensor of size 3]
比较函数
- topk 最大的k个数
- sort 排序
max/min 比较两个tensor的最大值和最小值。
import torch as t a = t.linspace(0, 10, 6).view(2, 3) b = t.linspace(10, 0, 6).view(2, 3) print(a) print(b) print(a > b) print(a[a > b]) 0 2 4 6 8 10 [torch.FloatTensor of size 2x3] 10 8 6 4 2 0 [torch.FloatTensor of size 2x3] 0 0 0 1 1 1 [torch.ByteTensor of size 2x3] 6 8 10 [torch.FloatTensor of size 3]
广播法则:
- 让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分通过在前面加1补齐。
- 两个数组要么在某一个维度的长度一致,要么其中一个为1,否则不能计算。
- 当输入数组的某个维度的长度为1时,计算时沿此维度复制扩充成一样的形状。
Variable
PyTorch 在autograd模块中实现了计算图的相关功能,autograd的核心数据结构是Variable。Variable封装了Tensor,并记录对Tensor的操作记录来构建计算图。
forward的输入输出都是Variable,只有Variable才具有自动求导功能,Tensor是没有的,所以在输入时,需要把Tensor封装成Varible。