官术网_书友最值得收藏!

3.1 張量

張量是所有DL工具包的基本組成部分。名字聽起來很神秘,但本質上張量就是一個多維數組。用數學知識來類比,單個數字就像點,是零維的,向量就像線段,是一維的,矩陣則是二維的對象。三維數字的集合可以用平行六面體表示,但它們不像矩陣一樣有特定的名稱。我們可以用“張量”來表示高維集合,如圖3.1所示。

054-01

圖3.1 從一個數字到n維張量

需要注意的是,在DL中所使用的張量和在張量演算或張量代數中所用的張量相比,只在部分層面上相關。在DL中,張量是任意多維的數組,但在數學中,張量是向量空間之間的映射,在某些情況下可以表示為多維數組,但背后具有更多的語義信息。數學家通常會對任何使用公認數學術語來命名不同事物的人皺眉,因此要當心!

3.1.1 創建張量

如果你熟悉NumPy庫,那你應該知道其主要目的是以通用的方式處理多維數組。在NumPy中,這樣的數組沒被稱為張量,但事實上,它們就是張量。張量在科學計算中被廣泛用作數據的通用存儲方式。例如,彩圖會被編碼成具有寬度、高度和色值的三維張量。

除了維度之外,元素類型也是張量的特征之一。PyTorch支持八種類型,包括三種浮點類型(16位、32位和64位)和五種整數類型(有符號8位、無符號8位、16位、32位和64位)。不同類型的張量用不同的類表示,其中最常用的是torch.FloatTensor(對應32位浮點類型)、torch.ByteTensor(無符號8位整數)、torch.LongTensor(有符號64位整數)。其余的可以在PyTorch的文檔中查到。

有三種方法可以在PyTorch中創建張量:

  • 通過調用所需類型的構造函數。
  • 通過將NumPy數組或Python列表轉換為張量。在這種情況下,類型將從數組的類型中獲取。
  • 通過要求PyTorch創建帶有特定數據的張量。例如,可以使用torch.zeros()函數創建一個全為零的張量。

下面是上述方法的實現示例:

054-02

在這里,我們導入了PyTorch和NumPy,并創建未初始化的3×2的張量。默認情況下,PyTorch會為張量分配內存,但不進行初始化。要清除張量的內容,需要使用以下操作:

055-01

張量有兩種類型的操作:inplace和functional。inplace操作需在函數名稱后附加一個下劃線,作用于張量的內容。然后,會返回對象本身。functional操作是創建一個張量的副本,對其副本進行修改,而原始張量保持不變。從性能和內存角度來看,inplace方式通常更為高效。

通過其構造函數創建張量的另一種方法是提供Python可迭代對象(例如列表或元組),它將被用作新創建張量的內容:

055-02

下面的代碼用NumPy創建了一個全零張量:

055-03

torch.tensor方法接受NumPy數組作為參數,并創建一個適當形狀的張量。在前面的示例中,我們創建了一個由零初始化的NumPy數組,默認情況下,該數組創建一個double(64位浮點數)數組。因此,生成的張量具有DoubleTensor類型(在前面的示例中使用dtype值顯示)。在DL中,通常不需要雙精度,因為使用雙精度會增加內存和性能開銷。通常的做法是使用32位浮點類型,甚至使用16位浮點類型,這已經能夠滿足需求了。要創建這樣的張量,需要明確指定NumPy數組的類型:

055-04

作為可選項,可以在dtype參數中將所需張量的類型提供給torch.tensor函數。但是,請小心,因為此參數期望傳入PyTorch類型規范,而不是NumPy類型規范。PyTorch類型保存在torch包中,例如torch.float32torch.uint8

055-05

007-03兼容性說明

0.4.0版本中添加了torch.tensor()方法和顯式PyTorch類型規范,這是朝著簡化張量創建邁出的一步。在以前的版本中,推薦使用torch.from_numpy()函數來轉換NumPy數組,但是在處理Python列表和NumPy數組的組合時遇到了問題。from_numpy()函數仍可實現后向兼容性,但不推薦使用此函數,而推薦使用更靈活的torch.tensor()方法。

