目录
基本数据类型
创建Tensor
索引和切片
维度变换
Broadcasting
合并和分割
数学运算及统计属性
基本数据类型
Tensor(张量)是线性代数中用到的一种数据结构,类似向量和矩阵,你可以在张量上进行算术运算。
PyTorch(Facebook创建的python包,提供两个高层特性:1) 类似Numpy的基于GPU加速的张量运算 2) 在基于回放(tape-based)的自动微分系统之上构建的深度神经网络。
在一般意义上,以基于可变数目的轴的规则网格组织的一组数字称为张量。标量是零阶张量。向量是一阶张量,矩阵是二阶张量。
张量和多维数组是不同类型的对象。前者是一种函数,后者是适宜在坐标系统中表示张量的一种数据结构。
在数学上,张量由多元线性函数定义。一个多元线性函数包含多个向量变量。张量域是张量值函数。
张量是需要定义的函数或容器。实际上,当数据传入时,计算才真正发生。当不需要严格区分数组和张量的时候,数组或多维数组(1D, 2D, …, ND)一般可以视作张量。
张量表述和矩阵类似,一般用大写字母表示张量,带整数下标的小写字母表示张量中的标量值。
import torch#创建0维tensor 标量 一般用作loss输出a=torch.tensor(1)print(a)print(len(a.shape))#print(a.dim()) 与上面的效果一样#创建1维tensor 向量 一般用于bias/linear inputb=torch.tensor([1])print(b)print(len(b.shape))#创建二维tensor 矩阵c=torch.randn(2,3) #2行3列 服从标准正态分布print(c)print(len(c.shape))print(c.size(0))#第一维print(c.size(1))#第二维#创建三维tensor 常用于RNNd=torch.randn(2,2,3)print(d)print(len(d.shape))print(d.size(0))#第一维print(d.size(1))#第二维print(d.size(2))#第三维
创建Tensor
Tensor和tensor都能用于生成新的张量,
在指定形状的大小时,会发生这种情况:对于多维矩阵,(3,4)可以表示三行四列的矩阵,这是没有歧义的。对于 Tensor 会创建一个三行四列的矩阵,但是对于 tensor 却无法创建相应的变量。因为它需要却确定的数据值。但当输入(5)时,Tensor 是一个矩阵,所以将这个5理解为是(1,5),一行五列的矩阵。tensor 会将这个5认为是一个确定的数据。它会创建出一个值为5的变量。
Tensor主要是创建多维矩阵的,标量从某种意义上,不算矩阵。所以Tensor可以通过赋值多维矩阵的方式创建,但是无法指定标量值进行创建。如果想创建单个值,采用[5.6] 这种形式,指定一行一列的矩阵。
同时,Tensor可以指定多维矩阵形状的大小,并且默认的数据类型是FloatTensor。
tensor主要是根据确定的数据值进行创建,无法直接指定形状大小,需要根据数据的大小进行创建。但同时,tensor没有赋值数据值是矩阵的限制,可以直接使用tensor(5.6)。
import numpy as npimport torch#利用numpy创建tensora=np.array([2,1,4])a1=torch.from_numpy(a)print(a)print(a1)b=np.ones([3,2])b1=torch.from_numpy(b)print(b)print(b1)#利用list创建tensor#tensor接收现成的数据#Tensor 接收数据的维度c=torch.tensor([1.1,2.4])print(c)d=torch.FloatTensor([1,20.6])print(d)e=torch.FloatTensor(2,3,3) #初始化2*3*3的张量 里面数字是随机生成的 仅仅是作为容器 后面要覆盖数据print(e)print(e.dim())#随机生成tensorf=torch.rand(3,3)print(f)f1=torch.rand_like(f)print(f1)f2=torch.randint(1,10,[3,3])print(f2)g=torch.full([2,3],7)print(g)#左闭右开h=torch.arange(1,10)h1=torch.arange(1,10,2)print(h)print(h1)i=torch.linspace(0,10,3)i1=torch.logspace(0,-1,10)print(i)print(i1)j=torch.ones(3,3)j1=torch.zeros(3,3)j2=torch.eye(3,3)print(j)print(j1)print(j2)
索引和切片
import torchimport numpy as npa=torch.rand(4,3,28,28)print(a[0].shape)print(a[0][0].shape)print(a[0][0][2])print(a[0][0][2][6])print(a.index_select(0, torch.tensor([2,3])))print(a.index_select(0, torch.tensor([2,3])).shape)print(a[...].shape)print(a[0,...].shape)print(a[:2,...,:25].shape)
维度变换
import torcha=torch.rand(4,1,28,28)print(a.view(4*1,28*28).shape)#维度增加print(a.unsqueeze(0).shape) #在第一个维度插入print(a.unsqueeze(-1).shape) #在最后一个维度插入#维度压缩b=torch.rand(2,1,1,12)print(b.squeeze().shape)#不指定参数会压缩所有可以压缩的维度print(b.squeeze(0).shape) #本身不可压缩则不会改变print(b.squeeze(1).shape)#维度扩充 expand不会增加数据 而repeat会拷贝原来数据 一般建议使用expand#expand参数为新的维度print(b.expand(2,6,6,12).shape) #只可以改变原来维度为1的数据print(b.expand(-1,6,-1,-1).shape) #-1表示不改变维度#repeat参数为每一个维度重复次数print(b.repeat(3,1,2,2).shape) #可以改变非1c=torch.rand(4,3,28,28)#transpose参数为交换的两个维度print(c.transpose(1,3).shape)print(c.transpose(2,3).transpose(0,1).shape)#permute指明交换后对应原维度print(c.permute(2,1,0,3).shape)
Broadcasting
转载自:PyTorch 中 Tensor Broadcasting 详解-PyTorch 中文网 (pytorchtutorial.com)
通常情况下,小一点的tensor会被broadcast到大一点的,这样才能保持大小一致。Broadcasting过程中的循环操作都在C底层进行,所以速度比较快。但也有一些情况下Broadcasting会带来性能上的下降。
两个Tensors只有在下列情况下下才能进行broadcasting操作:
每个tensor至少有一维遍历所有的维度,从尾部维度开始,每个对应的维度大小要么相同,要么其中一个是1,要么其中一个不存在
合并和分割
import torchimport numpy as np#cat进行张量拼接a=torch.rand(2,32,8)b=torch.rand(5,32,8)print(torch.cat([a,b],dim=0).shape)a1=torch.rand(2,32,8)b1=torch.rand(2,66,8)print(torch.cat([a1,b1],dim=1).shape)#stack 创建新维度a1=torch.rand(3,32,8)b1=torch.rand(3,32,8)print(torch.stack([a1,b1],dim=0).shape)a2=torch.rand(4,3,16,32)b2=torch.rand(4,3,16,32)print(torch.stack([a2,b2],dim=2).shape)#split按长度进行划分aa,bb=a2.split(2,dim=0)print(aa.shape)print(bb.shape)#chunk按数量划分aa1,bb1=a2.chunk(2,dim=2)print(aa1.shape)print(bb1.shape)
数学运算及统计属性
import torcha=torch.rand(2,3)b=torch.rand(3)print(a+b)print(torch.add(a,b))#矩阵乘法c=torch.ones(3,3)d=torch.rand(3,3)print(c@d)print(torch.matmul(c,d))
import torchimport numpy as npa=torch.full([8],1)b=a.view(2,4)c=a.view(2,2,2)print(a.norm(1),b.norm(1),c.norm(1)) #计算整体的L1范数print(a.norm(2),b.norm(2),c.norm(2)) #计算整体L2范数print(a.norm(1,dim=0),b.norm(1,dim=0),c.norm(1,dim=0)) #指定维度计算L1范数print(a.norm(2,dim=0),b.norm(2,dim=1),c.norm(2,dim=1)) #指定维度计算L1范数d=torch.rand(4,10)print(d.sum(),d.sum(dim=0),d.sum(dim=1))print(d.argmax(),d.max())#不指定dimension 会把tensor摊平print(d.argmax(dim=1),d.max(dim=1))#keepdim表示保留原来的维度print(d.max(dim=1,keepdim=True))print(d.argmax(dim=1,keepdim=True))#topk 第一个参数为前几大的数字 第二个为维度# 返回为前k个数 及其下标print(d.topk(3,dim=1))