Python深度學(xué)習(xí)入門(從零構(gòu)建CNN和RNN)_第1頁
Python深度學(xué)習(xí)入門(從零構(gòu)建CNN和RNN)_第2頁
Python深度學(xué)習(xí)入門(從零構(gòu)建CNN和RNN)_第3頁
Python深度學(xué)習(xí)入門(從零構(gòu)建CNN和RNN)_第4頁
Python深度學(xué)習(xí)入門(從零構(gòu)建CNN和RNN)_第5頁
已閱讀5頁,還剩175頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

Python

深度學(xué)習(xí)入門

從零構(gòu)建CNN和RNN

目錄

第1章基本概念

1.1函數(shù)

數(shù)學(xué)

小意圖

代碼

1.2導(dǎo)數(shù)

數(shù)學(xué)

示意圖

代碼

1.3嵌套函數(shù)

數(shù)學(xué)

示意圖

代碼

1.4鏈?zhǔn)椒▌t

數(shù)學(xué)

示意圖

代碼

1.5示例介紹

數(shù)學(xué)

示意圖

代碼

1.6多輸入函數(shù)

數(shù)學(xué)

示意圖

代碼

1.7多輸入函數(shù)的導(dǎo)數(shù)

數(shù)學(xué)

示意圖

代碼

1.8多向量輸入函數(shù)

數(shù)學(xué)

1.9基于已有特征創(chuàng)建新特征

數(shù)學(xué)

示意圖

代碼

1.10多向量輸入函數(shù)的導(dǎo)數(shù)

數(shù)學(xué)

示意圖

代碼

1.11向量函數(shù)及其導(dǎo)數(shù):再進(jìn)一步

數(shù)學(xué)

示意圖

代碼

向量函數(shù)及其導(dǎo)數(shù):后向傳遞

1.12包含兩個(gè)二維矩陣輸入的計(jì)算圖

數(shù)學(xué)

示意圖

代碼

1.13有趣的部分:后向傳遞

數(shù)學(xué)

示意圖

代碼

1.14小結(jié)

第2章基本原理

2.1監(jiān)督學(xué)習(xí)概述

2.2監(jiān)督學(xué)習(xí)模型

2.3線性回歸

2.3.1線性回歸:示意圖

2.3.2線性回歸:更有用的示意圖和數(shù)學(xué)

2.3.3加入截距項(xiàng)

2.3.4線性回歸:代碼

2.4訓(xùn)練模型

2.4.1計(jì)算梯度:示意圖

2.4.2計(jì)算梯度:數(shù)學(xué)和一些代碼

2.4.3計(jì)算梯度:完整的代碼

2.4.4使用梯度訓(xùn)練模型

2.5評估模型:訓(xùn)練集與測試集

2.6評估模型:代碼

分析最重要的特征

2.7從零開始構(gòu)建神經(jīng)網(wǎng)絡(luò)

2.7.1步驟1:一系列線性回歸

2.7.2步驟2:一個(gè)非線性函數(shù)

2.7.3步驟3:另一個(gè)線性回歸

2.7.4示意圖

2.7.5代碼

2.7.6神經(jīng)網(wǎng)絡(luò):后向傳遞

2.8訓(xùn)練和評估第一個(gè)神經(jīng)網(wǎng)絡(luò)

發(fā)生這種情況的兩個(gè)原因

2.9小結(jié)

第3章從零開始深度學(xué)習(xí)

3.1定義深度學(xué)習(xí)

3.2神經(jīng)網(wǎng)絡(luò)的構(gòu)成要素:運(yùn)算

3.2.1人意圖

3.2.2代碼

3.3神經(jīng)網(wǎng)絡(luò)的構(gòu)成要素:層

示意圖

3.4在構(gòu)成要素之上構(gòu)建新的要素

3.4.1層的藍(lán)圖

3.4.2稠密層

3.5NeuralNetwork類和其他類

3.5.1示意圖

3.5.2代碼

3.5.3Loss類

3.6從零開始構(gòu)建深度學(xué)習(xí)模型

3.6.1實(shí)現(xiàn)批量訓(xùn)練

3.6.2NeuralNetwork:代碼

3.7優(yōu)化器和訓(xùn)練器

3.7.1優(yōu)化器

3.7.2訓(xùn)練器

3.8整合

第一個(gè)深度學(xué)習(xí)模型

3.9小結(jié)與展望

第4章擴(kuò)展

4.1美于神經(jīng)網(wǎng)絡(luò)的一些直覺

4.2softmax交叉場損失函數(shù)

4.2.1組件1:softmax函數(shù)

4.2.2組件2:交叉端損失

4.2.3關(guān)于激活函數(shù)的注意事項(xiàng)

4.3實(shí)驗(yàn)

4.3.1數(shù)據(jù)預(yù)處理

4.3.2模型

4.3.3實(shí)驗(yàn):softmax交叉端損失函數(shù)

4.4動(dòng)量

4.4.1理解動(dòng)量

4.4.2在Optimizer類中實(shí)現(xiàn)動(dòng)量

4.4.3實(shí)驗(yàn):帶有動(dòng)量的隨機(jī)梯度下降

4.5學(xué)習(xí)率衰減

4.5.1學(xué)習(xí)率衰減的類型

4.5.2實(shí)驗(yàn):學(xué)習(xí)率衰減

4.6權(quán)重初始化

4.6.1數(shù)學(xué)和代碼

4.6.2實(shí)驗(yàn):權(quán)重初始化

4.7dropout

4.7.1定

實(shí)

4.7.2現(xiàn)

實(shí)

4.7.3融

4.8d

第5CNN

5.1神經(jīng)網(wǎng)絡(luò)與表征學(xué)習(xí)

5.1.1針對圖像數(shù)據(jù)的不同架構(gòu)

5.1.2卷積運(yùn)算

5.1.3多通道卷積運(yùn)算

5.2卷積層

5.2.1實(shí)現(xiàn)意義

5.2.2卷積層與全連接層的區(qū)別

5.2.3利用卷積層進(jìn)行預(yù)測:Flatten層

5.2.4池化層

5.3實(shí)現(xiàn)多通道卷積運(yùn)算

5.3.1前向傳遞

5.3.2后向傳遞

5.3.3批處理

5.3.4二維卷積

5.3.5最后一個(gè)元素:通道

5.4使用多通道卷積運(yùn)算訓(xùn)練CNN

5.4.1Flatten運(yùn)算

5.4.2完整的Conv2D層

5.4.3實(shí)驗(yàn)

5.5小結(jié)

第6章RNN

6.1關(guān)鍵限制:處理分支

6.2自動(dòng)微分

編碼梯度累積

6.3RNN的動(dòng)機(jī)

6.4RNN簡介

6.4.1RNN的第一個(gè)類:RNNLayer

6.4.2RNN的第二個(gè)類:RNNNode

6.4.3整合RNNNode類和RNNLayer類

6.4.4后向傳遞

6.5RNN:代碼

6.5.1RNNLayer類

6.5.2RNNNode類的基本元素

6.5.3vanillaRNNNode類

6.5.4vanillaRNNNode類的局限性

6.5.5GRUNode類

6.5.6LSTMNode類

6.5.7基于字符級RNN?諾言模型的數(shù)據(jù)表示

6.5.8其他語言建模任務(wù)

6.5.9組合RNNLayer類的變體

6.5.10將全部內(nèi)容整合在一起

6.6小結(jié)

第7章PyTorch

7.1PyTorchTensor

7.2使用PyTorch進(jìn)行深度學(xué)習(xí)

7.2.1PyTorch元素:Model類及其Layer類

7.2.2使用PyTorch實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)基本要素:DenseLayer類

7.2.3示例:基于PyTorch的波士頓房價(jià)模型