3.1.2 零維張量

從0.4.0版本開始,PyTorch已經支持了與標量相對應的零維張量(在圖3.1的左側)。這種張量可能是某些操作(例如對張量中的所有值求和)的結果。這種情況以前是通過創建維度為1的張量(向量)來處理的。

該解決方案是有效的,但它并不簡單,因為需要額外的索引才能訪問值。現在,已經支持零維張量并由合適的函數返回,并且可以通過torch.tensor()函數創建。為了訪問這種張量的實際Python值,可以使用特殊的item()方法:

056-01

3.1.3 張量操作

你可以對張量執行很多操作,因為操作太多,無法一一列出。通常,在PyTorch的官方文檔(http://pytorch.org/docs/)中搜索就足夠使用了。需要指出的是,除了前文所討論的inplace和functional(即帶有下劃線的函數和不帶下劃線的函數,例如abs()abs_()),還有兩個地方可以查找操作:torch包和張量類。在第一種情況下,函數通常接受張量作為參數。在第二個中,函數作用于張量上。

在大多數情況下,張量操作試圖和NumPy中相應的操作等效,因此,如果NumPy中存在一些不是非常專有的函數,那么PyTorch中也可能會有,例如torch.stack()torch.transpose()torch.cat()

3.1.4 GPU張量

PyTorch透明地支持CUDA GPU,這意味著所有操作都有兩個版本(CPU和GPU)供自動選擇。使用哪個版本操作根據所操作的張量類型決定。

我提到的每種張量類型都是針對CPU的,并且具有與之對應的GPU類型。唯一的區別是GPU張量在torch.cuda包中,而不是在torch中。例如,torch.FloatTensor是在CPU內存中的32位浮點張量,而torch.cuda.FloatTensor是在GPU中的32位浮點張量。

為了從CPU轉換到GPU,有一個to(device)的張量方法,可以創建張量的副本到指定設備(可以是CPU或GPU)。如果張量已經在相應的設備上,那么什么也不會發生,并且返回原始張量。可以用不同的方式指定設備類型。首先,可以僅傳遞設備的字符串名稱,對于CPU內存為“cpu”,對于GPU可用“cuda”。GPU設備可以在冒號之后指定一個可選設備的索引。例如,系統中的第二個GPU可以用“cuda:1”尋址(索引從零開始)。

to()方法中指定設備的另一種更為有效的方法是使用torch.device類,該類接受設備名稱和可選索引。它有device屬性,所以可以訪問張量當前所在的設備。

057-01

上面的代碼在CPU上創建了一個張量,然后將其復制到GPU中。兩個副本均可用于計算,并且所有GPU特有的機制對用戶都是透明的:

057-02

007-03兼容性說明

to()方法和torch.device類是在0.4.0中引入的。在以前的版本中,CPU和GPU之間的相互復制是分開的,分別通過單獨的方法CPU()cuda()來執行,需要添加額外的代碼行來顯式地將張量轉換成它們的CUDA版本。在最新的版本中,你可以在程序開始時創建一個想要的torch.device對象,然后在創建的每一個張量上使用to(device)。張量中的舊方法,cpu()cuda()仍然存在,如果想確保一個張量在CPU或GPU中,而不管它的原始位置,使用舊方法可能會更方便。

主站蜘蛛池模板: 金塔县| 策勒县| 开阳县| 张家口市| 临西县| 昭通市| 宣威市| 肇州县| 宁安市| 宣威市| 右玉县| 浦北县| 卓资县| 兴山县| 万全县| 成都市| 酉阳| 齐河县| 新龙县| 武定县| 威宁| 化德县| 岐山县| 长武县| 修文县| 南召县| 民县| 资溪县| 宁阳县| 永修县| 铁岭县| 外汇| 彩票| 日土县| 永平县| 烟台市| 迭部县| 江阴市| 汾西县| 富源县| 社会|