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

3.2 PyTorch基礎(chǔ)

本章使用的機(jī)器學(xué)習(xí)庫(kù)是基于PyTorch的。PyTorch是由Facebook開(kāi)源的基于Python的機(jī)器學(xué)習(xí)庫(kù)[229]。本節(jié)我們簡(jiǎn)要介紹PyTorch的相關(guān)基礎(chǔ)知識(shí),包括Tensor的創(chuàng)建、操作、以及自動(dòng)求導(dǎo)。如果讀者想更深入了解PyTorch的使用,請(qǐng)參考PyTorch官方文檔(鏈接3-4)。

3.2.1 創(chuàng)建Tensor

Tensor是PyTorch的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),是一個(gè)高維的數(shù)組,可以在跨設(shè)備(CPU、GPU等)中存儲(chǔ),其作用類(lèi)似于Numpy中的ndarray。PyTorch中內(nèi)置了多種創(chuàng)建Tensor的方式,我們首先導(dǎo)入torch模塊。

? 僅指定形狀大小:可以?xún)H僅通過(guò)指定形狀大小,自動(dòng)生成沒(méi)有初始化的任意值,包括empty、IntTensor、FloatTensor等接口。

? 通過(guò)隨機(jī)化函數(shù)(PyTorch內(nèi)置了很多隨機(jī)化函數(shù))創(chuàng)建具有某種初始分布的值,比如服從標(biāo)準(zhǔn)正態(tài)分布的randn、服從均勻分布的rand、服從高斯分布的normal等,一般我們只需要指定輸出tensor值的形狀。

? 通過(guò)填充特定的元素值來(lái)創(chuàng)建,比如通過(guò)ones函數(shù)構(gòu)建一個(gè)全1矩陣,通過(guò)zeros函數(shù)構(gòu)建全0矩陣,通過(guò)full函數(shù)指定其他特征值。

更多Tensor的創(chuàng)建方式,讀者也可以參考PyTorch的官方文檔,這里不再詳述。

3.2.2 Tensor與Python數(shù)據(jù)結(jié)構(gòu)的轉(zhuǎn)換

除了上一小節(jié)提到的創(chuàng)建方式,PyTorch還可以將已有Python數(shù)據(jù)結(jié)構(gòu)(如list,numpy.ndarray等)轉(zhuǎn)換為T(mén)ensor的接口。PyTorch的運(yùn)算都以Tensor為單位進(jìn)行,在運(yùn)算時(shí)都需要將非Tensor的數(shù)據(jù)格式轉(zhuǎn)化為T(mén)ensor,主要的轉(zhuǎn)換函數(shù)包括tensor、as_tensor、from_numpy。用戶(hù)只需要將list或者ndarray數(shù)值作為參數(shù)傳入,即可自動(dòng)轉(zhuǎn)換為PyTorch的Tensor數(shù)據(jù)結(jié)構(gòu)。

需要注意的是,as_tensor和from_numpy會(huì)復(fù)用原數(shù)據(jù)的內(nèi)存空間,也就是說(shuō),原數(shù)據(jù)或者Tensor的任意一方改變,都會(huì)導(dǎo)致另一方的數(shù)據(jù)改變。

3.2.3 數(shù)據(jù)操作

Tensor支持多種數(shù)據(jù)運(yùn)算,例如四則運(yùn)算、數(shù)學(xué)運(yùn)算(如指數(shù)運(yùn)算、對(duì)數(shù)運(yùn)算等)等。并且,對(duì)于每一種數(shù)據(jù)的操作,PyTorch提供了多種不同的方式來(lái)完成。我們以加法運(yùn)算為例,PyTorch有三種實(shí)現(xiàn)加法運(yùn)算的方式。

? 方式一:直接使用符號(hào)“+”來(lái)完成。

? 方式二:使用add函數(shù)。

? 方式三:PyTorch對(duì)數(shù)據(jù)的操作還提供了一種獨(dú)特的inplace模式,即運(yùn)算后的結(jié)果直接替換原來(lái)的值,而不需要額外的臨時(shí)空間。這種inplace版本一般在操作函數(shù)后面都有后綴“_”。