7.2.4PyTorch元素:Optimizer類和Loss類

7.2.5PyTorch元素:Trainer類

7.2.6PyTorch優(yōu)化學(xué)習(xí)技術(shù)

7.3PyTorch中的CNN

DataLoader類和transforms模塊

7.4PyTorch中的LSTM

7.5后記:通過自編碼器進(jìn)行無監(jiān)督學(xué)習(xí)

7.5.1表征學(xué)習(xí)

7.5.2應(yīng)對無標(biāo)簽場景的方法

7.5.3在PyTorch中實(shí)現(xiàn)自編碼器

7.5.4更強(qiáng)大的無監(jiān)督學(xué)習(xí)測試及解決方案

7.6小結(jié)

附錄深入探討

矩陣鏈?zhǔn)椒▌t

關(guān)于偏差項(xiàng)的損失梯度

通過矩陣乘法進(jìn)行卷積

第1章基本概念

不要記住這些公式。如果能理解這些概念,那么你就可以自己發(fā)明符號。

----JohnCochrane,InvestmentsNotes

本章旨在解釋一些基本的思維模型,這些模型對于理解神經(jīng)網(wǎng)絡(luò)的工作原理至關(guān)重要。具體地

說,本章將介紹嵌套數(shù)學(xué)函數(shù)(nestedmathematicalfunction)及其導(dǎo)數(shù)(derivative)。

我們將從最簡單的構(gòu)成要素開始逐步研究,證明可以構(gòu)建由函數(shù)鏈組成的復(fù)雜函數(shù)。即使其中

一個(gè)函數(shù)是接受多個(gè)輸入的矩陣乘法,也可以計(jì)算函數(shù)輸出相對于其輸入的導(dǎo)數(shù)。另外,理解

該過程對于理解神經(jīng)網(wǎng)絡(luò)至關(guān)重要,從第2章開始將涉及神經(jīng)網(wǎng)絡(luò)的內(nèi)容.

當(dāng)圍繞神經(jīng)網(wǎng)絡(luò)的基本構(gòu)成要素進(jìn)行研究時(shí),我們將從3個(gè)維度系統(tǒng)地描述所引入的每個(gè)概

念。

?以一個(gè)或多個(gè)方程式的形式所表示的數(shù)學(xué)。

?解釋過程的示意圖,類似于在參加編碼面試時(shí)畫在白板上的圖表。

?包含盡可能少的特殊語法的代碼(Pylhon是一個(gè)理想選擇)。

如前言所述,理解神經(jīng)網(wǎng)絡(luò)的一大挑戰(zhàn)是它需要多個(gè)思維模型。你在本章中就可以體會到這一

點(diǎn):對將討論的概念來說,以上3個(gè)維度分別代表不同的基本特征,只有把它們結(jié)合在一起,

才能對一些概念形成完整的認(rèn)識,比如嵌套數(shù)學(xué)函數(shù)如何以及為何起作用。注意,要完整地解

釋坤經(jīng)網(wǎng)絡(luò)的構(gòu)成要素,以上3個(gè)維度缺一不可。

明白了這一點(diǎn),接下來就可以開始本書的學(xué)習(xí)了。我將從一些非常簡單的構(gòu)成要素開始講解,

介紹如何基于這3個(gè)維度來理解不同的概念。第一個(gè)構(gòu)成要素是一個(gè)簡單但乂至關(guān)重要的概

念:函數(shù)。

1.1函數(shù)

什么是函數(shù)?如何描述函數(shù)?與神經(jīng)網(wǎng)絡(luò)一樣,函數(shù)也可以用多種方法描述,但沒有一種方法

能完整地描繪它。與其嘗試給出簡單的一句話描述,不如像盲人摸象那樣,依次根據(jù)每個(gè)維度

來了解函數(shù)。

數(shù)學(xué)

下面是兩個(gè)用數(shù)學(xué)符號描述的函數(shù)示例。

?/|(T)J2

■糜翻0地密軸嵯

以上有兩個(gè)函數(shù),分別為力和及當(dāng)輸入數(shù)字/時(shí),第一個(gè)函數(shù)將其轉(zhuǎn)換為了,第二個(gè)

函數(shù)則將其轉(zhuǎn)換為tnaxlJ.IJL

示意圖

下面是一種描繪函數(shù)的方法。

01.繪制一個(gè)T-U平面(其中才表示橫軸,V表示縱軸)。

02.繪制一些點(diǎn),其中,點(diǎn)的/坐標(biāo)是函數(shù)在某個(gè)范圍內(nèi)的輸入(通常是等距的),y坐標(biāo)

則是該范圍內(nèi)函數(shù)的輸出。

03.連接所繪制的點(diǎn)。

這種利用坐標(biāo)的方法是法國哲學(xué)家勒內(nèi)-笛卡兒發(fā)明的,它在許多數(shù)學(xué)領(lǐng)域非常有用,特別

是微積分領(lǐng)域。圖1T展示了以上兩個(gè)函數(shù)的示意圖。

平方函數(shù)RcLU函數(shù)

圖1-1:兩個(gè)連續(xù)、基本可微的函數(shù)

然而,還有另一種描繪函數(shù)的方法,這種方法在學(xué)習(xí)微積分時(shí)并沒有那么有用,但是對于思考

深度學(xué)習(xí)模型非常有幫助??梢园押瘮?shù)看作接收數(shù)字(輸入)并生成數(shù)字(輸出)的盒了,就

像小型工廠一樣,它們對輸入的處理有自己的內(nèi)部規(guī)則。圖卜2通過一般規(guī)則和具體的輸入

描繪了以上兩個(gè)函數(shù)。

定義:n

圖1-2:另一種描繪函數(shù)的方法

代碼

最后,可以使用代碼描述這兩個(gè)函數(shù)。在開始之前,先介紹一下NumPy這個(gè)Python庫,下

面會基于該庫編寫函數(shù)。

01.NumPy庫

NunPy是一個(gè)廣泛使用的Python庫,用于快速數(shù)值計(jì)算,其內(nèi)部大部分使用C語言編寫。

簡單地說,在神經(jīng)網(wǎng)絡(luò)中處理的數(shù)據(jù)將始終保存在一個(gè)多維數(shù)組中,主要是一維數(shù)組、二維數(shù)

組、三維數(shù)組或四維數(shù)組,尤其以二維數(shù)組或三維數(shù)組居多。NumPy庫中的ndarray類能夠

讓我們以直觀且快速的方式計(jì)算這些數(shù)組。舉一個(gè)最簡單的例子,如果將數(shù)據(jù)存儲在Python

列表或列表的嵌套列表中,則無法使用常規(guī)語法實(shí)現(xiàn)數(shù)據(jù)對位相加或相乘,但ndarray類可

以實(shí)現(xiàn):

print("Pythonlistoperations:*)

a=[1,2,3]

b=[4,5,6]

print(*a+b:/z,a+b)

try:

print(a*b)

exceptTypeError:

print(*a*bhasnomeaningforPythonlists*)

printO

printC,numpyarrayoperations:*)

a=np.array([1,2,3])

b=np.array([4,5,6])

print("a+b:",a+b)

print(*a*b<?a*b)

Pythonlistoperations:

a+b:[1,2,3,4,5,6]

a*bhasnomeaningforPythonlists

numpyarrayoperations:

a+b:[b7y]

a*b:[41018]

ndarray還具備n維數(shù)組所具有的多個(gè)特性:每個(gè)ndarray都具有n個(gè)軸(從0開始索

引),第一個(gè)軸為軸0,第二個(gè)軸為軸1,以此類推。另外,由于二維ndarray較為常見,

因此可以將軸0視為行,將軸1視為列,如圖1-3所示。

軸1

軸0

圖1-3:一個(gè)二維ndarray,其中軸0為行,軸1為列

