pytorch系列------2 tensor基礎
pytorch Tensor的基本用法
- Tensor的建立
- 索引,合併,切片
- 初始化
- 數學操作
1. Tensor的建立
1) 隨機數字
torch.rand(*sizes, out=None) → Tensor
返回一個張量,包含了從區間[0, 1)的均勻分佈中抽取的一組隨機數。張量的形狀由引數sizes定義
# torch.rand(sizes) -> [0,1)之間的均勻分佈
x = torch.rand(2,3)
x
out:
0.9161 0.7135 0.8969
0.7552 0.8760 0.2236
[torch.FloatTensor of size 2x3]
torch.randn(*sizes, out=None) → Tensor
返回一個張量,包含了從標準正態分佈(均值為0,方差為1,即高斯白噪聲)中抽取的一組隨機數。張量的形狀由引數sizes定義
# torch.randn(sizes) -> Z(0,1)
x = torch.randn(2,3)
x
out:
-1.9352 0.9779 1.7401
2.0432 -0.1962 -0.1177
[torch.FloatTensor of size 2x3]
torch.randperm(n)
返回張量, 0~n之間的一個全排列
# torch.randperm(n) -> permutation of 0~n
x = torch.randperm(5)
x
out:
3
1
4
0
2
[torch.LongTensor of size 5]
2) zeros, ones, eye, arrange
torch.zeros(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
返回張量,用0填充,size有引數sizes確定
# torch.zeros(2,3) -> [[0,0,0],[0,0,0]] x = torch.zeros(2,3) x
out:
0 0 0
0 0 0
[torch.FloatTensor of size 2x3]
torch.ones(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
返回張量,用1填充,size有引數sizes確定
# torch.ones(2,3) -> [[0,0,0],[0,0,0]]
x = torch.ones(2,3)
x
out:
1 1 1
1 1 1
[torch.FloatTensor of size 2x3]
torch.arange(start=0, end, step=1, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
返回一維張量,在[start, end)區間內,按step為間隔返回一個等差數列,
# torch.arange(start,end,step=1) -> [start,end) with step
y = torch.arange(1, 4)
x = torch.arange(0,3,step=0.5)
y
x
out:
tensor([ 1, 2, 3])
0.0000
0.5000
1.0000
1.5000
2.0000
2.5000
[torch.FloatTensor of size 6]
torch.eye(n, m=None, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
返回二維對角矩陣張量,對角線上為1,其餘為0
torch.eye(3)
out:
tensor([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
3) Tensor 資料型別
所有的資料型別都在這裡
https://pytorch.org/docs/stable/tensors.html#torch-tensor
建立size為[2,3]的浮點數張量
# torch.FloatTensor(size or list)
x = torch.FloatTensor(2,3)
x
out:
-7.4341e-17 4.5629e-41 -7.4341e-17
4.5629e-41 -7.4342e-17 2.9427e-44
[torch.FloatTensor of size 2x3]
建立資料為2,3的浮點數張量
# torch.FloatTensor(size or list)
x = torch.FloatTensor([2,3])
x
out:
2
3
[torch.FloatTensor of size 2]
轉換為整型張量
# tensor.type_as(tensor_type)
x = x.type_as(torch.IntTensor())
x
out:
2
3
[torch.IntTensor of size 2]
4) Tensor 和 numpy的相互轉換
從numpy轉換為Tensor
import numpy as np
# torch.from_numpy(ndarray) -> tensor
x1 = np.ndarray(shape=(2,3), dtype=int,buffer=np.array([1,2,3,4,5,6]))
x2 = torch.from_numpy(x1)
x2
out:
1 2 3
4 5 6
[torch.LongTensor of size 2x3]
從張量轉換為numpy陣列
# tensor.numpy() -> ndarray
x3 = x2.numpy()
x3
out:>
array([[1, 2, 3],
[4, 5, 6]])
5) GPU和CPU上的Tensor
建立Tensor
x = torch.FloatTensor([[1,2,3],[4,5,6]])
x
out:
1 2 3
4 5 6
[torch.FloatTensor of size 2x3]
轉換為GPU上:
x_gpu = x.cuda()
x_gpu
out:
1 2 3
4 5 6
[torch.cuda.FloatTensor of size 2x3 (GPU 0)]
從GPU格式轉換為CPU
x_cpu = x_gpu.cpu()
x_cpu
out:
1 2 3
4 5 6
[torch.FloatTensor of size 2x3]
6) tensor的size
也就是tensor的形狀
建立維度為[10, 12, 3,3]的浮點數張量
# tensor.size() -> indexing also possible
x = torch.FloatTensor(10,12,3,3)
x.size()[:]
out:
torch.Size([10, 12, 3, 3])
2. 索引(indexing),切片(slicing), 合併(joining), 更改形狀(reshaping)
1) indexing
torch.index_select(input, dim, index)
在dim的維度上,按index索引
比如下列就是在行上,索引第0和3行
# torch.index_select(input, dim, index)
x = torch.rand(4,3)
out = torch.index_select(x,0,torch.LongTensor([0,3]))
x,out
out:
(
0.9495 0.8593 0.2616
0.2279 0.0857 0.7603
0.4439 0.2024 0.8021
0.3477 0.6363 0.5002
[torch.FloatTensor of size 4x3],
0.9495 0.8593 0.2616
0.3477 0.6363 0.5002
[torch.FloatTensor of size 2x3])
也支援python和numpy的索引方式
x[:,0],x[0,:],x[0:2,0:2]
out:
(
0.9495
0.2279
0.4439
0.3477
[torch.FloatTensor of size 4],
0.9495
0.8593
0.2616
[torch.FloatTensor of size 3],
0.9495 0.8593
0.2279 0.0857
[torch.FloatTensor of size 2x2])
torch.masked_select(input, mask, out=None) → Tensor
返回一維張量,mask為一個ByteTensor,返回mask值為1的位置對應input的值,
mask和input的size不一定相同,但要滿足廣播機制
# torch.masked_select(input, mask)
x = torch.randn(2,3)
mask = torch.ByteTensor([[0,0,1],[0,1,0]])
out = torch.masked_select(x,mask)
x, mask, out
out:
(
-2.0702 -0.3064 -0.8124
0.2870 0.2648 0.4418
[torch.FloatTensor of size 2x3],
0 0 1
0 1 0
[torch.ByteTensor of size 2x3],
-0.8124
0.2648
[torch.FloatTensor of size 2])
來看一個更有意義的場景,
返回x中大於0.5的值:
x = torch.randn(3, 4)
x
'''
tensor([[ 0.3552, -2.3825, -0.8297, 0.3477],
[-1.2035, 1.2252, 0.5002, 0.6248],
[ 0.1307, -2.0608, 0.1244, 2.0139]])
'''
# 值大於0.5為1,否則為0
mask = x.ge(0.5)
mask
'''
tensor([[ 0, 0, 0, 0],
[ 0, 1, 1, 1],
[ 0, 0, 0, 1]], dtype=torch.uint8)
'''
torch.masked_select(x, mask)
'''
tensor([ 1.2252, 0.5002, 0.6248, 2.0139])
'''
2) joining
torch.cat(seq, dim=0) -> concatenate tensor along dim
最常見的是二維資料, dim為0是按行排列,dim為1是按列排列。
而對於二維陣列而言dim=-1和dim=1完全等價,因為dim=-1表示size的最後一個維度。
# torch.cat(seq, dim=0) -> concatenate tensor along dim
x = torch.FloatTensor([[1,2,3],[4,5,6]])
y = torch.FloatTensor([[-1,-2,-3],[-4,-5,-6]])
z1 = torch.cat([x,y],dim=0)
z2 = torch.cat([x,y],dim=1)
x,y,z1,z2
out:
(
1 2 3
4 5 6
[torch.FloatTensor of size 2x3],
-1 -2 -3
-4 -5 -6
[torch.FloatTensor of size 2x3],
1 2 3
4 5 6
-1 -2 -3
-4 -5 -6
[torch.FloatTensor of size 4x3],
1 2 3 -1 -2 -3
4 5 6 -4 -5 -6
[torch.FloatTensor of size 2x6])
3) slicing 切片
torch.chunk(tensor, chunks, dim=0) → List of Tensors
將tensor在維度dim上分割為特定數量的塊(chunks)
例如下列程式碼第一行將z1在行上分割為兩部分,第二行將z1在列上分為3部分
# torch.chunk(tensor, chunks, dim=0) -> tensor into num chunks
x_1, x_2 = torch.chunk(z1,2,dim=0)
y_1, y_2, y_3 = torch.chunk(z1,3,dim=1)
z1,x_1,x_2,z1,y_1,y_2,y_3
out:
(
1 2 3
4 5 6
-1 -2 -3
-4 -5 -6
[torch.FloatTensor of size 4x3],
1 2 3
4 5 6
[torch.FloatTensor of size 2x3],
-1 -2 -3
-4 -5 -6
[torch.FloatTensor of size 2x3],
1 2 3
4 5 6
-1 -2 -3
-4 -5 -6
[torch.FloatTensor of size 4x3],
1
4
-1
-4
[torch.FloatTensor of size 4x1],
2
5
-2
-5
[torch.FloatTensor of size 4x1],
3
6
-3
-6
[torch.FloatTensor of size 4x1])
和chunk的作用一樣
# torch.split(tensor,split_size,dim=0) -> split into specific size
x1,x2 = torch.split(z1,2,dim=0)
y1 = torch.split(z1,2,dim=1)
z1,x1,x2,y1
out:
(
1 2 3
4 5 6
-1 -2 -3
-4 -5 -6
[torch.FloatTensor of size 4x3],
1 2 3
4 5 6
[torch.FloatTensor of size 2x3],
-1 -2 -3
-4 -5 -6
[torch.FloatTensor of size 2x3], (
1 2
4 5
-1 -2
-4 -5
[torch.FloatTensor of size 4x2],
3
6
-3
-6
[torch.FloatTensor of size 4x1]))
4) squeezing
torch.squeeze(input,dim=None) -> reduce dim by 1
去掉張量中維度大小為1的dim
建立size為[10, 1,3,1,4]的張量,通過squeeze函式,去掉1的dim,變為[10,3,4]
# torch.squeeze(input,dim=None) -> reduce dim by 1
x1 = torch.FloatTensor(10,1,3,1,4)
x2 = torch.squeeze(x1)
x1.size(),x2.size()
out:
(torch.Size([10, 1, 3, 1, 4]), torch.Size([10, 3, 4]))
torch.unsqueeze(input,dim=None) -> add dim by 1
在指定的dim上新增大小為1維度
比如下列程式碼,在dim=0的維度上增加緯度值為1 的維度,所以張量size變為[1, 10, 3, 4]
# torch.unsqueeze(input,dim=None) -> add dim by 1
x1 = torch.FloatTensor(10,3,4)
x2 = torch.unsqueeze(x1,dim=0)
x1.size(),x2.size()
out:
(torch.Size([10, 3, 4]), torch.Size([1, 10, 3, 4]))
5) reshaping
tensor.view(size)
:改變張量的形狀size
經常在最後一層卷積層,第一層全連線層之前使用,展開為[batch, -1]的形狀
# tensor.view(size)
x1 = torch.FloatTensor(10,3,4)
# 展開為1維
x2 = x1.view(-1)
x3 = x1.view(5,-1)
x4 = x1.view(3,10,-1)
x1.size(), x2.size(), x3.size(), x4.size()
out:>
(torch.Size([10, 3, 4]),
torch.Size([120]),
torch.Size([5, 24]),
torch.Size([3, 10, 4]))
3. 初始化
import torch.nn.init as init
# 均勻分佈
x1 = init.uniform(torch.FloatTensor(3,4),a=0,b=9)
# 正太分佈
x2 = init.normal(torch.FloatTensor(3,4),std=0.2)
# 初始化為常數
x3 = init.constant(torch.FloatTensor(3,4),3.1415)
x1,x2,x3
out:
(
7.8079 3.7811 4.0829 8.0698
8.4885 5.2119 2.5769 1.4455
3.0500 3.9946 5.6066 4.9679
[torch.FloatTensor of size 3x4],
-0.4025 -0.2582 -0.0780 -0.2003
0.1577 -0.0933 -0.2640 -0.3402
0.1431 -0.1946 -0.1485 0.0026
[torch.FloatTensor of size 3x4],
3.1415 3.1415 3.1415 3.1415
3.1415 3.1415 3.1415 3.1415
3.1415 3.1415 3.1415 3.1415
[torch.FloatTensor of size 3x4])
4. 數學操作
1) 算數操作 Arithmetic operations
# torch.add()
x1 = torch.FloatTensor([[1,2,3],[4,5,6]])
x2 = torch.FloatTensor([[1,2,3],[4,5,6]])
add = torch.add(x1,x2)
x1,x2,add,x1+x2,x1-x2
out:
(
1 2 3
4 5 6
[torch.FloatTensor of size 2x3],
1 2 3
4 5 6
[torch.FloatTensor of size 2x3],
2 4 6
8 10 12
[torch.FloatTensor of size 2x3],
2 4 6
8 10 12
[torch.FloatTensor of size 2x3],
0 0 0
0 0 0
[torch.FloatTensor of size 2x3])
支援廣播機制
# torch.add() broadcasting
x1 = torch.FloatTensor([[1,2,3],[4,5,6]])
x2 = torch.add(x1,10)
x1,x2,x1+10,x2-10
(
1 2 3
4 5 6
[torch.FloatTensor of size 2x3],
11 12 13
14 15 16
[torch.FloatTensor of size 2x3],
11 12 13
14 15 16
[torch.FloatTensor of size 2x3],
1 2 3
4 5 6
[torch.FloatTensor of size 2x3])
元素級乘法:
# torch.mul() -> size better match
x1 = torch.FloatTensor([[1,2,3],[4,5,6]])
x2 = torch.FloatTensor([[1,2,3],[4,5,6]])
x3 = torch.mul(x1,x2)
x3
out:
1 4 9
16 25 36
[torch.FloatTensor of size 2x3]
也支援廣播:
# torch.mul() -> broadcasting
x1 = torch.FloatTensor([[1,2,3],[4,5,6]])
x2 = x1*10
x2
out:
10 20 30
40 50 60
[torch.FloatTensor of size 2x3]
元素級除法
# torch.div() -> size better match
x1 = torch.FloatTensor([[1,2,3],[4,5,6]])
x2 = torch.FloatTensor([[1,2,3],[4,5,6]])
x3 = torch.div(x1,x2)
x3
out:
1 1 1
1 1 1
[torch.FloatTensor of size 2x3]
# torch.div() -> broadcasting
x1 = torch.FloatTensor([[1,2,3],[4,5,6]])
x1/5
out:
0.2000 0.4000 0.6000
0.8000 1.0000 1.2000
[torch.FloatTensor of size 2x3]
2)其他的數學操作
pow 冪操作
求每一個元素的平方
# torch.pow(input,exponent)
x1 = torch.FloatTensor(3,4)
torch.pow(x1,2),x1**2
out:
(
1.00000e-33 *
5.5267 0.0000 5.5267 0.0000
0.0000 0.0000 5.5267 0.0000
0.0000 0.0000 0.0000 0.0000
[torch.FloatTensor of size 3x4],
1.00000e-33 *
5.5267 0.0000 5.5267 0.0000
0.0000 0.0000 5.5267 0.0000
0.0000 0.0000 0.0000 0.0000
[torch.FloatTensor of size 3x4])
指數操作
# torch.exp(tensor,out=None)
x1 = torch.FloatTensor(3,4)
torch.exp(x1)
out:
1 1 1 1
inf 1 inf 1
1 1 1 1
[torch.FloatTensor of size 3x4]
對數操作
# torch.log(input, out=None) -> natural logarithm
x1 = torch.FloatTensor(3,4)
torch.log(x1)
out:
nan -92.8880 -86.5151 -inf
-inf -inf -inf -inf
-inf -inf -inf -inf
[torch.FloatTensor of size 3x4]
3) 矩陣操作
矩陣乘法
# torch.mm(mat1, mat2) -> matrix multiplication
x1 = torch.FloatTensor(3,4)
x2 = torch.FloatTensor(4,5)
torch.mm(x1,x2)
out:
-9.6088e-12 5.8988e-36 5.5267e-33 0.0000e+00 -9.6628e-12
2.4562e-18 6.9592e+27 2.4562e-18 -2.4818e+01 8.6738e-02
1.2129e-32 5.8988e-36 5.5267e-33 0.0000e+00 -9.6628e-12
[torch.FloatTensor of size 3x5]
批矩陣乘法
# torch.bmm(batch1, batch2) -> batch matrix multiplication
x1 = torch.FloatTensor(10,3,4)
x2 = torch.FloatTensor(10,4,5)
torch.bmm(x1,x2).size()
out:
torch.Size([10, 3, 5])
點乘:
# torch.dot(tensor1,tensor2) -> dot product of two tensor
x1 = torch.FloatTensor(3,4)
x2 = torch.FloatTensor(3,4)
torch.dot(x1,x2)
out:
5.5267435454184226e-33
轉置
# torch.t(matrix) -> transposed matrix
x1 = torch.FloatTensor(3,4)
x1,x1.t()
out:
(
1.00000e-17 *
-7.4341 0.0000 -7.4341 0.0000
0.0000 0.0000 0.0000 0.0000
-7.4342 0.0000 -7.4342 0.0000
[torch.FloatTensor of size 3x4],
1.00000e-17 *
-7.4341 0.0000 -7.4342
0.0000 0.0000 0.0000
-7.4341 0.0000 -7.4342
0.0000 0.0000 0.0000
[torch.FloatTensor of size 4x3])
按兩個指定的維度調換位置
# torch.transpose(input,dim0,dim1) -> transposed matrix
x1 = torch.FloatTensor(10,3,4)
x1.size(), torch.transpose(x1,1,2).size(), x1.transpose(1,2).size()
out:
(torch.Size([10, 3, 4]), torch.Size([10, 4, 3]), torch.Size([10, 4, 3]))