對(duì)于其他的張量四則運(yùn)算操作,也可以仿照上面的三種方法來(lái)完成。Tensor的另一種常見(jiàn)操作是改變形狀。PyTorch使用view()來(lái)改變Tensor中的形狀,如下所示。

Tensor的創(chuàng)建默認(rèn)是存儲(chǔ)在CPU上的。如果設(shè)備中有GPU,為了提高數(shù)據(jù)操作的速度,我們可以將數(shù)據(jù)放置在GPU中。PyTorch提供了方便的接口將數(shù)據(jù)在兩者之間切換。

如果想將數(shù)據(jù)重新放置在CPU中,只需要執(zhí)行下面的操作即可。

3.2.4 自動(dòng)求導(dǎo)

自動(dòng)求導(dǎo)功能是PyTorch進(jìn)行模型訓(xùn)練的核心模塊,文獻(xiàn)[228]對(duì)PyTorch的自動(dòng)求導(dǎo)功能進(jìn)行了深入的講解和原理剖析。當(dāng)前,PyTorch的自動(dòng)求導(dǎo)功能通過(guò)autograd包實(shí)現(xiàn)。autograd包求導(dǎo)時(shí),首先要求Tensor將requires_grad屬性設(shè)置為T(mén)rue;隨后,PyTorch將自動(dòng)跟蹤該Tensor的所有操作;當(dāng)調(diào)用backward()進(jìn)行反向計(jì)算時(shí),將自動(dòng)計(jì)算梯度值并保存在grad屬性中。下面我們可以通過(guò)一個(gè)例子來(lái)查看自動(dòng)求導(dǎo)的過(guò)程,計(jì)算過(guò)程如下。

這是一個(gè)比較簡(jiǎn)單的數(shù)學(xué)運(yùn)算求解,上面的代碼塊所要求解的計(jì)算公式可以表示為

PyTorch采用的是動(dòng)態(tài)圖機(jī)制,也就是說(shuō),在訓(xùn)練模型時(shí)候,每迭代一次都會(huì)構(gòu)建一個(gè)新的計(jì)算圖。計(jì)算圖代表的是程序中變量之間的相互關(guān)系,因此,我們可以將式(3.1),表示為如圖3-4所示的計(jì)算圖。

圖3-4 對(duì)應(yīng)上面代碼示例的計(jì)算圖

當(dāng)對(duì)out變量執(zhí)行backward操作后,系統(tǒng)將自動(dòng)求取所有葉子變量對(duì)應(yīng)的梯度,這里的葉子節(jié)點(diǎn),就是我們的輸入變量x

但應(yīng)該注意的是,PyTorch在設(shè)計(jì)時(shí)為了節(jié)省內(nèi)存,沒(méi)有保留中間節(jié)點(diǎn)的梯度值,因此,如果用戶(hù)需要使用中間節(jié)點(diǎn)的梯度,或者自定義反向傳播算法(比如Guided Backpropagation[260],GBP),就需要用到PyTorch的Hooks機(jī)制,包括register_hook和register_backward_hook。這個(gè)技巧在卷積神經(jīng)網(wǎng)絡(luò)可視化中經(jīng)常使用[31,308]。Hooks機(jī)制是PyTorch的高級(jí)技巧,鑒于本書(shū)的寫(xiě)作目的和篇幅,我們不在此詳述,讀者可以查閱相關(guān)的資料[153]

通過(guò)對(duì)式(3.1)進(jìn)行求導(dǎo),得到out變量關(guān)于x的導(dǎo)數(shù)結(jié)果如下:

主站蜘蛛池模板: 沅江市| 兴海县| 兴安盟| 尖扎县| 尚志市| 儋州市| 闵行区| 玉山县| 阆中市| 萨嘎县| 津南区| 博客| 南通市| 邹城市| 娄底市| 普格县| 正安县| 那坡县| 屏山县| 丹江口市| 墨玉县| 桓台县| 泉州市| 邯郸县| 仁怀市| 安图县| 白玉县| 金山区| 定边县| 江安县| 闻喜县| 道孚县| 长海县| 阳江市| 凉山| 双流县| 尚义县| 舞钢市| 太原市| 蕉岭县| 施秉县|