NunPy庫的ndarray類還支持以直觀的方式對這些軸應(yīng)用函數(shù)。例如,沿軸0(二維數(shù)組的

行)求和本質(zhì)上就是沿該軸“折疊數(shù)組”,返回的數(shù)組匕原始數(shù)組少一個(gè)維度。對二維數(shù)組來

說,這相當(dāng)于對每一列進(jìn)行求和:

print('a:')

print(a)

printCa.sum(axis=0):,a.sum(axis=0))

print。a.sum(axis=l)/,a.sum(axis=D)

[[12]

[34]]

a.sum(axis=0):[46]

a.sum(axis=l):[37]

ndarray類支持將一維數(shù)組添加到最后一個(gè)軸上。對一個(gè)〃行。列的二維數(shù)組a而言,

這意味著可以添加長度為r的一維數(shù)組boNumPy將以直觀的方式進(jìn)行加法運(yùn)算,并將元素

添加到a的每一行中1。

a=np.array([[1,2,3],

[4,5,6]])

b=np.array([10,20,30])

print(*a+b:\n*?a+b)

[[112233]

[142536]]

02.類型檢查函數(shù)

如前所述,本書代碼的主要目標(biāo)是確保概念描述的準(zhǔn)確性和清晰性。隨著本書內(nèi)容的展開,這

將變得更具挑戰(zhàn)性,后文涉及編寫帶有許多參數(shù)的函數(shù),這些參數(shù)是復(fù)雜類的一部分。為了解

決這個(gè)問題,本書將在整個(gè)過程中使用帶有類型簽名的函數(shù)。例如,在第3章中,我們將使

用如下方式初始化神經(jīng)網(wǎng)絡(luò):

def_init_(self.

layers:List[Layer],

loss:Loss,

learning_rate:float=0.01)->None:

僅通過類型簽名,就能了解該類的用途。與此相對,考慮以下可用于定義運(yùn)算的類型簽名:

defoperation(xl,x2):

這個(gè)類型簽名本身并沒有給出任何提示。只有打印出每個(gè)對象的類型,查看對每個(gè)對象執(zhí)行的

運(yùn)算,或者根據(jù)名稱xl和x2進(jìn)行猜測,才能夠理解該函數(shù)的功能。這里可以改為定義具有

類型簽名的函數(shù),如下所示:

defoperational:ndarray,x2:ndarray)->ndarray:

很明顯,這是接受兩個(gè)ndarray的函數(shù),可以用某種方式將它們組合在一起,并瑜出該組合

的結(jié)果。由于它們讀起來更為清楚,因此本書將使用經(jīng)過類型檢查的函數(shù)。

03.NumPy庫中的基礎(chǔ)函數(shù)

了解前面的內(nèi)容后,現(xiàn)在來編寫之前通過NumPy庫定義的函數(shù):

defsquare(x:ndarray)->ndarray:

將輸入ndarray中的每個(gè)元素進(jìn)行平方運(yùn)算。

returnnp.power(x,2)

defleaky_relu(x:ndarray)->ndarray:

>>,

將LeakyReLU函數(shù)應(yīng)用于ndarray中的每個(gè)元素。

,,,

returnnp.maximum(0.2*x,x)

^卜NumPy庫有一個(gè)奇怪的地方,那就是可以通過使用np.(ndarray)或

ndarray.function_namc將許多函數(shù)應(yīng)用于ndarray。例如,前面的ReLU函數(shù)不以編寫成

x.clip(min=0)。本書將盡量保持一致,在整個(gè)過程中遵循np.function_name(ndarray)約定,

尤其會避免使用ndarray.T之類的技巧來轉(zhuǎn)置二維ndarray,而會使用

np.transpose{ndarray,(1,0))。

如果能通過數(shù)學(xué)、示意圖和代碼這3個(gè)維度來表達(dá)相同的基本概念,就說明你已經(jīng)初步擁有

了真正理解深度學(xué)習(xí)所需的靈活思維。

11這樣一來,后續(xù)便可以輕松地向矩陣乘法添加偏差。

1.2導(dǎo)數(shù)

像函數(shù)一樣,導(dǎo)數(shù)也是深度學(xué)習(xí)的一個(gè)非常重要的概念,大多數(shù)人可能很熟悉。同樣,導(dǎo)數(shù)也

可以用多種方式進(jìn)行描述。總體來說,函數(shù)在某一點(diǎn)上的導(dǎo)數(shù),可以簡單地看作函數(shù)輸出相對

于該點(diǎn)輸入的“變化率”。接下來基于前面介紹的3個(gè)維度來了解導(dǎo)數(shù),從而更好地理解導(dǎo)

數(shù)的原理。

數(shù)學(xué)

首先來從數(shù)學(xué)角度精確地定義導(dǎo)數(shù):可以使用一個(gè)數(shù)字來描述極限,即當(dāng)改變某個(gè)特定的輸入

值?時(shí),函數(shù)/輸出的變化:

通過為△設(shè)置非常小的值(例如0.001),可以在數(shù)值上近似此極限。因此,可以將導(dǎo)數(shù)計(jì)

算為:

A向肺磁

雖然近似準(zhǔn)確,但這只是完整導(dǎo)數(shù)思維模型的一部分,下面來從示意圖的維度認(rèn)識導(dǎo)數(shù)。

不意圖

采用一種熟悉的方式:在含有函數(shù)f圖像的笛卡兒坐標(biāo)系上,簡單地畫出該函數(shù)的一條切線,

則函數(shù)i在點(diǎn)n處的導(dǎo)數(shù)就是該線在點(diǎn)n處的斜率。正如本節(jié)中的數(shù)學(xué)描述一樣,這里也

可以通過兩種方式實(shí)際計(jì)算這條線的斜率。第一種方式是使用微積分來實(shí)際計(jì)算極限,第二種

方式是在n-0.001處和。f0.001處取連線/的斜率。后者如圖1-4所示,如果學(xué)過微

積分,應(yīng)該會很熟悉。

圖1-4:導(dǎo)數(shù)即為斜率

正如L1節(jié)所述,可以把函數(shù)想象成小型工廠?,F(xiàn)在想象那些工廠的輸入通過一根線連接到

輸出。求解導(dǎo)數(shù)相當(dāng)于回答這樣一個(gè)問題:如果將函數(shù)的輸入。拉高一點(diǎn),或者如果函數(shù)在

。處可能不對稱,因此把。拉低一點(diǎn),那么根據(jù)工廠的內(nèi)部運(yùn)作機(jī)制,輸出量將以這個(gè)小數(shù)

值的多少倍進(jìn)行變化呢?如圖1-5所示。

_______?

2-?

IX

圖1-5:導(dǎo)數(shù)可視化的另一種方法

對理解深度學(xué)習(xí)而言,第二種表示形式比第一種更為重要。

代碼

可以通過編碼來求解前面看到的導(dǎo)數(shù)的近似值:

frontypingimportCallable

defderiv(func:Callable[Lndarray],ndarray],

input_:ndarray,

delta:float=0.001)->ndarray:

,,,

計(jì)算函數(shù)func在input_數(shù)組中每個(gè)元素處的導(dǎo)數(shù)。

,,,

return(func(input_+delta)-func(input_-delta))/(2*delta)

幺當(dāng)說尸是E(隨機(jī)選的字母)的函數(shù)時(shí),其實(shí)是指存在某個(gè)函數(shù)£使得八上」「°

或者說,有一個(gè)函數(shù)L它接受對象河并產(chǎn)生對象廣。也可以說,P是函數(shù)/應(yīng)用于E

時(shí)產(chǎn)生的任意函數(shù)值:

可以將其編碼為下面這種形式。

deff(input_:ndarray)->ndarray:

#一些轉(zhuǎn)換

returnoutput

