0%

pytorch学习笔记2

Tensor与Autograd详解

参考自《深度学习框架PyTorch入门与实践》

Tensor

创建Tensor

创建Tensor的方法有很多:

函数 功能
Tensor(*size) 基础构造函数
ones(*size) 全为 1 Tensor
zeros(*size) 全为 0 Tensor
eyes(*size) 对角线为1,其他为0
arange(s,e,step) 从s到e,步长为step
linspace(s,e,step) 从s到e,均分为step份
rand/randn(*sizes) 均匀/标准分布
normal(mean,std)/uniform(from,to) 正态分布/均匀分布
randperm(m) 随机排列

用Tensor()函数创建tensor时,可以有很多方法:

1
2
3
4
5
6
7
8
9
x=t.Tensor([[1,2,3],[4,5,6]])#用一个list来创建
y=t.Tensor([1,2,3])
z=t.Tensor(1,2,3)#用几个值来确定Tensor的维度
print(x)
print(y)
print(y.tolist())
print(z)
a=x
a

image.png

1
2
3
4
5
6
print(x.size())
print(x.numel())
y=t.Tensor(x.size())
z=t.Tensor((2,3))#Tensor的元素是2和3
a=t.Tensor(2,3)#Tensor的大小是2*3
y,z,a

image.png

tensor.shape和tensor.size()是一样的:
image.png

一些其他的创建方法;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
x=t.ones(2,3)
print(x)
x=t.zeros(4,5)
print(x)
x=t.arange(1,7,2)#注意,第二个参数是取不到的
print(x)
x=t.arange(1,7.00000000000001,2)#注意,第二个参数是取不到的
print(x)
x=t.linspace(1,10.7,5)
print(x)
x=t.randn(3,3)#均值为0,方差为1的正态分布
print(x)
x=t.randperm(20)
print(x)
x=t.eye(3,5)
print(x)

image.png

改变形状的操作

用 view(),squeeze(),unsqueeze(),resize_()等方法可以改变tensor的形状

view()

view()用于直接改变形状,但不能改变tensor的大小。用法:

1
2
3
b=t.arange(0,6)
print(b.view(2,3))
print(b.view(-1,2,1,3)) # -1表示自动计算其大小

image.png

unsqueeze()

unsqueeze()用于增加tensor的维度。用法:

1
2
3
4
print(b)
print(b.unsqueeze(1))#从 6 变成 6*1
print(b.unsqueeze(-2))#-2 的意思是,增加的那个维度是增加了维度之后的tensor的倒数第二个维度。
#也就是说,从 6 增加成 1*6

image.png

squeeze()

squeeze()用于压缩大小为一的维度。用法:

1
2
3
4
x=t.Tensor(2,3,1)
print(x.squeeze(0))#第0个维度大小是2,不能压缩
print(x.squeeze())#压缩所有大小为1的维度
x.squeeze(2)#第二个维度大小是1,被压缩

image.png

resize_

resize_也可以用来修改形状。不同的是,如果新尺寸超过了原来的尺寸,会自动分配新的内存空间。用法:

1
2
3
4
x=t.rand(2,3)
print(x)
print(x.resize_(3,2))
x.resize_(3,3)

image.png

索引操作

Tensor可以按下标索引:

1
2
3
4
5
6
7
8
9
a=t.randn(3,4)
print(a)
print(a[0])#第0行
print(a[:,2])#第2列
print(a[1:3,2:4])#第1,2行和第2,3列的交叉
print(a[:2])#前两行
print(a[0:2])#前两行
print(a[0:1,:2])#第0行,前两列。形状是1*2
print(a[0,:2])#第0行,前两列。形状是2

image.png

1
2
3
4
print(a)
print(a>1)
print(a[a>1])#形状不同
print(a*(a>1))#形状相同

image.png

选择函数

选择函数用于从Tensor中选出一部分。

index_select()

index_select()用于选出tensor特定维度特定下表的部分。用法:

1
2
3
4
5
6
7
8
import torch
a = torch.linspace(1, 12, steps=12).view(3, 4)
print(a)
b = torch.index_select(a, 0, torch.tensor([0, 2]))#0表示第0个维度,0,2表示这一维度下表为0和2的会被选出来。
print(b)
print(a.index_select(0, torch.tensor([0, 2])))
c = a.index_select(1, torch.tensor([1, 3]))#1表示第一个维度
print(c)

image.png

mask_select()

a.mask_select(b)=a[b],没啥好用的

nonzero()

用于获得非0元素的下标,用法:

1
2
3
a=t.Tensor([2,3,0,0,1])
print(a.nonzero())
a[a.nonzero()]

gather()和scatter()

太复杂了,等用到的时候再搞。

高级索引

x[[],[]……[]] 其中第1个列表表示第0个维度要选的东西,第2个列表表示第1个维度要选的东西,以此类推。

1
2
3
4
x=t.arange(0,27).view(3,3,3)
print(x)
print(x[[1,2],[1,2],[2,1]])#相当于x[1,1,2]和x[2,2,1]
print(x[[1,2],[0],[0]])#相当于x[1,0,0]和x[2,0,0]

image.png

Tensor类型

tensor的元素默认类型是FloatTensor,可以通过t.set_default_tensor_type()修改默认类型。

常见类型有:

数据类型 CPU tensor GPU tensor
32bit浮点 torch.FloatTensor torch.cuda.FloatTensor
64bit浮点 torch.DoubleTensor torch.cuda.DoubleTensor
16bit浮点 16bit浮点只能在GPU里用 torch.cuda.HaltTensor
8bit无符号整型 torch.ByteTensor torch.cuda.ByteTensor
8bit有符号整型 torch.CharTensor torch.cuda.CharTensor
16bit有符号整型 torch.ShortTensor torch.cuda.ShortTensor
32bit有符号整型 torch.IntTensor torch.cuda.IntTensor
64bit有符号整型 torch.LongTensor torch.cuda.LongTensor

还可以用type()函数指定类型:

1
2
3
4
5
6
7
t.set_default_tensor_type("torch.FloatTensor")
a=t.rand(2,3)
print(a)
b=a.int()
print(b)
b=b.type("torch.DoubleTensor")
print(b)

逐元素操作

这些函数会对tensor的每一个元素进行操作,如下表所示:

函数 功能
abs/sqrt/div/exp/fmod/log/pow