Pytorch常用操作记录,pytorch文档:
1 | https://pytorch.org/docs/stable/ |
基本数据类型
data type
Data type | dtype | CPU tensor | GPU tensor |
---|---|---|---|
32-bit floating point | torch.float32 or torch.float |
torch.FloatTensor |
torch.cuda.FloatTensor |
64-bit floating point | torch.float64 or torch.double |
torch.DoubleTensor |
torch.cuda.DoubleTensor |
16-bit floating point | torch.float16 or torch.half |
torch.HalfTensor |
torch.cuda.HalfTensor |
8-bit integer (unsigned) | torch.uint8 |
torch.ByteTensor |
torch.cuda.ByteTensor |
8-bit integer (signed) | torch.int8 |
torch.CharTensor |
torch.cuda.CharTensor |
16-bit integer (signed) | torch.int16 or torch.short |
torch.ShortTensor |
torch.cuda.ShortTensor |
32-bit integer (signed) | torch.int32 or torch.int |
torch.IntTensor |
torch.cuda.IntTensor |
64-bit integer (signed) | torch.int64 or torch.long |
torch.LongTensor |
torch.cuda.LongTensor |
Boolean | torch.bool |
torch.BoolTensor |
torch.cuda.BoolTensor |
type check
1 | 2,3) a = torch.randn( |
2 | a.type() |
3 | 'torch.FloatTensor' |
4 | |
5 | type(a) |
6 | torch.Tensor |
7 | |
8 | isinstance(a, torch.FloatTensor) |
9 | True |
dim check
1 | 1,2,3) a = torch.rand( |
2 | a.shape |
3 | torch.Size([1,2,3]) |
4 | |
5 | list(a.shape) |
6 | [1,2,3] |
7 | |
8 | 0) a.size( |
9 | 1 |
10 | |
11 | a.dim() |
12 | 3 |
创建Tensor
from numpy
1 | 2,3.3]) a = np.array([ |
2 | torch.from_numpy(a) |
3 | tensor([2, 3]) |
from list
1 | In [*]: torch.tensor([2,3]) |
2 | Out[*]: tensor([2, 3]) |
3 | |
4 | In [*]: torch.FloatTensor([2,3.3]) |
5 | Out[*]: tensor([2.0000, 3.3000]) |
uninitialize
1 | In [*]: torch.Tensor(2,3) |
2 | Out[*]: |
3 | tensor([[-4.2107e-05, 4.5766e-41, 7.6038e-30], |
4 | [ 3.0963e-41, 1.1988e-20, 4.5766e-41]]) |
设置默认数据类型
1 | In [*]: torch.tensor([1.2, 3]).type() |
2 | Out[*]: 'torch.FloatTensor' |
3 | |
4 | In [*]: torch.set_default_tensor_type(torch.DoubleTensor) |
5 | |
6 | In [*]: torch.tensor([1.2, 3]).type() |
7 | Out[*]: 'torch.DoubleTensor' |
随机初始化
1 | In [*]: a = torch.rand(2,2) |
2 | In [*]: a |
3 | Out[*]: tensor([[0.0934, 0.9568], |
4 | [0.3287, 0.5201]]) |
5 | |
6 | In [*]: torch.rand_like(a) |
7 | Out[*]: tensor([[0.1323, 0.4544], |
8 | [0.3094, 0.7894]]) |
9 | |
10 | In [*]: torch.randint(1,10,[2,2]) |
11 | Out[*]: tensor([[8, 9], |
12 | [3, 1]]) |
13 | |
14 | In [*]: torch.randn(2,2) #标准正态分布 |
15 | Out[*]: tensor([[-0.6804, 0.0677], |
16 | [-0.8232, -0.8727]]) |
17 | |
18 | In [*]: torch.full([2,2],5) |
19 | Out[*]: tensor([[5., 5.], |
20 | [5., 5.]]) |
序列初始化
1 | In [*]: torch.arange(0,4) |
2 | Out[*]: tensor([0, 1, 2, 3]) |
3 | |
4 | In [*]: torch.arange(0,4,2) |
5 | Out[*]: tensor([0, 2]) |
6 | |
7 | In [*]: torch.arange(0,10) |
8 | Out[*]: tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) |
9 | |
10 | In [*]: torch.arange(0,10,2) |
11 | Out[*]: tensor([0, 2, 4, 6, 8]) |
12 | |
13 | In [*]: torch.range(0,10) |
14 | /home/haha/anaconda3/envs/py36/bin/ipython:1: UserWarning: torch.range is deprecated in favor of torch.arange and will be removed in 0.5. Note that arange generates values in [start; end), not [start; end]. |
15 | #!/home/haha/anaconda3/envs/py36/bin/python |
16 | Out[*]: tensor([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]) |
17 | |
18 | In [*]: torch.linspace(0,10,steps=5) |
19 | Out[*]: tensor([ 0.0000, 2.5000, 5.0000, 7.5000, 10.0000]) |
20 | |
21 | In [*]: torch.logspace(0,1,steps=5) |
22 | Out[*]: tensor([ 1.0000, 1.7783, 3.1623, 5.6234, 10.0000]) |
特殊初始化
1 | In [*]: torch.ones(2,2) |
2 | Out[*]: |
3 | tensor([[1., 1.], |
4 | [1., 1.]]) |
5 | |
6 | In [*]: torch.zeros(2,2) |
7 | Out[*]: |
8 | tensor([[0., 0.], |
9 | [0., 0.]]) |
10 | |
11 | In [*]: torch.eye(2,3) |
12 | Out[*]: |
13 | tensor([[1., 0., 0.], |
14 | [0., 1., 0.]]) |
15 | |
16 | In [*]: a = torch.zeros(3,3) |
17 | |
18 | In [*]: torch.ones_like(a) |
19 | Out[*]: |
20 | tensor([[1., 1., 1.], |
21 | [1., 1., 1.], |
22 | [1., 1., 1.]]) |
23 | |
24 | In [*]: torch.randperm(5) |
25 | Out[*]: tensor([0, 2, 3, 1, 4]) |
切片和索引
indexing
1 | In [*]: a = torch.rand(4,3,28,28) |
2 | |
3 | In [*]: a[*].shape |
4 | Out[*]: torch.Size([3, 28, 28]) |
5 | |
6 | In [*]: a[0,0,2].shape |
7 | Out[*]: torch.Size([*]) |
8 | |
9 | In [*]: a[0,0,2,4] |
10 | Out[*]: tensor(0.0452) |
first/last N
1 | In [*]: a[:2,1:,-1:,:].shape |
2 | Out[*]: torch.Size([2, 2, 1, 28]) |
by step
1 | In [*]: a[:,:,0:28:2,0:28:3].shape |
2 | Out[*]: torch.Size([4, 3, 14, 10]) |
3 | |
4 | In [*]: a[:,:,::2,::-1].shape |
5 | ----------------------------------------------------------------------- |
6 | ValueError Traceback (most recent call last) |
7 | <ipython-input-73-f808e66143f0> in <module> |
8 | ----> 1 a[:,:,::2,::-1].shape |
9 | |
10 | ValueError: negative step not yet supported |
11 | |
12 | In [*]: a[:,:,::2,::3].shape |
13 | Out[*]: torch.Size([4, 3, 14, 10]) |
by specific index
1 | In [*]: a.index_select(1,torch.arange(2)).shape |
2 | Out[*]: torch.Size([4, 2, 28, 28]) |
3 | |
4 | In [*]: a.index_select(3,torch.arange(7)).shape |
5 | Out[*]: torch.Size([4, 3, 28, 7]) |
6 | |
7 | In [*]: a[...,:2].shape |
8 | Out[*]: torch.Size([4, 3, 28, 2]) |
9 | |
10 | In [*]: a[1,...].shape |
11 | Out[*]: torch.Size([3, 28, 28]) |
by mask
1 | In [*]: x = torch.randn(3,4) |
2 | |
3 | In [*]: mask = x.ge(0.5) |
4 | |
5 | In [*]: mask |
6 | Out[*]: |
7 | tensor([[0, 1, 0, 0], |
8 | [1, 0, 0, 0], |
9 | [0, 0, 0, 0]], dtype=torch.uint8) |
10 | |
11 | In [*]: torch.masked_select(x,mask) |
12 | Out[*]: tensor([0.7164, 2.1624]) |
by flatten index
1 | In [*]: a = torch.tensor([[4,3,5],[6,8,7]]) |
2 | |
3 | In [*]: torch.take(a,torch.tensor([0,2,-1])) |
4 | Out[*]: tensor([4, 5, 7]) |
维度变换
view/reshape
1 | In [*]: a = torch.rand(4,1,28,28 |
2 | In [*]: a.view(4,28*28).shape |
3 | Out[*]: torch.Size([4, 784]) |
squeeze/unsqueeze
squeeze
1 | In [*]: a.shape |
2 | Out[*]: torch.Size([4, 1, 28, 28]) |
3 | |
4 | In [*]: a.unsqueeze(0).shape |
5 | Out[*]: torch.Size([1, 4, 1, 28, 28]) |
6 | |
7 | In [*]: a.unsqueeze(-1).shape |
8 | Out[*]: torch.Size([4, 1, 28, 28, 1]) |
unsqueeze
1 | In [*]: a = torch.rand(1,32,1,1) |
2 | |
3 | In [*]: a.shape |
4 | Out[*]: torch.Size([1, 32, 1, 1]) |
5 | |
6 | In [*]: a.squeeze().shape |
7 | Out[*]: torch.Size([*]) |
8 | |
9 | In [*]: a.squeeze(0).shape |
10 | Out[*]: torch.Size([32, 1, 1]) |
11 | |
12 | In [*]: a.squeeze(1).shape |
13 | Out[*]: torch.Size([1, 32, 1, 1]) |
transpose/t/permute
t
only expects a 2D tensor
1 | In [*]: a = torch.rand(3,4) |
2 | |
3 | In [*]: a.t().shape |
4 | Out[*]: torch.Size([4, 3]) |
transpose
1 | In [*]: a = torch.rand(4,3,32,32) |
2 | |
3 | In [*]: a.transpose(1,3).view(4,3*32*32).shape |
4 | --------------------------------------------------------------- |
5 | RuntimeError Traceback (most recent call last) |
6 | <ipython-input-45-bdff182163c0> in <module> |
7 | ----> 1 a.transpose(1,3).view(4,3*32*32).shape |
8 | |
9 | RuntimeError: invalid argument 2: view size is not compatible with input tensor size and stride (at least one dimension spans across two contiguous subspaces). Call .contiguous() before .view(). at /pytorch/aten/src/TH/generic/THTensor.cpp:203 |
10 | |
11 | In [*]: a1 = a.transpose(1,3).contiguous().view(4,3*32*32).view(4,3,32,32) |
12 | |
13 | In [*]: a2 = a.transpose(1,3).contiguous().view(4,3*32*32).view(4,32,32,3).transpose(1,3) |
14 | |
15 | In [*]: a1.shape,a2.shape |
16 | Out[*]: (torch.Size([4, 3, 32, 32]), torch.Size([4, 3, 32, 32])) |
17 | |
18 | In [*]: torch.all(torch.eq(a,a1)) |
19 | Out[*]: tensor(0, dtype=torch.uint8) |
20 | |
21 | In [*]: torch.all(torch.eq(a,a2)) |
22 | Out[*]: tensor(1, dtype=torch.uint8) |
permute
1 | In [*]: a.permute(0,2,3,1).shape |
2 | Out[*]: torch.Size([4, 32, 32, 3]) |
expand/repeat
expand: broadcasting
1 | In [*]: a = torch.rand(1,32,1,1) |
2 | |
3 | In [*]: a.expand(4,32,14,14).shape |
4 | Out[*]: torch.Size([4, 32, 14, 14]) |
repeat: memory copied
1 | In [*]: a = torch.rand(1,32,1,1) |
2 | |
3 | In [*]: a.repeat(4,32,1,1).shape |
4 | Out[*]: torch.Size([4, 1024, 1, 1]) |
5 | |
6 | In [*]: a.repeat(4,1,1,1).shape |
7 | Out[*]: torch.Size([4, 32, 1, 1]) |
8 | |
9 | In [*]: a.repeat(4,1,32,32).shape |
10 | Out[*]: torch.Size([4, 32, 32, 32]) |
拼接与拆分
cat
1 | In [*]: a = torch.rand(4,32,8) |
2 | |
3 | In [*]: b = torch.rand(5,32,8) |
4 | |
5 | In [*]: torch.cat([a,b],dim=0).shape |
6 | Out[*]: torch.Size([9, 32, 8]) |
stack
create new dim, 两个tensor维度相同
1 | In [*]: a.shape |
2 | Out[*]: torch.Size([4, 32, 8]) |
3 | |
4 | In [*]: torch.stack([a,a],dim=1).shape |
5 | Out[*]: torch.Size([4, 2, 32, 8]) |
6 | |
7 | In [*]: torch.stack([a,a],dim=3).shape |
8 | Out[*]: torch.Size([4, 32, 8, 2]) |
split
by length
1 | In [*]: c = torch.rand(2,32,8) |
2 | |
3 | In [*]: a,b = c.split([10,22],dim=1) |
4 | |
5 | In [*]: a.shape,b.shape |
6 | Out[*]: (torch.Size([2, 10, 8]), torch.Size([2, 22, 8])) |
1 | In [*]: a,b = c.split(16,dim=1) |
2 | |
3 | In [*]: a.shape,b.shape |
4 | Out[*]: (torch.Size([2, 16, 8]), torch.Size([2, 16, 8])) |
5 | |
6 | In [*]: a = c.split(2,dim=0) |
7 | |
8 | In [*]: a.shape |
9 | --------------------------------------------------------------- |
10 | AttributeError Traceback (most recent call last) |
11 | <ipython-input-86-d74f1bcdd37c> in <module> |
12 | ----> 1 a.shape |
13 | |
14 | AttributeError: 'tuple' object has no attribute 'shape' |
15 | |
16 | In [*]: len(a) |
17 | Out[*]: 1 |
18 | |
19 | In [*]: a[*].shape |
20 | Out[*]: torch.Size([2, 32, 8]) |
chunk
by num
1 | In [*]: a,b = c.chunk(2,dim=0) |
2 | |
3 | In [*]: a.shape,b.shape |
4 | Out[*]: (torch.Size([1, 32, 8]), torch.Size([1, 32, 8])) |
数学运算
add/minus/multiply/divide
1 | In [*]: a = torch.rand(3,4) |
2 | |
3 | In [*]: b = torch.rand(4) |
4 | |
5 | In [*]: a+b |
6 | Out[*]: |
7 | tensor([[0.8015, 1.1462, 1.0086, 0.3205], |
8 | [1.2817, 1.0414, 1.3938, 0.8069], |
9 | [0.4473, 0.4525, 1.7025, 0.9032]]) |
10 | |
11 | In [*]: torch.add(a,b) |
12 | Out[*]: |
13 | tensor([[0.8015, 1.1462, 1.0086, 0.3205], |
14 | [1.2817, 1.0414, 1.3938, 0.8069], |
15 | [0.4473, 0.4525, 1.7025, 0.9032]]) |
matmul
torch.mm: only for 2d tensor
1 | In [*]: a |
2 | Out[*]: |
3 | tensor([[3., 3.], |
4 | [3., 3.]]) |
5 | |
6 | In [*]: b = torch.ones(2,2) |
7 | |
8 | In [*]: torch.mm(a,b) |
9 | Out[*]: |
10 | tensor([[6., 6.], |
11 | [6., 6.]]) |
12 | |
13 | In [*]: torch.matmul(a,b) |
14 | Out[*]: |
15 | tensor([[6., 6.], |
16 | [6., 6.]]) |
17 | |
18 | In [*]: a@b |
19 | Out[*]: |
20 | tensor([[6., 6.], |
21 | [6., 6.]]) |
floor/ceil/round/trunc/frac
1 | In [*]: a |
2 | Out[*]: tensor(3.1400) |
3 | |
4 | In [*]: a.floor(),a.ceil(),a.trunc(),a.frac() |
5 | Out[*]: (tensor(3.), tensor(4.), tensor(3.), tensor(0.1400)) |
6 | |
7 | In [*]: torch.tensor(3.499).round() |
8 | Out[*]: tensor(3.) |
9 | |
10 | In [*]: torch.tensor(3.5).round() |
11 | Out[*]: tensor(4.) |
clamp
1 | In [*]: a |
2 | Out[*]: |
3 | tensor([[8.0798, 8.1040, 3.2681], |
4 | [2.9466, 3.6986, 7.1211]]) |
5 | |
6 | In [*]: a.clamp(3.5,7.5) |
7 | Out[*]: |
8 | tensor([[7.5000, 7.5000, 3.5000], |
9 | [3.5000, 3.6986, 7.1211]]) |
统计属性
min/max/mean/sum/argmax/argmin
1 | In [*]: a |
2 | Out[*]: |
3 | tensor([[0., 1., 2., 3.], |
4 | [4., 5., 6., 7.]]) |
5 | |
6 | In [*]: a.min(),a.max(),a.mean(),a.prod(),a.sum(),a.argmax(),a.argmin() |
7 | Out[*]: |
8 | (tensor(0.), |
9 | tensor(7.), |
10 | tensor(3.5000), |
11 | tensor(0.), |
12 | tensor(28.), |
13 | tensor(7), |
14 | tensor(0)) |
15 | |
16 | In [*]: a.argmax(dim=1) |
17 | Out[*]: tensor([3, 3]) |
18 | |
19 | In [*]: a.argmax(dim=1, keepdim=True) |
20 | Out[*]: |
21 | tensor([[*], |
22 | [*]]) |
23 | |
24 | In [*]: a.max(dim=1) |
25 | Out[*]: |
26 | torch.return_types.max( |
27 | values=tensor([3., 7.]), |
28 | indices=tensor([3, 3])) |
29 | |
30 | In [*]: a.max(dim=1,keepdim=True) |
31 | Out[*]: |
32 | torch.return_types.max( |
33 | values=tensor([[3.], |
34 | [7.]]), |
35 | indices=tensor([[*], |
36 | [*]])) |
topk/kth-value
1 | In [*]: a |
2 | Out[*]: |
3 | tensor([[0., 1., 2., 3.], |
4 | [4., 5., 6., 7.]]) |
5 | |
6 | In [*]: a.topk(2,dim=1) |
7 | Out[*]: |
8 | torch.return_types.topk( |
9 | values=tensor([[3., 2.], |
10 | [7., 6.]]), |
11 | indices=tensor([[3, 2], |
12 | [3, 2]])) |
13 | |
14 | In [*]: a.topk(2,dim=1,largest=False) |
15 | Out[*]: |
16 | torch.return_types.topk( |
17 | values=tensor([[0., 1.], |
18 | [4., 5.]]), |
19 | indices=tensor([[0, 1], |
20 | [0, 1]])) |
21 | |
22 | In [*]: a.kthvalue(3,dim=1) |
23 | Out[*]: |
24 | torch.return_types.kthvalue( |
25 | values=tensor([2., 6.]), |
26 | indices=tensor([2, 2])) |
compare
1 | In [*]: a |
2 | Out[*]: |
3 | tensor([[0., 1., 2., 3.], |
4 | [4., 5., 6., 7.]]) |
5 | |
6 | In [*]: a>0 |
7 | Out[*]: |
8 | tensor([[0, 1, 1, 1], |
9 | [1, 1, 1, 1]], dtype=torch.uint8) |
10 | |
11 | In [*]: torch.gt(a,0) |
12 | Out[*]: |
13 | tensor([[0, 1, 1, 1], |
14 | [1, 1, 1, 1]], dtype=torch.uint8) |
15 | |
16 | In [*]: torch.eq(a,a) |
17 | Out[*]: |
18 | tensor([[1, 1, 1, 1], |
19 | [1, 1, 1, 1]], dtype=torch.uint8) |
20 | |
21 | In [*]: torch.equal(a,a) |
22 | Out[*]: True |
where / gather
where
根据逻辑值将两个tensor进行聚合
1 | In [*]: cond = torch.randn(2,2) |
2 | |
3 | In [*]: cond |
4 | Out[*]: |
5 | tensor([[ 1.9013, -0.6679], |
6 | [-1.1109, -1.0334]]) |
7 | |
8 | In [*]: a = torch.ones(2,2) |
9 | |
10 | In [*]: a |
11 | Out[*]: |
12 | tensor([[1., 1.], |
13 | [1., 1.]]) |
14 | |
15 | In [*]: b = torch.zeros(2,2) |
16 | |
17 | In [*]: b |
18 | Out[*]: |
19 | tensor([[0., 0.], |
20 | [0., 0.]]) |
21 | |
22 | In [*]: torch.where(cond>0,a,b) |
23 | Out[*]: |
24 | tensor([[1., 0.], |
25 | [0., 0.]]) |
gather
根据index选择某个tensor中的一部分
1 | In [*]: idx = torch.randint(10,[3,3]) |
2 | |
3 | In [*]: idx |
4 | Out[*]: |
5 | tensor([[2, 3, 7], |
6 | [0, 4, 4], |
7 | [6, 4, 4]]) |
8 | |
9 | In [*]: label = (torch.arange(10)+100).expand(3,10) |
10 | |
11 | In [*]: label |
12 | Out[*]: |
13 | tensor([[100, 101, 102, 103, 104, 105, 106, 107, 108, 109], |
14 | [100, 101, 102, 103, 104, 105, 106, 107, 108, 109], |
15 | [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]]) |
16 | |
17 | In [*]: torch.gather(label,dim=1,index=idx) |
18 | Out[*]: |
19 | tensor([[102, 103, 107], |
20 | [100, 104, 104], |
21 | [106, 104, 104]]) |