P=f(E)

1.3嵌套函數(shù)

現(xiàn)在來介紹一個(gè)概念,該概念將成為理解神經(jīng)網(wǎng)絡(luò)的基礎(chǔ):函數(shù)可以被“嵌套”,從而形成“復(fù)

合”函數(shù)?!扒短住钡降资鞘裁匆馑寄兀考僭O(shè)有兩個(gè)函數(shù),按照數(shù)學(xué)慣例,它們分別為h和

角,其中一個(gè)函數(shù)的輸出將成為另一個(gè)函數(shù)的輸入,這樣就可以“把它們串在一起”。

數(shù)學(xué)

嵌套函數(shù)在數(shù)學(xué)上表示為:

這不太直觀,因?yàn)橛袀€(gè)奇怪的地方:嵌套函數(shù)是“從外而內(nèi)”讀取的,而而運(yùn)算實(shí)際上是“從

內(nèi)而外”執(zhí)行的。例如,盡管輟翻勵(lì)照讀作"h接受力接受T對象而產(chǎn)生對象可',

但其真正含義是“首先將力應(yīng)用于T,然后將為應(yīng)用于該結(jié)果,最終得到對象

不意圖

要表示嵌套函數(shù),最直觀的方法是使用小型工廠表示法,又稱盒子表示法。

如圖1-6所示,輸入進(jìn)入第一個(gè)函數(shù),轉(zhuǎn)換之后進(jìn)行輸出。然后,這個(gè)輸出進(jìn)入第二個(gè)函數(shù)

并再次轉(zhuǎn)換,得到最終輸出。

圖1-6:直觀地表示嵌套函數(shù)

代碼

前面已經(jīng)介紹了兩個(gè)維度,接下來從代碼維度來認(rèn)識嵌套函數(shù)。首先,為嵌套函數(shù)定義一個(gè)數(shù)

據(jù)類型:

frontypingimportList

*函數(shù)接受一個(gè)ndarray作為參數(shù)并生成一個(gè)ndarray

Array_Function=Callable][ndarray],ndarray]

n鏈?zhǔn)且粋€(gè)函數(shù)列表

Chain=List[Array_Function]

然后,定義數(shù)據(jù)如何經(jīng)過特定長度的鏈,以長度等于2為例,代碼如下所示。

defchainlength2(chain:Chain,

a:ndarray)->ndarray:

999

在一行代碼中計(jì)算“鏈”中的兩個(gè)函數(shù)。

,,,

assertlen(chain)==2,\

“Lengthofinput'chain'shouldbe2”

fl=chaintO]

f2=chain[l]

returnf2(f1(x))

另一種示意圖

使用盒子表示法描述嵌套函數(shù)表明,該復(fù)合函數(shù)實(shí)際上就只是一個(gè)函數(shù)。因此,可以將該函數(shù)

簡單地表示為,如圖1-7所示。

x—?Zf2-?y

圖1-7:嵌套函數(shù)的另一種表示法

此外,在微積分中有一個(gè)定理,那就是山“基本可微”的函數(shù)組成的復(fù)合函數(shù)本身就是基本可

微的!因此,可以將視為另一個(gè)可計(jì)算導(dǎo)數(shù)的函數(shù)。計(jì)算復(fù)合函數(shù)的導(dǎo)數(shù)對于訓(xùn)練深度

學(xué)習(xí)模型至關(guān)重要。

但是,現(xiàn)在需要一個(gè)公式,以便根據(jù)各個(gè)組成函數(shù)的導(dǎo)數(shù)來計(jì)算此復(fù)合函數(shù)的導(dǎo)數(shù)。這就是接

下來要介紹的內(nèi)容。

1.4鏈?zhǔn)椒▌t

鏈?zhǔn)椒▌t是一個(gè)數(shù)學(xué)定理,用于計(jì)算復(fù)合函數(shù)的導(dǎo)數(shù)。從數(shù)學(xué)上講,深度學(xué)習(xí)模型就是復(fù)合函

數(shù)。因此,理解其導(dǎo)數(shù)的計(jì)算過程對于訓(xùn)練它們非常重要,接下來的幾章將詳述這一點(diǎn)。

數(shù)學(xué)

在數(shù)學(xué)上,這個(gè)定理看起來較磬雜,對嘉合定的值七宮們有:

其中U只是一個(gè)偽變量,代表函數(shù)的輸入。

當(dāng)描述具有一個(gè)輸入和一個(gè)輸出的函數(shù)i的導(dǎo)數(shù)時(shí),可以將代表該函數(shù)導(dǎo)數(shù)的函數(shù)表

示為山,??梢杂闷渌麄巫兞刻娲@樣做并不會對結(jié)果造成影響,就像/和

/⑷丁表示同一個(gè)意思一樣。

<lf<1/

稍后,我們將處理包含多個(gè)輸入(例如工和力的函數(shù)。一旦碰到這種情況,區(qū)分Jr和4W

之間的不同含義就是有意義的。

這就是為什么在前面的公式中,我們在所有的導(dǎo)數(shù)中將u放在了底部:fi和h都是接受一

個(gè)瑜入并產(chǎn)生一個(gè)輸出的函數(shù),在這些情況下(有一個(gè)輸入和一個(gè)輸出的函數(shù)),我們將在導(dǎo)

數(shù)符號中使用Wo

示意圖

對理解鏈?zhǔn)椒▌t而言,本節(jié)中的數(shù)學(xué)公式不太直觀。對此,盒子表示法會更有幫助。下面通過

簡單的八九示例來解釋導(dǎo)數(shù)“應(yīng)該”是什么,如圖18所示。

-6單位

圖1-8:鏈?zhǔn)椒▌t示意圖

直觀地說,使用圖1-8中的示意圖,復(fù)合函數(shù)的導(dǎo)數(shù)應(yīng)該是其組成函數(shù)的導(dǎo)數(shù)的乘積。假設(shè)

在第一個(gè)函數(shù)中輸入5,并且當(dāng)〃-工時(shí),第一個(gè)函數(shù)的導(dǎo)數(shù)是3,那么用公式表示就是

瓢0盤

然后取第一個(gè)盒子中的函數(shù)值,假設(shè)它是1,即Zi(Vl-1,再計(jì)算第二個(gè)函數(shù)h在這個(gè)值

上的導(dǎo)數(shù),即計(jì)算o如圖1-8所示,這個(gè)值是-2。

想象這些函數(shù)實(shí)際上是串在一起的,如果將盒子2對應(yīng)的輸入更改1單位會導(dǎo)致盒子2的

輸出產(chǎn)生-2單位的變化,將盒子2對應(yīng)的輸入更改3單位則會導(dǎo)致盒子2的輸出變化-6

(-2X3)單位。這就是為什么在鏈?zhǔn)椒▌t的公式中,最終結(jié)果是一個(gè)乘積:

利用數(shù)學(xué)和示意圖這兩個(gè)維度,我們可以通過使用鏈?zhǔn)椒▌t來推斷嵌套函數(shù)的輸出相對于其輸

入的導(dǎo)數(shù)值。那么計(jì)算這個(gè)導(dǎo)數(shù)的代碼如何編寫呢?

代碼

下面對此進(jìn)行編碼,并證明按照這種方式計(jì)算的導(dǎo)數(shù)會產(chǎn)生“看起來正確”的結(jié)果。這里將使

用square函數(shù)2以及sigmoid函數(shù),后者在深度學(xué)習(xí)中非常重要:

12參見1.1節(jié)的“NumPy庫中的基礎(chǔ)函數(shù)”部分。

defsigmoid(x:ndarray)->ndarray:

,,,

將sigmoid函數(shù)應(yīng)用「輸入ndarray中的每個(gè)元素.

,,,

return1/(1+np.exp(-x))

