Tensor的属性
- 每一个Tensor对象都有以下几个属性:torch.dtype、torch.device和torch.layout
1、torch.dtype属性标识了torch.Tensor的数据类型。
2、torch.device属性标识了torch.Tensor对象在创建之后所存储在的设备名称。
torch.device包含了两种设备类型 ('cpu'
或者 'cuda'
) ,分别标识将Tensor对象储存于cpu内存或者gpu内存中,同时支持指定设备编号,比如多张gpu,可以通过gpu编号指定某一块gpu。 如果没有指定设备编号,则默认将对象存储于current_device()当前设备中;
举个例子, 一个torch.Tensor对象构造函数中的设备字段如果填写'cuda'
,那等价于填写了'cuda:X'
,其中X是函数 torch.cuda.current_device()的返回值。在torch.Tensor对象创建之后,可以通过访问torch.device属性实时访问当前对象所存储在的设备名称。构造torch.device
可以通过字符串/字符串和设备编号。
3、torch.layout属性标识了torch.Tensor在内存中的布局模式。
现在, 我们支持了两种内存布局模式 torch.strided
(dense Tensors) 和尚处试验阶段的torch.sparse_coo
(sparse COO Tensors, 一种经典的稀疏矩阵存储方式)。
torch.strided
跨步存储代表了密集张量的存储布局方式,当然也是最常用最经典的一种布局方式。 每一个strided tensor都有一个与之相连的torch.Storage
对象, 这个对象存储着tensor的数据。这些Storage对象为tensor提供了一种多维的, 跨步的(strided)数据视图。这一视图中的strides是一个interger整形列表:这个列表的主要作用是给出当前张量的各个维度的所占内存大小,严格的定义就是,strides中的第k个元素代表了在第k维度下,从一个元素跳转到下一个元素所需要跨越的内存大小。 跨步这个概念有助于提高多种张量运算的效率。
Tensor创建实例:
import torch a = torch.Tensor([[1, 2],[3, 4]])#定义一个2*2的张量,数值为1,2,3,4 print(a) Out[]: tensor([[1., 2.], [3., 4.]]) b = torch.Tensor(2, 2)#制定形状2*2 print(b) Out[]: tensor([[6.2106e-42, 0.0000e+00], [ nan, nan]])
稀疏张量实例:
i = torch.tensor([[0, 1, 2], [0, 1, 2]])#非0元素的坐标(0,0)(1,1)(2,2) v = torch.tensor([1, 2, 3])#非0元素具体的值对应上述坐标 a = torch.sparse_coo_tensor(i, v, (4, 4), dtype=torch.float32, device=dev) print(a) Out[]: tensor(indices=tensor([[0, 1, 2], [0, 1, 2]]), values=tensor([1., 2., 3.]), size=(4, 4), nnz=3, layout=torch.sparse_coo) #转变为稠密张量 i = torch.tensor([[0, 1, 2], [0, 1, 2]])#非0元素的坐标(0,0)(1,1)(2,2) v = torch.tensor([1, 2, 3])#非0元素具体的值对应上述坐标 a = torch.sparse_coo_tensor(i, v, (4, 4), dtype=torch.float32, device=dev).to_dense()#大小4*4 print(a) Out[]: tensor([[1., 0., 0., 0.], [0., 2., 0., 0.], [0., 0., 3., 0.], [0., 0., 0., 0.]])
Tensor的算术运算
- 哈达玛积(element wise,对应元素相乘)
- 二维矩阵乘法运算操作包括torch.mm()、torch.matmul()、@
- 对于高维的Tensor(dim>2),定义其矩阵乘法仅在最后的两个维度上,要求前面的维度必须保持一致,就像矩阵的索引一样并且运算操作只有torch.matmul()
算术运算实例:add加法、sub减法、mul哈达玛积(乘法)、div除法
import torch a = torch.rand(2, 3) b = torch.rand(2, 3) print(a) print(b) print(a + b) print(a.add(b)) print(torch.add(a, b)) print(a) print(a.add_(b))#其中,前三种一样,第四种是对 a 进行了修改。 print(a)
矩阵运算:
##matmul a = torch.ones(2, 1)#形状 b = torch.ones(1, 2) print(a @ b) print(a.matmul(b)) print(torch.matmul(a, b)) print(torch.mm(a, b)) print(a.mm(b)) ##高维tensor a = torch.ones(1, 2, 3, 4) b = torch.ones(1, 2, 4, 3) print(a.matmul(b).shape) out[]: torch.Size([1, 2, 3, 3])
幂运算pow、指数运算exp、对数运算log、开根号sqrt
a = torch.tensor([1, 2])#数值 print(torch.pow(a, 3)) print(a.pow(3)) print(a**3) print(a.pow_(3)) print(a)
Pytorch中的in-place操作
- “就地”操作,即不允许使用临时变量。
- 也称为原味操作。
- x=x+y
- add_、sub_、mul_等等
Pytorch中的广播机制
- 广播机制:张量参数可以自动扩展为相同大小
- 广播机制需要满足两个条件:
- 每个张量至少有一个维度
- 满足右对齐
A.ndim == B.ndim, 并且A.shape和B.shape对应位置的元素要么相同要么其中一个是1
import torch a = torch.rand(2, 2) b = torch.rand(1, 2) # a, 2*1 # b, 1*2 # c, 2*2 # a = torch.rand(2, 1, 1, 3) # b = torch.rand(4, 2, 3) # 2*4*2*3 c = a + b print(a) print(b) print(c) print(c.shape)
Tensor的取整/取余运算
- .floor()向下取整数
- .ceil()向上取整数
- .round()四舍五入>=0.5向上取整,<0.5向下取整
- .trunc()裁剪,只取整数部分
- .frac()只取小数部分
- %取余
- torch.fmod(a, b)除数除以元素的余数;torch.remainder(a, b)张量a每个元素的除法余数
Tensor的比较运算
- torch.eq(input,other,out=None) #按成员进行等式操作,相同返回True→Tensor
- torch.equal(tensor1,tensor2) #如果tensor1和tensor2有相同的size和elements,则为True→ bool
- torch.ge(input,other,out=None) #input>=other,逐个元素比较输入张量input是否大于或等于另外的张量或浮点数other。若大于或等于则返回为True,否则返回False。若张量other无法自动扩展成与输入张量input相同尺寸,则返回为False。→Tensor
- torch.gt(input,other,out=None) #input>other→Tensor
- torch.le(input,other,out=None) #input<=other→Tensor
- torch.lt(input,other,out=None) #input<other→Tensor
- torch.ne(input,other,out=None) #input!=other不等于→Tensor
Tensor的取前k个大/前k小/第k小的数值及其索引
- torch.sort(input,dim=None,descending=False,out=None)#对目标input进行排序;维度,对于二维数据:dim=0 按列排序,dim=1 按行排序,默认 dim=1
- torch.topk(input,k,dim=None,largest=True,sorted=True,out=None)#沿着指定维度返回最大k个数值及其索引值
- torch.kthvalue(input,k,dim=None,out=None)#沿着指定维度返回第k个最小值及其索引值
##topk,k和维度dim a = torch.tensor([[2, 4, 3, 1, 5], [2, 3, 5, 1, 4]]) print(a.shape) print(torch.topk(a, k=1, dim=1, largest=False)) ##topk a = torch.tensor([[2, 4, 3, 1, 5], [2, 3, 5, 1, 4]]) print(a.shape) print(torch.topk(a, k=2, dim=0, largest=False))
print(torch.kthvalue(a, k=2, dim=0)) print(torch.kthvalue(a, k=2, dim=1))
Tensor判定是否为finite/inf/nan
- torch.isfinite(tensor)/torch.isinf(tensor)/torch.isnan(tensor)
- 返回一个标记元素是否为finite/inf/nan的mask张量(有界,无界,nan)