Pytorch tensors (張量)
Introduce
Pytorch的Tensors可以理解成Numpy中的數(shù)組ndarrays(0維張量為標(biāo)量,一維張量為向量,二維向量為矩陣,三維以上張量統(tǒng)稱為多維張量),但是Tensors 支持GPU并行計(jì)算,這是其最大的一個(gè)優(yōu)點(diǎn)。
本文首先介紹tensor的基礎(chǔ)用法,主要tensor的創(chuàng)建方式以及tensor的常用操作。
tensors 基礎(chǔ)用法
- tensors 常用創(chuàng)建方法
# 創(chuàng)建一個(gè)5行3列的矩陣,數(shù)據(jù)類型為long
x = torch.empty(5,3,dtype=torch.long)
# 類似的還有如下創(chuàng)建方式:
x = torch.zeros()
x = torch.ones()
x = torch.ones_like(z) # 創(chuàng)建一個(gè)與z形狀相同的全1張量。
x = torch.rand()
x = torch.eye(2,2) # 2x2單位矩陣
x = torch.tensor([5.5, 3.0]) # 向量
# x = torch.tensor(5.5) 標(biāo)量
# x = torch.tensor([[5.5, 3.0]]) 矩陣
# 對x重新賦值(第一種是5X3全1矩陣,第二種是隨機(jī),size與x相同,新制定type覆蓋舊type)
x = x.new_ones(5,3,dtype=torch.double)
x = torch.randn_like(x,dtype=torch.float)
# tensor與numpy array的相互轉(zhuǎn)換,需要注意的是他們兩個(gè)用的都是共同的內(nèi)存空間,即不管哪一個(gè)的值發(fā)生改變,另外一個(gè)都會相應(yīng)改變
# 從numpy array創(chuàng)建tensor
x = torch.from_numpy(np.ones(5))
# tensor轉(zhuǎn)化為numpy array,調(diào)用.numpy()即可
y = x.numpy()
# 返回x的規(guī)模,返回值類型為元組tuple,張量也支持Numpy的shpae屬性
x.size()
# 改變張量的維度,與Numpy的reshape類似
x = torch.randn(4, 4) # torch.Size([4, 4])
y = x.view(16) # torch.Size([16]), equal to y = torch.reshape(x,[16])
z = x.view(-1, 8) # torch.Size([2, 8]),其中-1表示從其他維度大小推斷當(dāng)前維度大小
# note: 當(dāng)張量使用了permute和transpose后,tensor占用的內(nèi)存可能就變得不連續(xù)了,因此不能用view()函數(shù)來改變張量維度。必須先執(zhí)行函數(shù)contiguous()使tensor占用內(nèi)存空間連續(xù),其次再使用view()函數(shù)改變維度才可。但是后續(xù)Pytorch增加了函數(shù)reshape()來改變tensor維度,相當(dāng)于x.contigous().view()的功能,因此要改變維度直接使用y=torch.reshape(x,[16])即可。
- tensors 常用操作方式
# tensor的拼接
# cat(),不增加新的維度,在某維度上拼接tensor(理解向量或矩陣的拼接就行)
# example 1
x = torch.randn(2,3)
y = torch.randn(1,3)
z = torch.cat((x, y), 0) # 在0維(行)拼接y (y作為x的新行,增加行),維度為(3,3)
# example 2
x = torch.randn(2,3)
y = torch.randn(2,1)
z = torch.cat((x, y), 1) # 在1維(列)拼接y (y作為x的新列,增加列),維度為(2,4)
# tensor的堆疊
# stack(),增加新的維度,在新的維度上拼接tensor(無法想象,可以理解成新創(chuàng)建一個(gè)維度,然后把要堆疊的tensor放上去,新維度的大小就為要堆疊tensor的個(gè)數(shù))
# 以下例子請注意堆疊后新size中3的位置
# example 1
x = torch.randn(1,2)
y = torch.randn(1,2)
z = torch.randn(1,2)
p = torch.cat((x, y,z), 0) # 在第0維度上堆疊,維度為 (3x1x2)
# example 2
x = torch.randn(1,2)
y = torch.randn(1,2)
z = torch.randn(1,2)
p = torch.cat((x, y,z), 1) # 在第1維度上堆疊,維度為 (1x3x2)
# example 3
x = torch.randn(1,2)
y = torch.randn(1,2)
z = torch.randn(1,2)
p = torch.cat((x, y,z), 2) # 在第2維度上堆疊,維度為 (1x2x3)
# tensor交換兩個(gè)維度,size中對應(yīng)維度大小也交換,二維情況下類比于二維矩陣的轉(zhuǎn)置
# transpose()
# exmample
x = torch.randn(1,2)
x = x.transpose(0,1) # equal to x.transpose_(0,1)
print(x.size()) # torch.Size([2, 1])
# note: 一般情況下,函數(shù)后面有加_,如x.transpose_(0,1),才會直接對原始tensor x進(jìn)行操作,否則是返回一個(gè)新的tensor,而原始tensor x保持不變。
# tensor交換多個(gè)維度,size中對應(yīng)維度大小也交換
# permute()
# example
x = torch.randn(1,2,3)
x = x.permute(2,0,1) # 理解為第零維度用原始第二維度填充,第一維度用原始第零維度填充,第二維度用原始第一維度填充
print(x.size()) # torch.Size([3, 1, 2])
# tensor壓縮和解壓維度
# squeeze(dim):如果dim維為大小為1,則去除,否則不做任何變化。如若不指定dim,則去除所有大小為1的維度。
# unsqueeze(dim):在dim上添加一個(gè)維度,維度大小為1。
# example
z = torch.randn(1,2)
z.squeeze_()
print(z.size()) # torch.Size([2])
z.unsqueeze_(1)
print(z.size()) # torch.Size([2, 1])
# note: 另外一些常用的方法,比如.sum()、.max()、x[1:]等基本操作都與numpy中的用法類似。