現(xiàn)在編寫鏈?zhǔn)椒▌t:

defchain_deriv_2(chain:Chain,

input_range:ndarray)->ndarray:

,,,

使用鏈?zhǔn)椒▌t計(jì)算兩個(gè)嵌套函數(shù)的導(dǎo)數(shù):(f2fl(X))'=f2'(fl(x))*fr(x)o

,,,

assertlen(chain)==2,\

“Thisfunctionrequires'Chainobjectsoflength2”

assertinpul_range.ndim==1,\

*Functionrequiresa1dimensionalndarrayasinput_range*

fl=chain[0]

f2=chain[l]

ttdfl/dx

fl_of_x=fl(input_range)

#df1/du

dfldx=deriv(f1,input_range)

#df2/du(fl(x))

dt2du=deriv(tz,il(input_range))

#在每一點(diǎn)上將這些量相乘

returndfldx?df2du

圖1-9繪制了結(jié)果,并展示了鏈?zhǔn)椒▌t的有效性:

PLOr_RANGE=np.arange(-3,3,0.01)

chain」=[square,sigmoid]

chain_2=[sigmoid,square]

plot_chain(chain_l,PLOT一RANGE)

plot_chain_deriv(chain_l,PLOT_RANGE)

plot_chain(chain_2,PLOT_RANGE)

plotchainderiv(chain2,PLOTRANGE)

f(x)=Sigmoid(square(x))f(A)=square(sigmoid(A))

圖1-9:鏈?zhǔn)椒▌t的有效性3

3請?jiān)趫D靈社區(qū)本書主頁上查看該圖的彩色版本。一一編者注

鏈?zhǔn)椒▌t似乎起作用了。當(dāng)函數(shù)向_1_傾斜時(shí),導(dǎo)數(shù)為正;當(dāng)函數(shù)向下傾斜時(shí),導(dǎo)數(shù)為負(fù);當(dāng)函

數(shù)未發(fā)生傾斜時(shí),導(dǎo)數(shù)為零。

因此,實(shí)際上只要各個(gè)函數(shù)本身是基本可微的,就可以通過數(shù)學(xué)公式和代碼計(jì)算嵌套函數(shù)(或

復(fù)合函數(shù))的導(dǎo)數(shù),例如ZiAo

從數(shù)學(xué)上講,深度學(xué)習(xí)模型是這些基本可微函數(shù)的長鏈。建議花時(shí)間手動(dòng)執(zhí)行稍長一點(diǎn)的詳細(xì)

示例(參見1.5節(jié)),這樣有助于直觀地理解鏈?zhǔn)椒▌t,包括其運(yùn)行方式以及在更復(fù)雜的模

型中的應(yīng)用。

1.5示例介紹

仔細(xì)研究一條稍長的鏈,假設(shè)有3個(gè)基本可微的函數(shù),分別是f1、后和角,如何計(jì)算它

們的導(dǎo)數(shù)呢?從前面提到的微積分定理可以知道,由任意有限個(gè)“基本可微”函數(shù)組成的復(fù)合

函數(shù)都是基本可微的。因此,計(jì)算導(dǎo)數(shù)應(yīng)該不難實(shí)現(xiàn)。

數(shù)學(xué)

從數(shù)學(xué)上講,對于包含3個(gè)基本可微的函數(shù)的復(fù)合函數(shù),其導(dǎo)數(shù)的計(jì)算公式如下:

芋⑺=芋(/"G)))X芋3⑺)X孰習(xí)

dndudw

僅僅看公式不是很直觀,但相比1.4節(jié)介紹的適用于長度

為2的鏈,兩者的基本邏輯是一樣的。

不意圖

要理解以上公式,最為直觀的方法就是通過盒子示意圖,如圖1-10所示。

5?Z—?AW?Z?Z(ZW)y

I

z>

圖「10:通過盒子表示法理解如何計(jì)算3個(gè)嵌套函數(shù)的導(dǎo)數(shù)

使用與1.4節(jié)中類似的邏輯:假設(shè)八上〃的輸入(稱為n)通過一-根線連接到輸出(稱為

ft),則將n改變較小量△,將導(dǎo)致變化A的基產(chǎn)倍,進(jìn)而導(dǎo)致鏈中的下一步

乩八;變化八的宣統(tǒng)巡鰲魯蕤倍,以此類推,直到最終表示變化的完整公式

等于前一個(gè)鏈?zhǔn)椒▌t乘以A。請仔細(xì)思考上述解釋和圖1-10中的示意圖,無須花費(fèi)太長時(shí)

間。在編寫代碼時(shí),這一點(diǎn)會更容易理解。

代碼

在給定組合函數(shù)的情況下,如何將本節(jié)中的公式轉(zhuǎn)換為計(jì)算導(dǎo)數(shù)的代碼呢?我們可以在這個(gè)簡

單的示例中看到神經(jīng)網(wǎng)絡(luò)前向傳遞和后向傳遞的雛形:

defchain_deriv_3(chain:Chain,

input_range:ndarray)->ndarray:

,,,

使用鏈?zhǔn)椒▌t來il算3個(gè)嵌套函數(shù)的導(dǎo)數(shù):

(f3(f2(fl)))'=f3*(f2(fl(x)))*f2*(fl(x))*fV(x)<

,,,

assertlen(chain)==3,\

*Thisfunctionrequires'Chain'objectstohavelength3*

fl=chain[0]

f2=chainEl]

f3=chain[2]

#fl(x)

fl_of_x=fl(input_range)

#f2(fl(x))

f2_of_x=f2(fl_of_x)

#df3du

df3du=dcriv(f3,f2_of_x)

#df2du

df2du=deriv(f2,fl_of_x)

#dfIdx

dfIdx=tieriv(fl,inputrange)

并在每?點(diǎn)上將這些量相乘

returndfldx*df2du*df3du

注意,在計(jì)算這個(gè)嵌套函數(shù)的鏈?zhǔn)椒▌t時(shí),這里對它進(jìn)行了兩次“傳遞”。

01.“向前”傳遞它,計(jì)算出fl_of_x和f2_of_x,這個(gè)過程可以稱作(或視作)“前向傳

遞”。

02.“向后”通過函數(shù),使用在前向傳遞中計(jì)算出的量及計(jì)算構(gòu)成導(dǎo)數(shù)的量。

最后,將這3個(gè)量相乘,得到導(dǎo)數(shù)。

接下來使用前面定義的3個(gè)簡單函數(shù)來說明上面的方法是可行的,這3個(gè)函數(shù)分別為

sigmoid、square才口leakyrelu<>

PI.Or_RANGE=np.range(-3,3,0.01)

p1ot_chain([1eaky_re1u,sigmoid,square],PLOT_RANGE)

plotchainderiv(fleakyrelu,sigmid,square],PLOTRANGE)

圖1T1:即使使用三重嵌套函數(shù),鏈?zhǔn)椒▌t也有效4

4請?jiān)趫D靈社區(qū)本書主頁上查看該圖的彩色版本。一一編者注

再次將導(dǎo)數(shù)圖與原始函數(shù)的斜率進(jìn)行比較,可以看到鏈?zhǔn)椒▌t確實(shí)正確地計(jì)算了導(dǎo)數(shù)。

基于以上理解,現(xiàn)在再來看一下具有多個(gè)輸入的復(fù)合函數(shù),這類函數(shù)遵循已經(jīng)建立的相同原理,

最終將更適用于深度學(xué)習(xí)。

1.6多輸入函數(shù)

至此,我們已經(jīng)從概念上理解了如何將函數(shù)串在一起形成復(fù)合函數(shù),并且知道了如何將這些函

數(shù)表示為一系列輸入或輸出的盒子,以及如何計(jì)算這些函數(shù)的導(dǎo)數(shù)。一方面通過數(shù)學(xué)公式理解

