pytorch中對tensor操作:分片、索引、壓縮、擴充、交換維度、拼接、切割
- 1 根據維度提取子集
- 2 對資料進行壓縮和擴充:torch.squeeze() 和torch.unsqueeze()
- 3 對資料維度進行交換:tensor.permute()
- 4 對資料進行拼接:torch.cat(), torch.stack()
- 5 對資料進行切割:torch.split()
1 根據維度提取子集
1.0 原始資料情況
import torch
#### 先看一下原始資料
a = torch.tensor([[[1,2,3,4],[5,6,7,8],[9,10,11,12]],
[[-1,-2,-3,-4],[-5,-6,-7,-8],[-9,-10,-11,-12]]], dtype=float)
print(a)
# 每個print下面的內容是輸出,這里是一個2*3*4的三維矩陣
tensor([[[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.]],
[[ -1., -2., -3., -4.],
[ -5., -6., -7., -8.],
[ -9., -10., -11., -12.]]], dtype=torch.float64)
1.1 根據第一個維度提取一個子集
#### 根據第一個維度提取第一個元素,結果是一個3*4的矩陣
print(a[0])
tensor([[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.]], dtype=torch.float64)
#### 根據第一個維度提取前兩個元素,結果是一個2*3*4的矩陣,其實等于a,因為a在第一個維度也就兩個元素
print(a[0:2])
tensor([[[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.]],
[[ -1., -2., -3., -4.],
[ -5., -6., -7., -8.],
[ -9., -10., -11., -12.]]], dtype=torch.float64)
1.2 根據前兩個維度提取一個子集
#### 方法1.2.1
#### 提取第一個維度的第2個元素,再從中提取第二個維度的第3個元素,
#### 結果是一個向量
print(a[1,2])
tensor([ -9., -10., -11., -12.], dtype=torch.float64)
#### 方法1.2.2
#### 提取第一個維度的前兩個元素,再從中提取第二個維度的1:2維度(也就是第1個元素)
#### 結果是一個2*1*4的矩陣
print(a[0:2,1:2])
tensor([[[ 5., 6., 7., 8.]],
[[-5., -6., -7., -8.]]], dtype=torch.float64)
#### 方法1.2.3
#### 提取第一個維度的前兩個元素,再從中提取第二個維度的第1個元素
#### 注意結果是一個2*4的矩陣
print(a[0:2,1])
tensor([[ 5., 6., 7., 8.],
[-5., -6., -7., -8.]], dtype=torch.float64)
#### 方法1.2.4
#### 提取第二個維度的第3個元素,其他維度的元素全部提取
print(a[:,2]) # 同 print(a[:,2,:]),也就是維度比第二個維度大的下標可以忽略,默認全部提取
tensor([[ 9., 10., 11., 12.],
[ -9., -10., -11., -12.]], dtype=torch.float64)
注意:上面的方法1.2.1最后的維數是1維,和原始資料比下降了兩個維度,方法1.2.2和1.2.3想要獲得的資料是一致的,但是維度不同,方法1.2.3下降了一個維度,從上面我們可以發現,用n個固定的標量來作為下標,會使得結果比原始資料降低n個維數,比如方法1.2.1種有兩個固定標量(1和2),所以維數從3維下降成1維,方法1.2.3種有一個固定標量(1),所以下降了兩維,方法1.2.4種有一個固定標量(2),所以下降了一維,
1.3 提取某個特定的元素的值
#### 提取第一個維度的第1個元素,再從中提取第二個維度的第3個元素,再從中提取第三個維度的第2個元素
print(a[0,2,1])
tensor(10., dtype=torch.float64)
#### 將這個值從tensor變數轉成python中的數值變數
print(a[0,2,1].item())
10.0
2 對資料進行壓縮和擴充:torch.squeeze() 和torch.unsqueeze()
2.1 squeeze()將元素個數只有1的維度壓縮掉
#### 先看一下b長什么樣,是一個2*1*4的3維矩陣
b = a[:,1:2]
print(b)
tensor([[[ 5., 6., 7., 8.]],
[[-5., -6., -7., -8.]]], dtype=torch.float64)
#### 將第二個維度壓縮掉,因為第二個維度的元素個數只有1,所以可以壓縮
c = b.squeeze(1) # 等價于 c = torch.squeeze(b,1)
print(c) # 看一下壓縮后的結果,是一個2*4的矩陣
tensor([[ 5., 6., 7., 8.],
[-5., -6., -7., -8.]], dtype=torch.float64)
print(b) # 發現b沒有變化,也就是torch.squeeze()會回傳一個tensor,而不是inplace的操作
tensor([[[ 5., 6., 7., 8.]],
[[-5., -6., -7., -8.]]], dtype=torch.float64)
# tensor.squeeze_()是inplace操作
b.squeeze_(1)
print(b)
tensor([[ 5., 6., 7., 8.],
[-5., -6., -7., -8.]], dtype=torch.float64)
#### 將b中所有只有一個元素的維度都壓縮
b = a[:,1:2,2:3]
print(b)
tensor([[[ 7.]],
[[-7.]]], dtype=torch.float64)
print(b.squeeze())
tensor([ 7., -7.], dtype=torch.float64)
2.2 unsqueeze()對資料進行擴充維度
#### 先看一下資料的情況
b = a[0:2,1]
print(b)
tensor([[ 5., 6., 7., 8.],
[-5., -6., -7., -8.]], dtype=torch.float64)
print(b.size())
torch.Size([2, 4])
#### 在第一個維度進行擴充
print(b.unsqueeze(0)) # 等價于print(torch.unsqueeze(b,0))
tensor([[[ 5., 6., 7., 8.],
[-5., -6., -7., -8.]]], dtype=torch.float64)
print(b.unsqueeze(0).size())
torch.Size([1, 2, 4])
#### 在第二個維度進行擴充
# 等于將方法1.2.3的結果在第2個維度上進行擴充,變成和方法1.2.2是一樣的結果
print(b.unsqueeze(1))
tensor([[[ 5., 6., 7., 8.]],
[[-5., -6., -7., -8.]]], dtype=torch.float64)
print(b.unsqueeze(1).size())
torch.Size([2, 1, 4])
#### 在第三個維度進行擴充
print(b.unsqueeze(2))
tensor([[[ 5.],
[ 6.],
[ 7.],
[ 8.]],
[[-5.],
[-6.],
[-7.],
[-8.]]], dtype=torch.float64)
print(torch.unsqueeze(b,2))
torch.Size([2, 4, 1])
3 對資料維度進行交換:tensor.permute()
permute可以對資料維度進行交換,資料本身不變
#### 先看一下原始資料
print(a)
tensor([[[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.]],
[[ -1., -2., -3., -4.],
[ -5., -6., -7., -8.],
[ -9., -10., -11., -12.]]], dtype=torch.float64)
print(a.size())
torch.Size([2, 3, 4])
#### 將原始資料a的第2維給新資料b的第1維;第1維給第二維;第3維給第3維
b= a.permute(1,0,2)
print(b)
tensor([[[ 1., 2., 3., 4.],
[ -1., -2., -3., -4.]],
[[ 5., 6., 7., 8.],
[ -5., -6., -7., -8.]],
[[ 9., 10., 11., 12.],
[ -9., -10., -11., -12.]]], dtype=torch.float64)
print(b.size())
torch.Size([3, 2, 4])
#### a本身不變
print(a)
tensor([[[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.]],
[[ -1., -2., -3., -4.],
[ -5., -6., -7., -8.],
[ -9., -10., -11., -12.]]], dtype=torch.float64)
4 對資料進行拼接:torch.cat(), torch.stack()
4.1 cat
指定維度,利用cat對多個資料進行拼接,拼接前后的總維數不變
#### 先看一下資料
a = torch.tensor([[1,2,3,4],[5,6,7,8]])
b = torch.tensor([[9,10,11,12],[13,14,15,16]])
print(a)
tensor([[1, 2, 3, 4],
[5, 6, 7, 8]])
print(b)
tensor([[ 9, 10, 11, 12],
[13, 14, 15, 16]])
#### 根據第一維度拼接
print(torch.cat((a,b),0)) # 等價于print(torch.cat((a,b))
tensor([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
#### 根據第二維度拼接
print(torch.cat((a,b),1))
tensor([[ 1, 2, 3, 4, 9, 10, 11, 12],
[ 5, 6, 7, 8, 13, 14, 15, 16]])
#### 還可以拼接多個
print(torch.cat((a,b,a))
tensor([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[ 1, 2, 3, 4],
[ 5, 6, 7, 8]])
4.2 stack
指定維度,對多個資料進行拼接,拼接后總維數增加1
#### 按照第一個維度堆疊
print(torch.stack((a,b),0)) # 等價于torch.stack((a,b))
tensor([[[ 1, 2, 3, 4],
[ 5, 6, 7, 8]],
[[ 9, 10, 11, 12],
[13, 14, 15, 16]]])
print(torch.stack((a,b)).size()) # 2維變成3維
torch.Size([2, 2, 4])
#### 按照第二個維度堆疊
print(torch.stack((a,b),1))
tensor([[[ 1, 2, 3, 4],
[ 9, 10, 11, 12]],
[[ 5, 6, 7, 8],
[13, 14, 15, 16]]])
#### 按照第三個維度堆疊
print(torch.stack((a,b),2))
tensor([[[ 1, 9],
[ 2, 10],
[ 3, 11],
[ 4, 12]],
[[ 5, 13],
[ 6, 14],
[ 7, 15],
[ 8, 16]]])
#### 和cat一樣,可以對多個資料進行stack
print(torch.stack((a,b,a),2))
tensor([[[ 1, 9, 1],
[ 2, 10, 2],
[ 3, 11, 3],
[ 4, 12, 4]],
[[ 5, 13, 5],
[ 6, 14, 6],
[ 7, 15, 7],
[ 8, 16, 8]]])
5 對資料進行切割:torch.split()
利用split對資料進行切割,split的第二個引數可以是一個數字也可以是一個list,第三個引數是維度,切割后的資料維度和原始資料一致
#### 先看一下資料
a = torch.arange(1,16).reshape(5,3)
print(a)
tensor([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15]])
#### 均勻切割,根據第一個維度將a切割,每塊包含2個元素,最后不足的就有多少輸出多少
x = torch.split(a,2,0) # 獲得3塊結果,每塊結果的維度和原始資料一致
print(x[0])
tensor([[1, 2, 3],
[4, 5, 6]])
print(x[1])
tensor([[ 7, 8, 9],
[10, 11, 12]])
print(x[2]) # 因為最后一塊資料不足,所以只有一行,而不是兩行
tensor([[13, 14, 15]])
#### 均勻切割,根據第二個維度進行切割,每塊包含2個元素
x = torch.split(a,2,1)
print(x[0])
tensor([[ 1, 2],
[ 4, 5],
[ 7, 8],
[10, 11],
[13, 14]])
print(x[1])
tensor([[ 3],
[ 6],
[ 9],
[12],
[15]])
#### 自定義切割,根據第二個維度切割,一共切割成兩塊,第一個塊包含1個元素(也就是1列),第二塊包含2個元素(也就是2列)
x = torch.split(a,[1,2],1)
print(x[0])
tensor([[ 1],
[ 4],
[ 7],
[10],
[13]])
print(x[1])
tensor([[ 2, 3],
[ 5, 6],
[ 8, 9],
[11, 12],
[14, 15]])
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/225790.html
標籤:AI
上一篇:基于opencv和 yolo 遇到的bug ‘cv::dnn::dnn4_v20200310::readNetFromDarknet‘
下一篇:無人機——遙控器篇(三)
