下载地址(wheel)
数据类型
Int----IntTensor of size()
Float----FloatTensor of size()
Int array----IntTensor of size[d1, d2, ...]
Float array----FloatTensor of size[d1, d2, ...]
string----无
# string怎么编码
# ·One-hot编码:[0,1]表示一类,[1,0]表示一类。(向量太稀疏,字符串之间没有相关性)
# ·Embedding:word2vec、glove
基本操作
a = torch.randn(2, 3) # 随机正态分布N(0,1)的2*3维tensor张量
a.type() # 'torch.FloatTensor'
type(a) # torch.Tensor
isinstance(a, torch.FloatTensor) # True
# GPU
data.type() # 'torch.DoubleTensor'
data.cuda().type() # 'torch.cuda.DoubleTensor'
# dimension=0
a = torch.tensor(2.) # dim=0的2.0张量
a.shape # torch.Size([]) shape是张量属性中的一个成员
a.size() # torch.Size([])
len(a.shape) # 0
a.dim() # 0
# dimension=1
a = torch.tensor([1.1, 2.2, ...]) # dim=1的张量
a = torch.FloatTensor(1) # dim=1,数值随机
a = torch.FloatTensor(2, 3) # 指定shape,dim=2,数值随机,[[0.1,0.2,0.3],[0.1,0.2,0.3]]
a = torch.FloatTensor([2.1, 2.2]) # list[2.1, 2.2]的FloatTensor
data = np.ones(2) # array([1., 1.]),dim=1,shape=2,1行2列[1. 1.]
torch.from_numpy(data) # tensor([1., 1.], dtype=torch.float64) 从numpy导入float是double类型
a = torch.ones(2) # dim=1,shape=2,张量tensor[1., 1.]
# dimension=n(n>=2)
a = torch.randn(2, 3) # 随机正态分布N(0,1)的2*3维tensor,数值随机
a.shape # torch.Size([2, 3]) shape是张量属性中的一个成员
a.size(0) # 第一个维度2
a.size(1) # 第二个维度3
a.shape[1] # 第二个维度3
a = torch.rand(1, 2, 3) # 0~1随机分布的1*2*3维
a.shape # torch.Size([1, 2, 3]) shape是张量属性中的一个成员
a[0] # [2, 3]的tensor[[0.1,0.2,0.3],[0.1,0.2,0.3]]
list(a.shape) # 转成list类型 [1, 2, 3]
# others
a.numel() # num of element: tensor占用内存的数量
# [batch_size, channel, height, width] = [3, 3, 28, 28]
# numel() # 3*3*28*28=7056
# a.dim()相当于len(a.shape)
torch.empty() # 置0,可指定shape
torch.zeros() # 置0,可指定shape
torch.ones() # 置1,可指定shape
torch.eye() # 对角线元素置1,可指定shape,shape=[非对角矩阵],eye(3)默认3*3对角矩阵
torch.*_like(a) # shape=a.shape,ones_like(a),eye_like(a)
torch.tensor() # 不可指定shape,只能是数值或list[],list可以用()不推荐
torch.Tensor() # 可指定shape或list[],默认类型FloatTensor类型,增强学习一般DoubleTensor
torch.set_default_tensor_type(torch.DoubleTensor)
torch.rand() # 0~1随机数值,不包括1,可指定shape
torch.rand_like(a) # 0~1随机数值,shape=a.shape
torch.randint(min, max, shape) # [min, max)整数随机取值, shape=(m,n)
torch.randn() # 随机正态分布N(0,1),数值随机,均值为0,可指定shape
a = torch.normal(mean=torch.full([10],0.),std=torch.arange(1.,0.,-0.1)) # 随机正态分布N(u,std)
torch.full([shape], value) # 指定shape,全为value
torch.arange(min=0, max, -0.1) # [min, max)均匀递增取值,每次递增(-0.1),默认递增1
torch.arange(10) # tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
torch.range(min, max) # [min, max]均匀递增取值,默认递增1,UserWarning
torch.range(0,10) # UserWarning, tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
for a in range(10): # Python里也有range
print(a) # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
torch.linspace(min, max, steps) # [min, max]均匀递增取值,取值steps个,linspace(0,10,11)
torch.logspace(min, max, steps, base=10) # [min, max]均匀递增取值,取值steps个,底数默认10
torch.randperm(max) # [min=0, max)均匀随机索引,0~max全部取到,相当于随机打散random.shuffle
# 索引:(:等效于->,[min=0,max),:表示取完,-1表示最后一个,-1:从末尾开始取,:-1取到最后一个)
a = torch.Tensor(3, 3, 28, 28)
a[:2].shape # torch.Size([2, 3, 28, 28])
a[:2, :1,:, :].shape # torch.Size([2, 1, 28, 28])
a[:2, 1:,:, :].shape # torch.Size([2, 2, 28, 28])
a[:2,-1:,:, :].shape # torch.Size([2, 1, 28, 28])
# select by steps间隔索引,start:end:step,min:max:间隔,[min,max)间隔采样
a[:, :,0:28:2,::2].shape # torch.Size([3, 3, 14, 14])
# 指定索引 (第i个维度,索引值)
a.index_select(0,torch.tensor([0,2])).shape # torch.Size([2, 3, 28, 28])
a.index_select(2,torch.tensor([0,9])).shape # torch.Size([3, 3, 2, 28])
a.index_select(2,torch.arange(28)).shape # torch.Size([3, 3, 2, 28])
# ...表示任意多的维度,为了方便
a[...].shape # torch.Size([3, 3, 28, 28])
a[0,...].shape # torch.Size([3, 28, 28]) a[0,...]相当于a[0]
a[:,1,...].shape # torch.Size([3, 28, 28])
a[0,...,::2].shape # torch.Size([3, 28, 14]) 当有...出现时,右边的索引理解为最右边
a[...,:5].shape # torch.Size([3, 3, 28, 5])
# torch.masked_select(a, mask)
# torch.take(src, torch.tensor([索引号list])) # 先将src打平再取索引
# shape变换
# 版本区别,任意指定shape
a.view(shape)
a.reshape(shape)
# 维度变换
# unsqueeze 参数范围 [-a.dim()-1, a.dim()+1) positive idx/negative idx
a.shape = torch.Size([3,3,28,28])
a.unsqueeze(0).shape # torch.Size([1,3,3,28,28])
a.unsqueeze(-1).shape # torch.Size([3,3,28,28,1])
a.unsqueeze(-5).shape # torch.Size([1,3,3,28,28])
a.unsqueeze(4).shape # torch.Size([3,3,28,28,1])
# squeeze 参数范围 [-a.dim()-1, a.dim()+1) 只有dim()=1的维度才能被压缩
a.unsqueeze(0).squeeze(-5).shape # torch.Size([3,3,28,28])
a.squeeze() # 压缩所有dim()=1的维度
# 维度上的shape变换
a.shape = torch.Size([3,3,28,28])
b.shape = torch.Size([1,3,1,1])
b.expand(3,3,28,28).shape # torch.Size([3,3,28,28]) # 只能1->N,m->m,不能m->N(报错)
b.expand(-1,-1,28,-1).shape # torch.Size([1,3,28,1]) # -1保持原来的不变
b.expand(-1,-1,28,-6).shape # torch.Size([1,3,28,-6]) # -n 最新版这个bug已经被facebook修复
b.repeat(3,3,28,1).shape # torch.Size([3,9,28*28,28]) # repeat的次数
## broadcasting
# [class, students, scores] add bias for every students: +5 score
# [4个班,32个学生,8门课分数],每门课分数加5分
# a = [4, 32, 8] b = [5.0] --> [4,32,8]
b.unsqueeze(0).unsqueeze(0).expand_as(a)
# 矩阵转置
a.t() # t() expects a 2D tensor. only 2D
a.shape # torch.Size([4,3,28,28]) [batch_size,channel,height,width]
a1 = a.transpose(1,3).view(4,3*28*28) # RuntimeRrror: Call .contiguous() before .view()
a1 = a.transpose(1,3).contiguous().view(4,3*28*28).view(4,3,28,28)
# [b,c,h,w]-->[b,w,h,c]-->[b,w*h*c]-->[b,w,h,c]
a2 = a.transpose(1,3).contiguous().view(4,3*28*28).view(4,3,28,28).transpose(1,3)
# [b,c,h,w]-->[b,w,h,c]-->[b,w*h*c]-->[b,w,h,c]-->[b,c,h,w]
# a1.shape == a2.shape == a.shape 内容不同
torch.all(torch.eq(a,a1)) # tensor(0, dtype=torch.uint8) 所有元素不一致
torch.all(torch.eq(a,a2)) # tensor(1, dtype=torch.uint8) 所有元素一致
# permute()参数表示原来的维度位置
b = a.permute(0,2,3,1) # torch.Size([4,28,28,3])
# [b,c,h,w]-->[b,h,w,c]
# RuntimeRrror: Call .contiguous() before .view()
# 合并与分割
# cat()
# a = [class1-4, students, scores] = [4,32,8]
# b = [class5-9, students, scores] = [5,32,8]
torch.cat([a,b], dim=0) # [4+5,32,8]
# stack(), a b的shape一致
# a = [32,8]
# b = [32,8]
c = torch.stack([a,b], dim=0) # [2,32,8]
# 在dim=0之前创建了一个新的维度,c[0][:][:]=0 其他都是a的元素, c[1][:][:]=1 其他都是b的元素
# split() by len
# c = [2,32,8]
aa, bb = c.split([1,1], dim=0)
aa, bb = c.split(1, dim=0)
aa.shape, bb.shape # torch.Size([1,32,8]), torch.Size([1,32,8])
# chunk() by num
aa, bb = c.chunk(2, dim=0)
aa.shape, bb.shape # torch.Size([1,32,8]), torch.Size([1,32,8])
# 基本运算
# + - * /
# torch.add() sub() mul() div()
# 维度不同也可以
# 相同位置元素进行+-*/
# 矩阵相乘
torch.mm(a,b) # only for 2D
a@b # a@b.t() == a@(b.t())
torch.matmul(a,b)
# 永远只对最后两个维度进行矩阵乘法
a = torch.rand(4,3,28,64)
b = torch.rand(4,1,64,32)
torch.matmul(a,b).shape # torch.Size([4,3,28,32]) # 将b的第1维1broadcast成3提出来,矩阵乘法
a = torch.rand(4,3,28,64)
b = torch.rand(4,64,32)
torch.matmul(a,b).shape # 报错
a = torch.ones(2,1,3,4)
b = torch.rand(5,4,2)
torch.matmul(a,b).shape # torch.Size([2,5,3,2])
# 将a的第0维2作为batch提出来,则a和b都可看作三维。再把a的1 broadcast成5,提取公因式5,矩阵乘法。
# 乘方
a = torch.full([2,2],3)
a.pow(2) # 每个元素3^2=9
a**2 # 3^2=9
# 开方
a = torch.full([2,2],9)
a.sqrt() # 每个元素9^0.5=3
a.rsqrt() # 每个元素9^0.5=3 再做倒数1/3=0.3333
a**0.5 # 也是开二次方
# exp e=2.7183
a = torch.exp(torch.ones(2,2))
# log 默认以e为底数
torch.log(a) # torch.ones(2,2)
torch.log2(a)
torch.log10(a)
# 近似 Approximation
a = torch.tensor(3.14)
a.floor(), a.ceil(), a.trunc(), a.frac()
# 向下取整数,向上取整数,整数部分,小数部分
(tensor.(3.), tensor.(4.), tensor.(3.), tensor.(0.1400))
a.round() # tensor(3.) # 四舍五入
# 区间限定函数 clamp()
# 作用:将输入input张量每个元素的夹紧到区间 [min,max],并返回结果到一个新张量。
# torch.clamp(input, min, max, out=None) → Tensor
# tensor.clamp(min, max, out=None) → Tensor # 两个参数
# tensor.clamp(max, out=None) → Tensor # 一个参数
# torch.meshgrid()
x1, y1 = torch.meshgrid(x,y)
# 输出的是两个tensor,size是x.size*y.size(行数是x的个数,列数是y的个数)
# 注意:两个参数的数据类型相同,要么都是float,要么都是int,否则会报错。
a = torch.tensor([0.1, 0.2, 0.3])
b = torch.tensor([1.0, 2.0])
aa,bb=torch.meshgrid(a,b)
# tensor([[0.1000, 0.1000],
# [0.2000, 0.2000],
# [0.3000, 0.3000]])
# tensor([[1., 2.],
# [1., 2.],
# [1., 2.]])