了導(dǎo)數(shù),另一方面通過“向前”組件和“向后”組件,根據(jù)傳遞過程中計(jì)算出的量理解了導(dǎo)數(shù)。

在深度學(xué)習(xí)中處理的函數(shù)往往并非只有一個(gè)輸入。相反,它們有多個(gè)輸入,在某些步驟中,這

些輸入以相加、相乘或其他方式組合在一起。正如下面介紹的,我們同樣可以計(jì)算這些函數(shù)的

輸出相對于其輸入的導(dǎo)數(shù)。現(xiàn)在假設(shè)存在一個(gè)有多個(gè)輸入的簡單場景,其中兩個(gè)輸入相加,然

后再輸入給另一個(gè)函數(shù)。

數(shù)學(xué)

在這個(gè)例子中,從數(shù)學(xué)意義上開始討論實(shí)際上很有幫助。如果輸入是T和叢那么可以認(rèn)為

函數(shù)分兩步進(jìn)行。在步驟1中,了和“傳到了將它們相加的函數(shù)。將該函數(shù)表示為C(整

個(gè)過程使用希臘字母表示函數(shù)名),然后將函數(shù)的輸出表示為從形式上看,這樣很容易表

示:

翻幽j磕0融朝也

步驟2是將。傳給某個(gè)函數(shù)??梢允侨我膺B續(xù)函數(shù),例如sigmoid函數(shù)或square函

數(shù),甚至是名稱不以,開頭的函數(shù))。將此函數(shù)的輸出表示為也就是:

s—\

將整個(gè)函數(shù)用i表示,可以寫作:

據(jù)雄R翻外堿

從數(shù)學(xué)意義上理解,這樣更為簡潔,但這實(shí)際上是兩個(gè)按順序執(zhí)行的運(yùn)算,這一點(diǎn)在表達(dá)式中

較為模糊。為了說明這一點(diǎn),來看示意圖。

示意圖

既然談到了多輸入函數(shù),現(xiàn)在來定義我們一直在討論的一個(gè)概念:用箭頭表示數(shù)學(xué)運(yùn)算順序的

示意圖叫作計(jì)算圖(computationalgraph)o例如,圖1-12展示了上述函數(shù)f的計(jì)算圖。

圖1-12:多輸入函數(shù)

可以看到,兩個(gè)輸入進(jìn)入n輸出n,然后n再被傳遞給了

代碼

對此進(jìn)行編碼非常簡單。但是要注意,必須添加一條額外的斷言:

defmu11iple_inputsadd(x:ndarray,

y:ndarray,

sigma:ArrayFunction)->float:

,,,

具有多個(gè)輸入和加法的函數(shù),前向傳遞。

assertx.shape==y.shape

a=x+y

returnsigma(a)

與本章前面提到的函數(shù)不同,對于輸入ndarray的每個(gè)元素,這個(gè)函數(shù)不只是簡單地進(jìn)行“逐

元素”運(yùn)算。每當(dāng)處理將多個(gè)ndarray作為輸入的運(yùn)算時(shí),都必須檢查它們的形狀,從而確

保滿足該運(yùn)算所需的所有條件。在這里,對于像加法這樣的簡單運(yùn)算,只需要檢查形狀是否相

同,以便逐元素進(jìn)行加法運(yùn)算。

1.7多輸入函數(shù)的導(dǎo)數(shù)

可以根據(jù)函數(shù)的兩個(gè)輸入來計(jì)算其輸出的導(dǎo)數(shù),這一點(diǎn)很容易理解。

數(shù)學(xué)

鏈?zhǔn)椒▌t在這些函數(shù)中的應(yīng)用方式與前面各節(jié)介紹的方式相同。由于擷醐H通版襦

是嵌套函數(shù),因此可以這樣計(jì)算導(dǎo)數(shù):

Of沏,,—,—加(.da....

—=?。?。(工、必)x丁Ml"”=?。唬?/x?。麄憬?/p>

UJTOUOXUUOX

當(dāng)然,,加的計(jì)算公式與此相同。

現(xiàn)在要注意:

無論工(或的值如何,X(或切每增加一單位,n都會增加一單位。

基于這一點(diǎn),稍后可以通過編寫代碼來計(jì)算這樣一個(gè)函數(shù)的導(dǎo)數(shù)。

75意圖

從概念上講,計(jì)算多輸入函數(shù)的導(dǎo)數(shù)與計(jì)算單輸入函數(shù)的導(dǎo)數(shù)所用的方法是相同的:計(jì)算每個(gè)

組成函數(shù)“后向”通過計(jì)算圖的導(dǎo)數(shù),然后將結(jié)果相乘即可得出總導(dǎo)數(shù),如圖1-13所示。

圖1-13:多輸入函數(shù)后向通過計(jì)算圖

代碼

defmultipleinputsaddbackward(x:ndarray,

y:ndarray,

sigma:ArrayFunction)->float:

999

計(jì)算這個(gè)簡單函數(shù)對兩個(gè)輸入的導(dǎo)數(shù)。

tt計(jì)算前向傳遞結(jié)果

a=x+y

#計(jì)算導(dǎo)數(shù)

dsda=deriv(sigma,a)

dadx,dady=1,1

returndsda*dadx,dsda*dady

當(dāng)然,你可以修改以上代碼,比如讓x和y相乘,而不是相加。

接下來將研究一個(gè)更復(fù)雜的示例,該示例更接近于深度學(xué)習(xí)的工作原理:一個(gè)與前一示例類似

的函數(shù),但包含兩個(gè)向量輸入。

1.8多向量輸入函數(shù)

深度學(xué)習(xí)涉及處理輸入為向量(vector)或矩陣(matrix)的函數(shù)。這些對象不僅可以進(jìn)行加

法、乘法等運(yùn)算,還可以通過點(diǎn)積或矩陣乘法進(jìn)行組合。前面提到的鏈?zhǔn)椒▌t的數(shù)學(xué)原理,以

及使用前向傳遞和后向傳遞計(jì)算函數(shù)導(dǎo)數(shù)的邏輯在這里,乃然適用,本章剩余部分將對此展開介

紹。

這些技術(shù)將最終成為理解深度學(xué)習(xí)有效性的關(guān)鍵。深度學(xué)習(xí)的目標(biāo)是使模型擬合某些數(shù)據(jù)。更

準(zhǔn)確地說,這意味著要找到一個(gè)數(shù)學(xué)函數(shù),以盡可能最優(yōu)的方式將對數(shù)據(jù)的觀測(將作為函數(shù)

的輸入)映射到對數(shù)據(jù)的目標(biāo)預(yù)測(將作為函數(shù)的輸出)。這些觀測值將被編碼為矩陣,通常

以行作為觀測值,每列則作為該觀測值的數(shù)字特征。第2章將對此進(jìn)行更詳細(xì)的介紹,現(xiàn)階

段必須能夠計(jì)算涉及點(diǎn)積和矩陣乘法的復(fù)雜函數(shù)的導(dǎo)數(shù)。

下面從數(shù)學(xué)維度精確定義上述概念。

數(shù)學(xué)

在珅經(jīng)網(wǎng)絡(luò)中,表示單個(gè)數(shù)據(jù)點(diǎn)的典型方法是將n個(gè)特征列為一行,其中每個(gè)特征都只是一

個(gè)數(shù)字,如工1、C等表示如下:

需巨酶踴/

這里要記住的一個(gè)典型示例是預(yù)測房價(jià),第2章將從零開始針對這個(gè)示例構(gòu)建神經(jīng)網(wǎng)絡(luò)。在

該示例中,3、C等是房屋的數(shù)字特征,例如房屋的占地面積或到學(xué)校的距離。

1.9基于已有特征創(chuàng)建新特征

神經(jīng)網(wǎng)絡(luò)中最常見的運(yùn)算也許就是計(jì)算已有特征的加權(quán)和,加權(quán)和可以強(qiáng)化某些特征而弱化其

他特征,從而形成一種新特征,但它本身僅僅是舊特征的組合。用數(shù)學(xué)上的一種簡潔的方式表

達(dá)就是使用該觀測值的點(diǎn)積(dotproduct),包含與特征M陲嚴(yán)跡&喇等長的一組權(quán)重。

下面分別從數(shù)學(xué)、示意圖、代碼等維度來探討這個(gè)概念。

數(shù)學(xué)

如果存在如下情況:

那么可以將此運(yùn)算的輸出定義為:

解H減醫(yī)哪3H用勰躥E瞬瞬曲噂隰黛翩曲的口中1雨^潴

注意,這個(gè)運(yùn)算是矩陣乘法的一個(gè)特例,它恰好是一個(gè)點(diǎn)積,因?yàn)閄只有一行,而W只

有一列。

接下來介紹用示意圖描繪它的幾種方法。

不意圖

可以通過一種簡單的方法來描繪這種運(yùn)算,如圖1-14所示。

輸入輸出

昌二Ci

e=

矩陣乘法

圖1T4:矩陣乘法(向量點(diǎn)積)示意圖(一)

圖1-14中的運(yùn)算接受兩個(gè)輸入(都可以是ndarray),并生成一個(gè)輸出ndarray0

對涉及多個(gè)輸入的大量運(yùn)算而言,這確實(shí)做了很大的簡化。但是我們也可以突出顯示各個(gè)運(yùn)算

和瑜入,如圖1_15和圖1-16所示。

中間最

N

圖1-15:矩陣乘法示意圖(二)

圖1-16:矩陣乘法示意圖(三)

注意,矩陣乘法(向量點(diǎn)積)是表示許多獨(dú)立運(yùn)算的一種簡潔方法。這種運(yùn)算會讓后向傳遞的

導(dǎo)數(shù)計(jì)算起來非常簡潔,下一節(jié)將介紹這一點(diǎn)。

代碼

對矩陣乘法進(jìn)行編碼很簡單:

defmatmulforward(X:ndarray,

W:ndarray)->ndarray:

,,,

計(jì)算矩陣乘法的前向傳遞結(jié)果。

assertX.shape[1]==W.shape[0],\

,,,

對于矩陣乘法,第一個(gè)數(shù)組中的列數(shù)應(yīng)與第二個(gè)數(shù)組中的行數(shù)相匹配:而這里,

第一個(gè)數(shù)組中的列數(shù)為{0},第二人數(shù)組中的行數(shù)為

.format(X.shape[1],W.shape10])

