目录
基本数据类型
创建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 input b=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 常用于RNN d=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 np import torch #利用numpy创建tensor a=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()) #随机生成tensor f=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 torch import numpy as np a=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 torch a=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) #可以改变非1 c=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 torch import 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 torch a=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 torch import numpy as np a=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))
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)