淺談pytorch中stack和cat的及to_tensor的坑
初入計(jì)算機(jī)視覺(jué)遇到的一些坑
1.pytorch中轉(zhuǎn)tensor
x=np.random.randint(10,100,(10,10,10)) x=TF.to_tensor(x) print(x)
這個(gè)函數(shù)會(huì)對(duì)輸入數(shù)據(jù)進(jìn)行自動(dòng)歸一化,比如有時(shí)候我們需要將0-255的圖片轉(zhuǎn)為numpy類型的數(shù)據(jù),則會(huì)自動(dòng)轉(zhuǎn)為0-1之間
2.stack和cat之間的差別
stack
x=torch.randn((1,2,3)) y=torch.randn((1,2,3)) z=torch.stack((x,y))#默認(rèn)dim=0 print(z.shape) #torch.Size([2, 1, 2, 3])
所以stack的之后的數(shù)據(jù)也就很好理解了,z[0,...]的數(shù)據(jù)是x,z[1,...]的數(shù)據(jù)是y。
cat
z=torch.cat((x,y)) print(z.size()) #torch.Size([2, 2, 3])
cat之后的數(shù)據(jù) z[0,:,:]是x的值,z[1,:,:]是y的值。
其中最關(guān)鍵的是stack之后的數(shù)據(jù)的size會(huì)多出一個(gè)維度,而cat則不會(huì),有一個(gè)很簡(jiǎn)單的例子來(lái)說(shuō)明一下,比如要訓(xùn)練一個(gè)檢測(cè)模型,label是一些標(biāo)記點(diǎn),eg:[x1,y1,x2,y2]
送入網(wǎng)絡(luò)的加上batchsize則時(shí)Size:[batchsize,4],如果我已經(jīng)有了兩堆數(shù)據(jù),data1:Size[128,4],data2:Size[128,4],需要將這兩個(gè)數(shù)據(jù)合在一起的話目標(biāo)data:Size[256,4]。
顯然我們要做的是:torch.cat((data1,data2))
如果我們的數(shù)據(jù)是這樣:有100個(gè)label,每一個(gè)label被放進(jìn)一個(gè)list(data)中,[[x1,y1,x2,y2],[x1,y1,x2,y2],...]其中data是一個(gè)list長(zhǎng)度為100,而list中每一個(gè)元素是張圖片的標(biāo)簽,size為[4]我們需要將他們合一起成為一Size:[100,4]的的數(shù)據(jù)。
顯然我們要做的是torch.stack(data)。而且torch.stack的輸入?yún)?shù)為list類型!
補(bǔ)充:pytorch中的cat、stack、tranpose、permute、unsqeeze
pytorch中提供了對(duì)tensor常用的變換操作。
cat 連接
對(duì)數(shù)據(jù)沿著某一維度進(jìn)行拼接。cat后數(shù)據(jù)的總維數(shù)不變。
比如下面代碼對(duì)兩個(gè)2維tensor(分別為2*3,1*3)進(jìn)行拼接,拼接完后變?yōu)?*3還是2維的tensor。
代碼如下:
import torch torch.manual_seed(1) x = torch.randn(2,3) y = torch.randn(1,3) print(x,y)
結(jié)果:
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 2x3]
-1.5228 0.3817 -1.0276
[torch.FloatTensor of size 1x3]
將兩個(gè)tensor拼在一起:
torch.cat((x,y),0)
結(jié)果:
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
-1.5228 0.3817 -1.0276
[torch.FloatTensor of size 3x3]
更靈活的拼法:
torch.manual_seed(1) x = torch.randn(2,3) print(x) print(torch.cat((x,x),0)) print(torch.cat((x,x),1))
結(jié)果
// x
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 2x3]// torch.cat((x,x),0)
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 4x3]// torch.cat((x,x),1)
0.6614 0.2669 0.0617 0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661 0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 2x6]
stack,增加新的維度進(jìn)行堆疊
而stack則會(huì)增加新的維度。
如對(duì)兩個(gè)1*2維的tensor在第0個(gè)維度上stack,則會(huì)變?yōu)?*1*2的tensor;在第1個(gè)維度上stack,則會(huì)變?yōu)?*2*2的tensor。
見(jiàn)代碼:
a = torch.ones([1,2]) b = torch.ones([1,2]) c= torch.stack([a,b],0) // 第0個(gè)維度stack
輸出:
(0 ,.,.) =
1 1(1 ,.,.) =
1 1
[torch.FloatTensor of size 2x1x2]
c= torch.stack([a,b],1) // 第1個(gè)維度stack
輸出:
(0 ,.,.) =
1 1
1 1
[torch.FloatTensor of size 1x2x2]
transpose ,兩個(gè)維度互換
代碼如下:
torch.manual_seed(1) x = torch.randn(2,3) print(x)
原來(lái)x的結(jié)果:
0.6614 0.2669 0.0617
0.6213 -0.4519 -0.1661
[torch.FloatTensor of size 2x3]
將x的維度互換
x.transpose(0,1)
結(jié)果
0.6614 0.6213
0.2669 -0.4519
0.0617 -0.1661
[torch.FloatTensor of size 3x2]
permute,多個(gè)維度互換,更靈活的transpose
permute是更靈活的transpose,可以靈活的對(duì)原數(shù)據(jù)的維度進(jìn)行調(diào)換,而數(shù)據(jù)本身不變。
代碼如下:
x = torch.randn(2,3,4) print(x.size()) x_p = x.permute(1,0,2) # 將原來(lái)第1維變?yōu)?維,同理,0→1,2→2 print(x_p.size())
結(jié)果:
torch.Size([2, 3, 4])
torch.Size([3, 2, 4])
squeeze 和 unsqueeze
常用來(lái)增加或減少維度,如沒(méi)有batch維度時(shí),增加batch維度為1。
squeeze(dim_n)壓縮,減少dim_n維度 ,即去掉元素?cái)?shù)量為1的dim_n維度。
unsqueeze(dim_n),增加dim_n維度,元素?cái)?shù)量為1。
上代碼:
# 定義張量 import torch b = torch.Tensor(2,1) b.shape Out[28]: torch.Size([2, 1]) # 不加參數(shù),去掉所有為元素個(gè)數(shù)為1的維度 b_ = b.squeeze() b_.shape Out[30]: torch.Size([2]) # 加上參數(shù),去掉第一維的元素為1,不起作用,因?yàn)榈谝痪S有2個(gè)元素 b_ = b.squeeze(0) b_.shape Out[32]: torch.Size([2, 1]) # 這樣就可以了 b_ = b.squeeze(1) b_.shape Out[34]: torch.Size([2]) # 增加一個(gè)維度 b_ = b.unsqueeze(2) b_.shape Out[36]: torch.Size([2, 1, 1])
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python Web程序部署到Ubuntu服務(wù)器上的方法
在本文記錄了我在Ubuntu中部署Flask Web站點(diǎn)的過(guò)程, 其中包括用戶創(chuàng)建、代碼獲取、Python3環(huán)境的安裝、虛擬環(huán)境設(shè)置、uWSGI啟動(dòng)程序設(shè)置,并將Nginx作為前端反向代理,需要的朋友參考下吧2018-02-02教你用Python實(shí)現(xiàn)短信驗(yàn)證碼的發(fā)送
當(dāng)我們?cè)谧?cè)一個(gè)網(wǎng)頁(yè)時(shí),有的網(wǎng)頁(yè)會(huì)讓必須要短信驗(yàn)證、郵箱驗(yàn)證,才可以進(jìn)行賬號(hào)的注冊(cè),下面這篇文章主要給大家介紹了關(guān)于用Python實(shí)現(xiàn)短信驗(yàn)證碼發(fā)送的相關(guān)資料,需要的朋友可以參考下2022-12-12python?包實(shí)現(xiàn)?time?時(shí)間管理操作
這篇文章主要介紹了python包實(shí)現(xiàn)time時(shí)間管理操作,文章通過(guò)獲取當(dāng)前時(shí)間戳,即當(dāng)前系統(tǒng)內(nèi)表示時(shí)間的一個(gè)浮點(diǎn)數(shù),下文更多相關(guān)內(nèi)容需要的小伙伴可以參考一下2022-04-04Python實(shí)現(xiàn)動(dòng)態(tài)添加類的屬性或成員函數(shù)的解決方法
這篇文章主要介紹了Python實(shí)現(xiàn)動(dòng)態(tài)添加類的屬性或成員函數(shù)的解決方法,在類似插件開(kāi)發(fā)的時(shí)候會(huì)比較有用,需要的朋友可以參考下2014-07-07跟老齊學(xué)Python之再深點(diǎn),更懂list
對(duì)于list,由于她的確非常非常龐雜,在python中應(yīng)用非常廣泛,所以,雖然已經(jīng)介紹完畢了基礎(chǔ)內(nèi)容,這里還要用一講深入一點(diǎn)點(diǎn),往往越深入越...2014-09-09將Django項(xiàng)目遷移到linux系統(tǒng)的詳細(xì)步驟
這篇文章主要介紹了將Django項(xiàng)目遷移到linux系統(tǒng)的詳細(xì)步驟,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03教你在Excel中調(diào)用Python腳本實(shí)現(xiàn)數(shù)據(jù)自動(dòng)化處理的方法
Excel是全世界最流行的編程語(yǔ)言,Excel已經(jīng)可以實(shí)現(xiàn)編程語(yǔ)言的算法,因此它是具備圖靈完備性的,和JavaScript、Java、Python一樣,今天通過(guò)本文給大家介紹下Python數(shù)據(jù)自動(dòng)化處理的相關(guān)知識(shí),感興趣的朋友一起看看吧2022-02-02