并矩陣乘法

N=np.dot(X,W)

returnN

這里有一個(gè)新的斷言,它確保了矩陣乘法的有效性。(這是第一個(gè)運(yùn)算,它不僅處理相同大小

的ndarray,還逐元素執(zhí)行運(yùn)算,而現(xiàn)在的輸出與輸入實(shí)際上并不匹配。因此,這個(gè)斷言很重

要。)

1.10多向量輸入函數(shù)的導(dǎo)數(shù)

對于僅以一個(gè)數(shù)字作為輸入并生成一個(gè)輸出的函數(shù),例如八門戶或統(tǒng)口蛔醯做城,

計(jì)算導(dǎo)數(shù)很簡單,只需應(yīng)用微積分中的規(guī)則即可。然而,對于向量函數(shù),其導(dǎo)數(shù)就沒有那么簡

竺w

單了:如果將點(diǎn)積寫為颼寓嬲"嬲這種形式,那么自然會產(chǎn)生一個(gè)問題:m和蒜分

別是什么?

數(shù)學(xué)

如何定義“矩陣的導(dǎo)數(shù)”?回顧一下,矩陣語法只是對一堆以特定形式排列的數(shù)字的簡寫,“矩

陣的導(dǎo)數(shù)”實(shí)際上是指“矩陣中每個(gè)元素的導(dǎo)數(shù)”。由于x有一行,因此它可以這樣定義:

命『聰1藪熟

口―N—■——?■——■

然而,?的輸出只是一個(gè)數(shù)字:瞪=斶疑物子腌魏觸啥膝勒憾,可以看到,如果叫改

變了F單位,那么N將改變inxf單位。同理,其他的?元素也滿足這種情況。因此

可以得出下面的公式:

這個(gè)結(jié)果出乎意料地簡練,掌握這一點(diǎn)極為關(guān)鍵,既可以理解深度學(xué)習(xí)的有效性,又可以知道

如何清晰地實(shí)現(xiàn)深度學(xué)習(xí)。

以此類推,可以得到如下公式。

不意圖

從概念上講,我們只想執(zhí)行圖1-17所示的操作。

輸入力輸出

圖『17:矩陣乘法的后向傳遞

如前面的例子所示,當(dāng)只處理加法和乘法時(shí),計(jì)算這些導(dǎo)數(shù)很容易。但是如何利用矩陣乘法實(shí)

現(xiàn)類似的操作呢?圖1-17中的示意圖并不直觀,要準(zhǔn)確地定義它,必須求助于本節(jié)中的數(shù)學(xué)

公式。

代碼

從數(shù)學(xué)上推算答案應(yīng)該是最困難的部分,對結(jié)果進(jìn)行編碼則比較簡單:

defmatmul_backwarcl_first(X:ndarray,

W:ndarray)->ndarray:

,,,

計(jì)算矩陣乘法相對于第?個(gè)參數(shù)的后向傳遞結(jié)果。

*后向傳遞

dNdX=np.transpose(W,(1,0))

returndNdX

這里計(jì)算的dNdX表示X的每個(gè)元素相對于輸出N的和的偏導(dǎo)數(shù)。在本書中,這個(gè)量有一

個(gè)特殊的名稱,即X的梯度(gradient)。這個(gè)概念是指,對于X的單個(gè)元素?(例如乃),

dNdX中的對應(yīng)元素(具體來說是dNdX[2])是向量點(diǎn)積N的輸出相對于Z3的偏導(dǎo)數(shù)。在

本書中,梯度僅指偏導(dǎo)數(shù)的多維對應(yīng)物。具體來說,它是函數(shù)輸出相對于該函數(shù)輸入的每個(gè)元

素的偏導(dǎo)數(shù)數(shù)組。

L11向量函數(shù)及其導(dǎo)數(shù):再進(jìn)一步

當(dāng)然,深度學(xué)習(xí)模型不止涉及一個(gè)運(yùn)算,它們包括長鏈?zhǔn)竭\(yùn)算,其中一些是1.10節(jié)介紹的向

量函數(shù),另一些則只是將函數(shù)逐元素地應(yīng)用于它們接受的ndarray(輸入)中?,F(xiàn)在來計(jì)算包

含這兩種函數(shù)的復(fù)合函數(shù)的導(dǎo)數(shù)。假設(shè)函數(shù)接受向量X和向量VV,執(zhí)行1.10節(jié)描述的點(diǎn)

