Pytorch | 詳解Pytorch科學計算包——Tensor

本文始發於個人公衆號:TechFlow,原創不易,求個關注


今天是Pytorch專題的第二篇,我們繼續來了解一下Pytorch中Tensor的用法。

上一篇文章當中我們簡單介紹了一下如何創建一個Tensor,今天我們繼續深入Tensor的其他用法


tensor操作


size()和shape


我們可以用size()函數或者直接調用tensor當中的shape屬性獲取一個tensor的大小,這兩者是等價的,一般情況下我們用前者多一些。


view


我們可以通過view改變一個tensor的shape,它會根據我們指定的shape返回一個新的tensor

需要注意的是,view返回的是原數據的一個引用,也就是說我們改變原數據,view出來的結果會同樣發生變化。

在上面這個例子當中,我們把原tensor x中的[0, 1]的位置修改成了2,我們print y會發現y當中的元素同樣發生了變化。


numel


我們可以用numel獲取tenosr當中元素的數量:


squeeze和unsqueeze


我們可以用squeeze來減少tensor的維度,而使用unsqueeze來增加一個tenor的維度

其中unsqueeze接收一個參數,允許我們指定我們希望增加的維度。我們可以通過size明顯看到數據的變化:

squeeze是減少維度,相比之下沒有那麼多操作,它會自動將長度是1的維度消除,如果沒有一個維度長度是1,也就是說當前已經是最簡的形式,那麼什麼也不會變化。

也支持使用另一個數組作爲索引訪問數據:


Tensor索引


Tensor當中支持與Numpy數組類似的索引操作,語法也非常相似。和Numpy一樣,索引得到的結果是原數據的引用,也就是說我們修改其中一個,另一個也會跟着發生變動。

它支持多維索引:

也支持切片:

也可以通過bool數組獲取元素:


Tensor運算


Tensor當中有大量的運算api,我們只列舉其中最常用的幾種,剩下的使用頻率不高,大家可以用到的時候再去查閱相應的文檔。

加減乘除

Tensor當中支持好幾種運算的方法,我們以加法爲例來了解一下。首先支持通過符號直接運算:

第二種方法是我們可以調用torch當中的函數,比如加法的函數就是add。

如果使用torch當中的函數進行計算的話,它還支持out參數,允許我們傳入一個tensor,它會將計算結果存儲tensor當中。

除此之外,它還允許我們進行inplace操作,也就是在原tensor值的基礎上直接修改,而不是通過函數值返回。和Numpy當中傳入inplace參數的設計不同,Tensor當中是通過api區分的,在原函數名下增加一個下劃線即是inplace的api,比如add的inplace方法是add_。


矩陣點乘


在機器學習領域當中,矩陣點乘是一個經常用到的操作。因爲爲了節省時間,我們通常會把樣本和特徵以及各類參數向量化,通過矩陣或者是向量點乘的形式來進行加權求和、線性變換等操作。所以矩陣點乘非常重要,必定會用到。

在Numpy當中我們通過dot函數來計算兩個矩陣之間的內積,而在Tensor當中做了嚴格的區分,只有一維的向量纔可以使用dot計算點乘,多維的向量只能使用matmul計算矩陣的乘法。爲了簡化,還可以使用mm來代替matmul。如果你學過TensorFlow的話,你會發現matmul是TensorFlow當中點乘的api,Pytorch當中沿用了這個命名。

可以看到,mm和matmul計算得到的結果是一致的。


類型轉換


在Numpy當中,我們通過astype方法轉換類型,而在Tensor當中將這個方法拆分,每一種類型都有自己的轉化函數

比如我們想要將tensor轉化成int類型,調用的是int()方法,想要轉化成float類型調用的是float()方法。調用這些方法之後,會返回一個新的tensor。

Tensor當中定義了7種CPU類型和8種GPU類型:

我們可以調用內置函數將它們互相轉化,這些轉換函數有:long(), half(), int(), float(), double(), byte(), char(), short()。我相信這些函數的含義大家應該都可以理解。


轉置與變形


Tensor當中的轉置操作和Numpy中不太相同,在Numpy當中,我們通過.T或者是transpose方法來進行矩陣的轉置。如果是高維數組進行轉置,那麼Numpy會將它的維度完全翻轉。

而在Tensor當中區分了二維數組和高維數組,二維數組的轉置使用的函數是t(),它的用法和.T一樣,會將二維數組的兩個軸調換。

如果是高維數組調用t函數會報錯,如果我們要變換高維數組的形狀,可以調用transpose和permute兩個方法。先說transpose方法,它接收兩個int型參數,表示需要調換的兩個軸。比如一個形狀是[4, 3, 2]的矩陣,我們可以通過0,1,2表示它的所有軸,傳入兩個,指定想要調換的兩個軸:

而permute可以調換多個軸的位置,所以它接受的參數是一個int型的不定參數。我們傳入我們希望得到的軸的順序,Tensor會根據我們傳入的軸的順序對數據進行翻轉:

另外,t和transpose支持inplace操作,而permute不行,這也是他們顯著的區別之一。


設備之間移動


我們可以通過device這個屬性看到tensor當前所在的設備:

我們可以通過cuda函數將一個在CPU的tensor轉移到GPU,但是不推薦這麼幹。比較好的辦法是使用to方法來進行設備轉移

將tensor轉移到GPU上進行計算可以利用GPU的併發性能提升計算的效率,這是Pytorch當中常用的手段。to方法不僅可以改變tensor的設備,還可以同時變更tensor當中元素的類型:


總結


雖然tensor擁有許多額外的功能和計算函數,但是tensor的意義並不僅僅如此。最重要的是,它可以提升我們的計算速度。這當中的原理也很簡單,因爲在Python的List當中,每一個元素其實都是一個對象。即使我們存儲的是一個int或者是float,Python都會將它們封裝成一個對象,這會帶來額外的開銷。如果只是少量的數據影響不大,如果是上百萬甚至是更大的量級,那麼兩者的差距就會非常大。另外一點就是tensor庫的底層也是C和C++,運行效率顯然Python更高。所以我們不能簡單地把它理解成一個計算包,對於深度學習來說,它並不僅僅只是計算。

Tensor當中還有許多其他的方法,這其中許多實用頻率很低加上篇幅的限制,我們不能一一窮盡,大家只需要對Tensor庫整體有一個映像,一些具體的使用方法和細節可以用到的時候再進行查詢。

本文基於滴滴雲GPU完成,租借滴滴雲GPU,使用滴滴雲AI大師碼2323,享受9折優惠。

如果喜歡本文,可以的話,請點個關注,給我一點鼓勵,也方便獲取更多文章。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章