積(將其表示為AH,然后將向量輸入到函數(shù)”中。這里將用新的語言來表達(dá)同樣

的目標(biāo):計(jì)算這個(gè)新函數(shù)的輸出相對于向量X和向量W的梯度。從第2章開始,木書將

詳細(xì)介紹它如何與神經(jīng)網(wǎng)絡(luò)相關(guān)聯(lián)。現(xiàn)在只需大致了解這個(gè)概念,也就是可以為任意復(fù)雜度的

計(jì)算圖計(jì)算梯度。

數(shù)學(xué)

公式很簡單,如下所示。

劇曰用第僻g娥堿溫嬤然日解蜜哈鰥解叫曲命蠹喃

不意圖

圖1-18與圖1-17類似,只不過在最后添加了函數(shù)

周二0-s

圖1-18:與圖1-17類似,但在最后添加了另一個(gè)函數(shù)

代碼

可以像下面這樣編寫本例中的函數(shù)。

defmatrix_forward_extra(X:ndarray,

W:ndarray,

sigma:AiTayJ'unction)->ndarray:

,“,

計(jì)算涉及矩陣乘法的函數(shù)(一個(gè)額外的函數(shù))的前向傳遞結(jié)果。

,,,

assertX.shape[1]==W.shape[0]

升矩陣乘法

N=np.dot(X,W)

#通過sigma傳遞矩陣乘法的輸出

S=sigmn(\)

returnS

向量函數(shù)及其導(dǎo)數(shù):后向傳遞

類似地,后向傳遞只是前述示例的直接擴(kuò)展。

01.數(shù)學(xué)

由于;■是嵌套函數(shù),具體來說就是凰鬣篝的曰一圖獻(xiàn)虬因此該函數(shù)在X

處的導(dǎo)數(shù)可以這樣表示:

Ofdo....dv..

—=—(r(X.VV))x——IX、Wa

i)Xihli)X

這是一個(gè)很好的定義,”是連續(xù)函數(shù),可以在任意點(diǎn)求導(dǎo)。在這里,只在

坳懿輟,4■黎.哈燔題網(wǎng)處對其求值。

此外,我們在1.10節(jié)的示例中已經(jīng)推斷出眥O因此,可以這樣表達(dá):

與前面的示例樣,由丁?最終答案是數(shù)字顫虢魏曹幽募呼曹聾海嘲乘以城中

的與X形狀相同的向量,因此這個(gè)公式會得出一個(gè)與X形狀相同的向量。

02.示意圖

圖1-19所示的這個(gè)函數(shù)的后向傳遞示意圖與前面的例子類似,甚至不需要在數(shù)學(xué)上做過多解

釋。矩陣乘法的結(jié)果包含所計(jì)算的e函數(shù)的導(dǎo)數(shù),只需要在這個(gè)導(dǎo)數(shù)的基礎(chǔ)上再添加一個(gè)乘

法。

圖1-19:帶有矩陣乘法的圖:后向傳遞

03.代碼

對后向傳遞進(jìn)行編碼也很簡單:

defmatrix_funclion_backward_l(X:ndarray,

W:ndarray,

sigma:ArrayFunction)->ndarray:

,,,

計(jì)算矩陣函數(shù)相對于?第一個(gè)元素的導(dǎo)數(shù)。

,,,

assertX.shape[1]==W.shape[0]

#矩陣乘法

N=np.dot(X,W)

*通過sigma傳遞矩陣乘法的輸出

S=sigma(N)

#后向計(jì)算

dSdN=deriv(sigma,N)

#dNdX

dNdX=np.transpose(W,(1,0))

#將它們相乘。因?yàn)檫@里的dNdX姑1X1,所以順序無關(guān)緊要

returnnp.dot(dSdN,dNdX)

注意,這里顯示的動(dòng)態(tài)效果與1.5節(jié)中3個(gè)嵌套函數(shù)示例顯示的動(dòng)態(tài)效果相同:計(jì)算前向傳

遞(這里指N)上的量,然后在后向傳遞期間進(jìn)行使用。

04.這是對的嗎?

如何判斷正在計(jì)算的這些導(dǎo)數(shù)是否正確?測試起來很簡單,就是稍微擾動(dòng)輸入并觀察輸出結(jié)果

的變化。例如,在這種情況下,X為:

print(X)

[[0.47230.6151-1.7262]]

如果將n增加0.01,即從-1.7262增加到T.7162,那么應(yīng)該可以看到由輸出梯度相對于

r<x0.01的前向函數(shù)生成的值有所增加,如圖1-20所示。

圖1-20:梯度檢查示意圖

利用matrixfunctionbackward1函數(shù),可以看到梯度是-0.1121:

print(matrixfunctionbackward1(X,W,sigmoid))

[[i).0852-0.0557-0.1121]]

可以看到,在將乃遞增0.01之后,函數(shù)的輸出相應(yīng)減少了約0.01X-0.1121=-0.001121,

這可以幫助測試該梯度是否正確。如果減幅(或增幅)大于或小于此量,那么關(guān)于鏈?zhǔn)椒▌t的

計(jì)算就是錯(cuò)誤的。然而,當(dāng)執(zhí)行計(jì)算時(shí),少量增加n確實(shí)會使函數(shù)的輸出值減小0.01X

-0.1121,這意味著計(jì)算的導(dǎo)數(shù)是正確的!

1.12節(jié)介紹的示例涉及前面介紹的所有運(yùn)算,并且可以直接用于第2章將構(gòu)建的模型。

1.12包含兩個(gè)二維矩陣輸入的計(jì)算圖

在深度學(xué)習(xí)和更通用的機(jī)器學(xué)習(xí)中,需要處理輸入為兩個(gè)二維數(shù)組的運(yùn)算,其中一個(gè)數(shù)組表示

一批數(shù)據(jù)X,另一個(gè)表示權(quán)重卬。這對建模上下文很有幫助,第2章將對此展開介紹。本

章僅關(guān)注此運(yùn)算背后的原理和數(shù)學(xué)意義,具體來說,就是通過一個(gè)簡單的示例詳細(xì)說明,我們

不再以一維向量的點(diǎn)積為例,而是介紹二維知陣的乘法。即使如此,本章介紹的推算過程仍然

具有數(shù)學(xué)意義,并且實(shí)際上非常容易編碼。

和以前一樣,從數(shù)學(xué)上看,得出這些結(jié)果并不困難,但過程看起來有點(diǎn)復(fù)雜。不管怎樣,結(jié)果

還是相當(dāng)清晰的。當(dāng)然,我們會對其按步驟進(jìn)行分解,并將其與代碼和示意圖聯(lián)系起來。

數(shù)學(xué)

假設(shè)X和w如下所示:

黑3

就工

這可能對應(yīng)一個(gè)數(shù)據(jù)集,其中每個(gè)觀測值都具有3個(gè)特征,3行可能對應(yīng)要對其進(jìn)行預(yù)測的3

個(gè)觀測值。

現(xiàn)在將為這些矩陣定義以下簡單的運(yùn)算。

01.將這些矩陣相乘。和以前一樣,將把執(zhí)行此運(yùn)算的函數(shù)表示為rVir,將輸出表示為

.V。因此,可以這樣表示:蟠口堿翦嬲L

02.將結(jié)果N傳遞給可微函數(shù)并定義s-

和以前一樣,現(xiàn)在的問題是:輸出S相對?于X和VV的梯度是多少?可以簡單地再次使用

鏈?zhǔn)椒▌t嗎?為什么?

注意,本例與之前的示例有所不同:$不是數(shù)字,而是矩陣。那么,一個(gè)矩陣相對于另一矩

陣的梯度意味著什么呢?

這就引出了一個(gè)微妙但十分重要的概念:可以在目標(biāo)多維數(shù)組上執(zhí)行任何一系列運(yùn)算,但是要

對某些輸出定義好梯度,這需要對序列中的最后一個(gè)數(shù)組求和(或以其他方式聚合成單個(gè)數(shù)字),

這樣“X中每個(gè)元素的變化會在多大程度上影響輸出”這一問題才有意義。

因此,在最后添加第3個(gè)函數(shù)A,該函數(shù)獲取£中的元素并將其求和。

通過數(shù)學(xué)把它具體化。首先,把X和W相乘:

J\\Xu\iIJUXIriiXU31Tilx|x工位>:心處

A:<14—xu*?4-in<+T2\xu..nm:432+r=x一工防乂亡仃

乂U]¥132<121+fJiX

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論