【內(nèi)容介紹】動手學(xué)深度學(xué)習(xí)-基于pytorch版本
你好! 這是【李沐】動手學(xué)深度學(xué)習(xí)v2-基于pytorch版本的學(xué)習(xí)筆記
教材
源代碼
安裝教程(安裝pytorch不要用pip,改成conda,pip太慢了,下載不下來)
個人推薦學(xué)習(xí)學(xué)習(xí)筆記
【脈絡(luò)梳理】
預(yù)備知識
數(shù)據(jù)操作
??本節(jié)代碼文件在源代碼文件的chapter_preliminaries/ndarray.ipynb中
-
創(chuàng)建數(shù)組
??創(chuàng)建數(shù)組需要:
??①形狀
??②每個元素的數(shù)據(jù)類型
??③每個元素的值 -
訪問元素
??①一個元素:[1,2]
??②一行:[1,:]
??③一列:[:,1]
??④子區(qū)域:[1:3,1:] #第1到2行,第1到最后1列
??⑤子區(qū)域:[::3,::2] #從第0行開始,每3行一跳,從第0列開始,每2列一跳。
數(shù)據(jù)預(yù)處理
??本節(jié)代碼文件在源代碼文件的chapter_preliminaries/pandas.ipynb中
-
reshape函數(shù)
??使用reshape函數(shù)后不指向同一塊內(nèi)存,但數(shù)據(jù)改變是同步的import torch a=torch.arange(12) b=a.reshape((3,4)) b[:]=2 # 改變b,a也會隨之改變 print(a) # tensor([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) a[:]=1 # 改變a,b也會隨之改變 print(b) # tensor([[1, 1, 1, 1],[1, 1, 1, 1],[1, 1, 1, 1]]) print(id(b)==id(a)) # False # 但a、b內(nèi)存不同 print(id(a)) # 2157597781424 print(id(b)) # 2157597781424
線性代數(shù)
??本節(jié)代碼文件在源代碼文件的chapter_preliminaries/linear-algebra.ipynb中
-
張量的按元素操作
??標(biāo)量、向量、矩陣和任意數(shù)量軸的張量(統(tǒng)稱為張量)有一些實用的屬性。 例如,你可能已經(jīng)從按元素操作的定義中注意到,任何按元素的一元運算都不會改變其操作數(shù)的形狀。 同樣,給定具有相同形狀的任意兩個張量,任何按元素二元運算的結(jié)果都將是相同形狀的張量。
??例如,將兩個相同形狀的矩陣相加,會在這兩個矩陣上執(zhí)行按元素加法;兩個矩陣的按元素乘法稱為Hadamard積(Hadamard product)(數(shù)學(xué)符號 ? \bigodot ?)。 對于矩陣 A ∈ R m n , B ∈ R m n \bf A\in\mathbb R^{mn},\bf B\in\mathbb R^{mn} A∈Rmn,B∈Rmn, 其中第 i \it i i行和第 j \it j j列的元素是 b i j b_{ij} bij?。 矩陣 A \bf A A和 B \bf B B的Hadamard積為import torch A = torch.arange(20, dtype=torch.float32).reshape(5, 4) B = A.clone() # 通過分配新內(nèi)存,將A的一個副本分配給B print(A) #tensor([[ 0., 1., 2., 3.],[ 4., 5., 6., 7.],[ 8., 9., 10., 11.],[12., 13., 14., 15.],[16., 17., 18., 19.]]) print(A+B) #tensor([[ 0., 2., 4., 6.],[ 8., 10., 12., 14.],[ 16., 18., 20., 22.],[24., 26., 28., 30.],[32., 34., 36., 38.]]) print(A*B) #tensor([[0., 1., 4., 9.],[16., 25., 36., 49.],[64., 81., 100., 121.],[144., 169., 196., 225.],[256., 289., 324., 361.]])
-
降維求和
??①原始shape:[5,4]
????· axis=0?sum:[?4?]
????· axis=1?sum:[?5?]
??②原始shape:[2,5,4]
????· axis=1?sum:[2,4]
????· axis=2?sum:[2,5]
????· axis=[1,2]?sum:[?4?] -
非降維求和
??原始shape:[2,5,4]?參數(shù) keepdims=True
????· axis=1?sum:[2,1,4]
????· axis=1?sum:[2,1,1]
矩陣計算
??本節(jié)代碼文件在源代碼文件的chapter_preliminaries/calculus.ipynb中
-
將導(dǎo)數(shù)拓展到向量
?? -
標(biāo)量對列向量求導(dǎo)
???? 其中, a 不是關(guān)于 x 的函數(shù), 0 和 1 是向量 ; 其中,\it a不是關(guān)于\bf x的函數(shù),\color{black} 0和\bf 1是向量; 其中,a不是關(guān)于x的函數(shù),0和1是向量;
?????? -
列向量對列向量求導(dǎo)
??結(jié)果是矩陣
????
???樣例:
????? x ∈ R n , y ∈ R m , ? y ? x ∈ R m n ; a , a 和 A 不是關(guān)于 x 的函數(shù), 0 和 I 是矩陣 ; \bf x\in\mathbb R^{n} ,\bf y\in\mathbb R^{m},\frac{\partial\bf y}{\partial\bf x}\in\mathbb R^{mn};\it a,\bf a和\bf A不是關(guān)于\bf x的函數(shù),\color{black} 0和\bf I是矩陣; x∈Rn,y∈Rm,?x?y?∈Rmn;a,a和A不是關(guān)于x的函數(shù),0和I是矩陣;
?????????? -
將導(dǎo)數(shù)拓展到矩陣
????
自動求導(dǎo)
??本節(jié)代碼文件在源代碼文件的chapter_preliminaries/autograd.ipynb中
-
向量鏈?zhǔn)椒▌t
??
??樣例:
?????? -
自動求導(dǎo)的兩種模式
???? -
反向累積模式
????
????樣例:
??????
-
正向累積與反向累積復(fù)雜度比較
??正向累積內(nèi)存復(fù)雜度為O(1),反向累積內(nèi)存復(fù)雜度為O(n);但神經(jīng)網(wǎng)絡(luò)通常不會用正向累積,因為正向累積每計算一個變量的梯度都需要掃一遍,計算復(fù)雜度太高。
??
線性神經(jīng)網(wǎng)絡(luò)
線性回歸
??本節(jié)代碼文件在源代碼文件的chapter_linear-networks/linear-regression.ipynb中
-
線性模型
????
??線性模型可以看做是單層神經(jīng)網(wǎng)絡(luò):
??????
???衡量預(yù)估質(zhì)量(損失函數(shù)):
?????? -
訓(xùn)練數(shù)據(jù)
???? -
參數(shù)學(xué)習(xí)
????
??顯示解:
?????? -
總結(jié)
????
深度學(xué)習(xí)的基礎(chǔ)優(yōu)化算法
-
梯度下降
??通過不斷地在損失函數(shù)遞減的方向上更新參數(shù)來降低誤差。
????
??學(xué)習(xí)率不能太大也不能太小:
???? -
小批量隨機梯度下降
????
??批量大小不能太大也不能太?。?/strong>
?????? -
總結(jié)
????
線性回歸的從零開始實現(xiàn)
??本節(jié)代碼文件在源代碼文件的chapter_linear-networks/linear-regression-scratch.ipynb中
- 實現(xiàn)流程
??其中,定義模型包括定義損失函數(shù)和定義優(yōu)化算法
線性回歸的簡潔實現(xiàn)
??本節(jié)代碼文件在源代碼文件的chapter_linear-networks/linear-regression-concise.ipynb中
??簡潔實現(xiàn)是指通過使用深度學(xué)習(xí)框架來實現(xiàn)線性回歸模型,具體流程與從零開始實現(xiàn)大體相同,不過一些常用函數(shù)不需要我們自己寫了(直接導(dǎo)庫,用別人寫好的)
- 實現(xiàn)流程
Softmax回歸
??本節(jié)代碼文件在源代碼文件的chapter_linear-networks/softmax-regression.ipynb中
-
回歸vs分類(從回歸到多類分類)
??回歸估計一個連續(xù)值;分類預(yù)測一個離散類別。
???? -
從回歸到多類分類 — 均方損失
???? -
從回歸到多類分類 — 無校驗比例
???? -
從回歸到多類分類 — 校驗比例
???? -
Softmax和交叉熵損失
???? -
總結(jié)
????
損失函數(shù)
??本節(jié)代碼文件在源代碼文件的chapter_linear-networks/softmax-regression.ipynb中
損失函數(shù)用來衡量預(yù)測值與真實值之間的區(qū)別,是機器學(xué)習(xí)里非常重要的概念。下面介紹三種常用的損失函數(shù)。
-
①L2 Loss
???? l ( y , y ′ ) = ∣ y ? y ′ ∣ \it l(y,y') = \mid y-y' \mid l(y,y′)=∣y?y′∣
????????
藍色曲線:表示當(dāng)y=0時,變換預(yù)測值y’。
綠色曲線:表示似然函數(shù)。
橙色曲線:表示損失函數(shù)的梯度,可以發(fā)現(xiàn),當(dāng)y與y’相差較大的時候,梯度的絕對值也較大。 -
②L1 Loss
???? l ( y , y ′ ) = 1 2 ( y ? y ′ ) 2 \it l(y,y') = \frac{1}{2} ( y-y')^2 l(y,y′)=21?(y?y′)2
????????
藍色曲線:表示當(dāng)y=0時,變換預(yù)測值y’。
綠色曲線:表示似然函數(shù)。
橙色曲線:表示損失函數(shù)的梯度,可以發(fā)現(xiàn),當(dāng)y’>0時,導(dǎo)數(shù)為1,當(dāng)y’<0時,導(dǎo)數(shù)為-1。 -
③Huber’s Robust Loss(魯棒損失)
????????
藍色曲線:表示當(dāng)y=0時,變換預(yù)測值y’。
綠色曲線:表示似然函數(shù)。
橙色曲線:表示損失函數(shù)的梯度。
圖像分類數(shù)據(jù)集
??本節(jié)代碼文件在源代碼文件的chapter_linear-networks/image-classification-dataset.ipynb中
-
MNIST數(shù)據(jù)集
??是圖像分類中廣泛使用的數(shù)據(jù)集之一,但作為基準(zhǔn)數(shù)據(jù)集過于簡單。 我們將使用類似但更復(fù)雜的Fashion-MNIST數(shù)據(jù)集。 -
Fashion-MNIST數(shù)據(jù)集
??①Fashion-MNIST由10個類別的圖像組成,分別為t-shirt(T恤)、trouser(褲子)、pullover(套衫)、dress(連衣裙)、coat(外套)、sandal(涼鞋)、shirt(襯衫)、sneaker(運動鞋)、bag(包)和ankle boot(短靴)。
??② 每個類別由訓(xùn)練數(shù)據(jù)集(train dataset)中的6000張圖像 和測試數(shù)據(jù)集(test dataset)中的1000張圖像組成。
??③ 每個輸入圖像的高度和寬度均為28像素。 數(shù)據(jù)集由灰度圖像組成,其通道數(shù)為1。
Softmax回歸的從零開始實現(xiàn)
??本節(jié)代碼文件在源代碼文件的chapter_linear-networks/softmax-regression-scratch.ipynb中
-
實現(xiàn)流程
??我們使用Fashion-MNIST數(shù)據(jù)集, 并設(shè)置數(shù)據(jù)迭代器的批量大小為256。每個樣本都將用固定長度的向量表示。 原始數(shù)據(jù)集中的每個樣本都是 28×28 的圖像。 在本節(jié)中,我們將展平每個圖像,把它們看作長度為784的向量。 在后面的章節(jié)中,我們將討論能夠利用圖像空間結(jié)構(gòu)的特征, 但現(xiàn)在我們暫時只把每個像素位置看作一個特征。
????分類精度即正確預(yù)測數(shù)量與總預(yù)測數(shù)量之比
Softmax回歸的簡潔實現(xiàn)
??本節(jié)代碼文件在源代碼文件的chapter_linear-networks/softmax-regression-concise.ipynb中
??通過深度學(xué)習(xí)框架的高級API也能更方便地實現(xiàn)softmax回歸模型。
-
實現(xiàn)流程
??本節(jié) 繼續(xù)使用Fashion-MNIST數(shù)據(jù)集,并保持批量大小為256。
多層感知機
感知機
-
感知機
?? -
感知機與回歸和Softmax回歸的區(qū)別
??感知機是二分類(1或-1),而回歸的輸出是實數(shù),Softmax回歸的輸出是概率。 -
訓(xùn)練感知機
???? -
收斂定理
???? -
XOR問題
??? -
總結(jié)
??
多層感知機
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/mlp.ipynb中
-
學(xué)習(xí)XOR
???? -
單隱藏層
??隱藏層大小是超參數(shù)(輸入和輸出大小由數(shù)據(jù)決定,輸出大小人為決定。)
???? -
單隱藏層 — 單分類
??只有一個輸出,即輸出是標(biāo)量。
????
Q:為什么需要非線性的激活函數(shù)?(σ(x)不可以等于x,也不可以等于nx)
A: 如果激活函數(shù)是線性的,那么單隱藏層的多層感知機就變成了最簡單的線性模型。
??? -
激活函數(shù)
??①Sigmoid 激活函數(shù)
????
??②Tanh 激活函數(shù)
???
??③ReLU 激活函數(shù)
???? -
單隱藏層 — 多類分類
???? -
多隱藏層
???? -
總結(jié)
???
多層感知機的從零開始實現(xiàn)
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/mlp-scratch.ipynb中
-
實現(xiàn)流程
??我們實現(xiàn)一個具有單隱藏層的多層感知機, 它包含256個隱藏單元。 注意,我們可以將這兩個變量都視為超參數(shù)。 通常,我們選擇2的若干次冪作為層的寬度。 因為內(nèi)存在硬件中的分配和尋址方式,這么做往往可以在計算上更高效。
多層感知機的簡潔實現(xiàn)
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/mlp-concise.ipynb中
-
與softmax回歸的簡潔實現(xiàn)相比
??唯一的區(qū)別是我們添加了2個全連接層(之前我們只添加了1個全連接層)。第一層是隱藏層,它包含256個隱藏單元,并使用了ReLU激活函數(shù)。第二層是輸出層。
??訓(xùn)練過程的實現(xiàn)與我們實現(xiàn)softmax回歸時完全相同。
模型選擇
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/underfit-overfit.ipynb中
-
訓(xùn)練誤差和泛化誤差
??? -
驗證數(shù)據(jù)集和測試數(shù)據(jù)集
??? -
K-折交叉驗證
??? -
總結(jié)
???
過擬合和欠擬合
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/underfit-overfit.ipynb中
-
過擬合和欠擬合
???
??? -
數(shù)據(jù)復(fù)雜度
??? -
模型容量
??? -
模型容量的影響
??? -
估計模型容量
???
??? 其中,d+1中的1是偏移,m是隱藏層大小,k是分類的類別數(shù) - VC 維
???
-
線性分類器的 VC 維
??? -
VC 維的用處
??? -
總結(jié)
???
權(quán)重衰退
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/weight-decay.ipynb中
??權(quán)重衰退是一種常見的處理過擬合(模型復(fù)雜度過高)的方法。
-
使用均方范數(shù)作為硬性限制
??? -
使用均方范數(shù)作為柔性限制
??? -
演示對最優(yōu)解的影響
??? -
參數(shù)更新法則
??? -
總結(jié)
???
暫退法(Dropout)
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/dropout.ipynb中
-
暫退法(丟棄法)的動機
??? -
無偏差的加入噪音
??? -
使用丟棄法
??? -
推理中的丟棄法
??? -
總結(jié)
???
數(shù)值穩(wěn)定性
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/numerical-stability-and-init.ipynb中
-
神經(jīng)網(wǎng)絡(luò)的梯度
???
???其中,矩陣乘法容易帶來梯度爆炸和梯度消失的問題 -
數(shù)值穩(wěn)定性的常見兩個問題
???
?例子:MLP
???
???
??????↑ ↑ ↑ 此時,就會造成梯度爆炸
???
???
??????↑ ↑ ↑ 此時,就會造成梯度消失 -
梯度爆炸的問題
??? -
梯度消失的問題
??? -
總結(jié)
???
模型初始化和激活函數(shù)
??本節(jié)代碼文件在源代碼文件的chapter_multilayer-perceptrons/numerical-stability-and-init.ipynb中
-
讓訓(xùn)練更加穩(wěn)定
??? -
讓每層的方差是個常數(shù)
??? -
權(quán)重初始化
???
例子:MLP
????
??①假設(shè)沒有激活函數(shù):
????
???正向方差:
?????
???反向均值和方差:
??????
??②假設(shè)線性的激活函數(shù):
???正向:
?????
???反向:
????? -
Xavier 初始
???Xavier 是一種常見的權(quán)重初始化方法
??? -
檢查常用激活函數(shù)
??? -
總結(jié)
???
深度學(xué)習(xí)計算
層和塊
??本節(jié)代碼文件在源代碼文件的chapter_deep-learning-computation/model-construction.ipynb中
-
塊的組成
??塊(block)可以描述單個層、由多個層組成的組件或整個模型本身。 使用塊進行抽象的一個好處是可以將一些塊組合成更大的組件, 這一過程通常是遞歸的。
????
??從編程的角度來看,塊由類(class)表示。 它的任何子類都必須定義一個將其輸入轉(zhuǎn)換為輸出的前向傳播函數(shù), 并且必須存儲任何必需的參數(shù)。 注意,有些塊不需要任何參數(shù)。 最后,為了計算梯度,塊必須具有反向傳播函數(shù)。 在定義我們自己的塊時,由于自動微分提供了一些后端實現(xiàn),我們只需要考慮前向傳播函數(shù)和必需的參數(shù)。 -
塊需要提供的基本功能
??①將輸入數(shù)據(jù)作為其前向傳播函數(shù)的參數(shù)。
??②通過前向傳播函數(shù)來生成輸出。注:輸出的形狀可能與輸入的形狀不同。
??③計算其輸出關(guān)于輸入的梯度,可通過其反向傳播函數(shù)進行訪問。通常這是自動發(fā)生的。
??④存儲和訪問前向傳播計算所需的參數(shù)。
??⑤根據(jù)需要初始化模型參數(shù)。 -
自定義塊
??在下面的代碼片段中,我們從零開始編寫一個塊。 它包含一個多層感知機,其具有256個隱藏單元的隱藏層和一個10維輸出層。 注意,下面的MLP類繼承了表示塊的類。我們的實現(xiàn)只需要提供我們自己的構(gòu)造函數(shù)(Python中的__init__函數(shù))和前向傳播函數(shù)。class MLP(nn.Module): # 用模型參數(shù)聲明層。這里,我們聲明兩個全連接的層 def __init__(self): # 調(diào)用MLP的父類Module的構(gòu)造函數(shù)來執(zhí)行必要的初始化。 # 這樣,在類實例化時也可以指定其他函數(shù)參數(shù),例如模型參數(shù)params(稍后將介紹) super().__init__() self.hidden = nn.Linear(20, 256) # 隱藏層 self.out = nn.Linear(256, 10) # 輸出層 # 定義模型的前向傳播,即如何根據(jù)輸入X返回所需的模型輸出 def forward(self, X): # 注意,這里我們使用ReLU的函數(shù)版本,其在nn.functional模塊中定義。 return self.out(F.relu(self.hidden(X)))
注意一些關(guān)鍵細節(jié): 首先,我們定制的__init__函數(shù)通過super().init() 調(diào)用父類的__init__函數(shù), 省去了重復(fù)編寫模版代碼的痛苦。 然后,我們實例化兩個全連接層, 分別為self.hidden和self.out。 注意,除非我們實現(xiàn)一個新的運算符, 否則我們不必擔(dān)心反向傳播函數(shù)或參數(shù)初始化, 系統(tǒng)將自動生成這些。
-
順序塊
??回想一下Sequential的設(shè)計是為了把其他模塊串起來。 為了構(gòu)建我們自己的簡化的MySequential, 我們只需要定義兩個關(guān)鍵函數(shù):
???①一種將塊逐個追加到列表中的函數(shù)。
???②一種前向傳播函數(shù),用于將輸入按追加塊的順序傳遞給塊組成的“鏈條”。
下面的MySequential類提供了與默認Sequential類相同的功能:class MySequential(nn.Module): def __init__(self, *args): super().__init__() for idx, module in enumerate(args): # 這里,module是Module子類的一個實例。我們把它保存在'Module'類的成員 # 變量_modules中。_module的類型是OrderedDict self._modules[str(idx)] = module def forward(self, X): # OrderedDict保證了按照成員添加的順序遍歷它們 for block in self._modules.values(): X = block(X) return X
_modules:__init__函數(shù)將每個模塊逐個添加到有序字典_modules中,_modules的主要優(yōu)點是: 在模塊的參數(shù)初始化過程中, 系統(tǒng)知道在_modules字典中查找需要初始化參數(shù)的子塊。
參數(shù)管理
??本節(jié)代碼文件在源代碼文件的chapter_deep-learning-computation/parameters.ipynb中
-
參數(shù)訪問
??為方便解釋,先定義如下神經(jīng)網(wǎng)絡(luò):
??我們從已有模型中訪問參數(shù)。 當(dāng)通過Sequential類定義模型時, 我們可以通過索引來訪問模型的任意層。 這就像模型是一個列表一樣,每層的參數(shù)都在其屬性中。 如下所示,我們可以檢查第二個全連接層的參數(shù)。import torch from torch import nn net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1)) X = torch.rand(size=(2, 4)) net(X)
print(net[2].state_dict()) #OrderedDict([('weight', tensor([[ 0.0251, -0.2952, -0.1204, 0.3436, -0.3450, -0.0372, 0.0462, 0.2307]])), ('bias', tensor([0.2871]))])
-
提取目標(biāo)參數(shù)
??從第二個全連接層(即第三個神經(jīng)網(wǎng)絡(luò)層)提取偏置, 提取后返回的是一個參數(shù)類實例,并進一步訪問該參數(shù)的值:
參數(shù)是復(fù)合的對象,包含值、梯度和額外信息。 這就是我們需要顯式參數(shù)值的原因。 除了值之外,我們還可以訪問每個參數(shù)的梯度。 在上面這個網(wǎng)絡(luò)中,由于我們還沒有調(diào)用反向傳播,所以參數(shù)的梯度處于初始狀態(tài)。print(type(net[2].bias)) #<class 'torch.nn.parameter.Parameter'> print(net[2].bias) #Parameter containing: #tensor([0.2871], requires_grad=True) print(net[2].bias.data) #tensor([0.2871])
print(net[2].weight.grad == None) #True
-
一次性訪問所有參數(shù)
??當(dāng)我們需要對所有參數(shù)執(zhí)行操作時,逐個訪問它們可能會很麻煩。 當(dāng)我們處理更復(fù)雜的塊(例如,嵌套塊)時,情況可能會變得特別復(fù)雜, 因為我們需要遞歸整個樹來提取每個子塊的參數(shù)。 下面,我們將通過演示來比較訪問第一個全連接層的參數(shù)和訪問所有層:
這為我們提供了另一種訪問網(wǎng)絡(luò)參數(shù)的方式,如下所示:print(*[(name, param.shape) for name, param in net[0].named_parameters()]) #('weight', torch.Size([8, 4])) ('bias', torch.Size([8])) print(*[(name, param.shape) for name, param in net.named_parameters()]) #('0.weight', torch.Size([8, 4])) ('0.bias', torch.Size([8])) ('2.weight', torch.Size([1, 8])) ('2.bias', torch.Size([1]))
net.state_dict()['2.bias'].data #tensor([0.2871])
-
從嵌套塊收集參數(shù)
??我們首先定義一個生成塊的函數(shù)(可以說是“塊工廠”),然后將這些塊組合到更大的塊中。
設(shè)計了網(wǎng)絡(luò)后,我們看看它是如何工作的:def block1(): return nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 4), nn.ReLU()) def block2(): net = nn.Sequential() for i in range(4): # 在這里嵌套 net.add_module(f'block {i}', block1()) return net rgnet = nn.Sequential(block2(), nn.Linear(4, 1)) rgnet(X) #tensor([[0.1713], # [0.1713]], grad_fn=<AddmmBackward0>)
因為層是分層嵌套的,所以我們也可以像通過嵌套列表索引一樣訪問它們。 下面,我們訪問第一個主要的塊中、第二個子塊的第一層的偏置項:print(rgnet) ''' Sequential( (0): Sequential( (block 0): Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=4, bias=True) (3): ReLU() ) (block 1): Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=4, bias=True) (3): ReLU() ) (block 2): Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=4, bias=True) (3): ReLU() ) (block 3): Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=4, bias=True) (3): ReLU() ) ) (1): Linear(in_features=4, out_features=1, bias=True) ) '''
rgnet[0][1][0].bias.data #tensor([-0.0444, -0.4451, -0.4149, 0.0549, -0.0969, 0.2053, -0.2514, 0.0220])
-
參數(shù)初始化
??深度學(xué)習(xí)框架提供默認隨機初始化, 也允許我們創(chuàng)建自定義初始化方法, 滿足我們通過其他規(guī)則實現(xiàn)初始化權(quán)重。默認情況下,PyTorch會根據(jù)一個范圍均勻地初始化權(quán)重和偏置矩陣, 這個范圍是根據(jù)輸入和輸出維度計算出的。 PyTorch的nn.init模塊提供了多種預(yù)置初始化方法。
①內(nèi)置初始化
??下面的代碼將所有權(quán)重參數(shù)初始化為標(biāo)準(zhǔn)差為0.01的高斯隨機變量, 且將偏置參數(shù)設(shè)置為0。
??我們還可以將所有參數(shù)初始化為給定的常數(shù),比如初始化為1:def init_normal(m): if type(m) == nn.Linear: nn.init.normal_(m.weight, mean=0, std=0.01) nn.init.zeros_(m.bias) net.apply(init_normal) net[0].weight.data[0], net[0].bias.data[0] #(tensor([-0.0017, 0.0232, -0.0026, 0.0026]), tensor(0.))
??我們還可以對某些塊應(yīng)用不同的初始化方法。 例如,下面我們使用Xavier初始化方法初始化第一個神經(jīng)網(wǎng)絡(luò)層, 然后將第三個神經(jīng)網(wǎng)絡(luò)層初始化為常量值42:def init_constant(m): if type(m) == nn.Linear: nn.init.constant_(m.weight, 1) nn.init.zeros_(m.bias) net.apply(init_constant) net[0].weight.data[0], net[0].bias.data[0] #(tensor([1., 1., 1., 1.]), tensor(0.))
②自定義初始化def xavier(m): if type(m) == nn.Linear: nn.init.xavier_uniform_(m.weight) def init_42(m): if type(m) == nn.Linear: nn.init.constant_(m.weight, 42) net[0].apply(xavier) net[2].apply(init_42) print(net[0].weight.data[0]) #tensor([-0.4645, 0.0062, -0.5186, 0.3513]) print(net[2].weight.data) #tensor([[42., 42., 42., 42., 42., 42., 42., 42.]])
??有時,深度學(xué)習(xí)框架沒有提供我們需要的初始化方法。 在下面的例子中,我們使用以下的分布為任意權(quán)重參數(shù) ?? 定義初始化方法:
w ∽ { U ( 5 , 10 ) , 可能性1/4 0 , 可能性1/2 U ( ? 10 , ? 5 ) , 可能性1/4 w \backsim \begin{cases} U(5,10), & \text{可能性1/4} \\ 0, & \text{可能性1/2} \\ U(-10,-5), & \text{可能性1/4} \\ \end{cases} w∽? ? ??U(5,10),0,U(?10,?5),?可能性1/4可能性1/2可能性1/4?
注意,我們始終可以直接設(shè)置參數(shù):def my_init(m): if type(m) == nn.Linear: print("Init", *[(name, param.shape) for name, param in m.named_parameters()][0]) nn.init.uniform_(m.weight, -10, 10) m.weight.data *= m.weight.data.abs() >= 5 ''' Init weight torch.Size([8, 4]) Init weight torch.Size([1, 8]) ''' net.apply(my_init) net[0].weight[:2] ''' tensor([[ 8.8025, 6.4078, 0.0000, -8.4598], [-0.0000, 9.0582, 8.8258, 7.4997]], grad_fn=<SliceBackward0>) '''
net[0].weight.data[:] += 1 net[0].weight.data[0, 0] = 42 net[0].weight.data[0] #tensor([42.0000, 7.4078, 1.0000, -7.4598])
-
參數(shù)綁定
??有時我們希望在多個層間共享參數(shù): 我們可以定義一個稠密層,然后使用它的參數(shù)來設(shè)置另一個層的參數(shù)。
??這個例子表明第三個和第五個神經(jīng)網(wǎng)絡(luò)層的參數(shù)是綁定的。 它們不僅值相等,而且由相同的張量表示。 因此,如果我們改變其中一個參數(shù),另一個參數(shù)也會改變。 你可能會思考:當(dāng)參數(shù)綁定時,梯度會發(fā)生什么情況? 答案是由于模型參數(shù)包含梯度,因此在反向傳播期間第二個隱藏層 (即第三個神經(jīng)網(wǎng)絡(luò)層)和第三個隱藏層(即第五個神經(jīng)網(wǎng)絡(luò)層)的梯度會加在一起。# 我們需要給共享層一個名稱,以便可以引用它的參數(shù) shared = nn.Linear(8, 8) net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), shared, nn.ReLU(), shared, nn.ReLU(), nn.Linear(8, 1)) net(X) # 檢查參數(shù)是否相同 print(net[2].weight.data[0] == net[4].weight.data[0]) ''' tensor([True, True, True, True, True, True, True, True]) ''' net[2].weight.data[0, 0] = 100 # 確保它們實際上是同一個對象,而不只是有相同的值 print(net[2].weight.data[0] == net[4].weight.data[0]) ''' tensor([True, True, True, True, True, True, True, True]) '''
自定義層
??本節(jié)代碼文件在源代碼文件的chapter_deep-learning-computation/custom-layer.ipynb中
-
不帶參數(shù)的層
??下面的CenteredLayer類要從其輸入中減去均值。 要構(gòu)建它,我們只需繼承基礎(chǔ)層類并實現(xiàn)前向傳播功能。import torch import torch.nn.functional as F from torch import nn class CenteredLayer(nn.Module): def __init__(self): super().__init__() def forward(self, X): return X - X.mean()
讓我們向該層提供一些數(shù)據(jù),驗證它是否能按預(yù)期工作。
layer = CenteredLayer() layer(torch.FloatTensor([1, 2, 3, 4, 5])) #tensor([-2., -1., 0., 1., 2.])
我們可以將層作為組件合并到更復(fù)雜的模型中,比如:
net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())
-
帶參數(shù)的層
??下面我們定義具有參數(shù)的層, 這些參數(shù)可以通過訓(xùn)練進行調(diào)整。 我們可以使用內(nèi)置函數(shù)來創(chuàng)建參數(shù),這些函數(shù)提供一些基本的管理功能。 比如管理訪問、初始化、共享、保存和加載模型參數(shù)。 這樣做的好處之一是:我們不需要為每個自定義層編寫自定義的序列化程序。
??現(xiàn)在,讓我們實現(xiàn)自定義版本的全連接層。該層需要兩個參數(shù),一個用于表示權(quán)重,另一個用于表示偏置項。 在此實現(xiàn)中,我們使用修正線性單元作為激活函數(shù)。該層需要輸入?yún)?shù):in_units和units,分別表示輸入數(shù)(輸入維度)和輸出數(shù)(輸出維度)。class MyLinear(nn.Module): def __init__(self, in_units, units): super().__init__() self.weight = nn.Parameter(torch.randn(in_units, units)) self.bias = nn.Parameter(torch.randn(units,)) def forward(self, X): linear = torch.matmul(X, self.weight.data) + self.bias.data return F.relu(linear) linear = MyLinear(5, 3) linear.weight ''' Parameter containing: tensor([[ 1.9054, -3.4102, -0.9792], [ 1.5522, 0.8707, 0.6481], [ 1.0974, 0.2568, 0.4034], [ 0.1416, -1.1389, 0.5875], [-0.7209, 0.4432, 0.1222]], requires_grad=True) '''
我們可以使用自定義層直接執(zhí)行前向傳播計算:
linear(torch.rand(2, 5)) ''' tensor([[2.4784, 0.0000, 0.8991], [3.6132, 0.0000, 1.1160]]) '''
我們還可以使用自定義層構(gòu)建模型,就像使用內(nèi)置的全連接層一樣使用自定義層:
net = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1)) net(torch.rand(2, 64)) ''' tensor([[0.], [0.]]) '''
讀寫文件
??本節(jié)代碼文件在源代碼文件的chapter_deep-learning-computation/read-write.ipynb中
??有時我們希望保存訓(xùn)練的模型, 以備將來在各種環(huán)境中使用(比如在部署中進行預(yù)測)。 此外,當(dāng)運行一個耗時較長的訓(xùn)練過程時, 最佳的做法是定期保存中間結(jié)果, 以確保在服務(wù)器電源被不小心斷掉時,我們不會損失幾天的計算結(jié)果。
-
加載和保存張量
??對于單個張量,我們可以直接調(diào)用load和save函數(shù)分別讀寫它們。 這兩個函數(shù)都要求我們提供一個名稱,save要求將要保存的變量作為輸入。import torch from torch import nn from torch.nn import functional as F x = torch.arange(4) torch.save(x, 'x-file')
我們現(xiàn)在可以將存儲在文件中的數(shù)據(jù)讀回內(nèi)存。
x2 = torch.load('x-file') x2 #tensor([0, 1, 2, 3])
??我們可以存儲一個張量列表,然后把它們讀回內(nèi)存。
y = torch.zeros(4) torch.save([x, y],'x-files') x2, y2 = torch.load('x-files') (x2, y2) #(tensor([0, 1, 2, 3]), tensor([0., 0., 0., 0.]))
??我們甚至可以寫入或讀取從字符串映射到張量的字典。 當(dāng)我們要讀取或?qū)懭肽P椭械乃袡?quán)重時,這很方便。
mydict = {'x': x, 'y': y} torch.save(mydict, 'mydict') mydict2 = torch.load('mydict') mydict2 #{'x': tensor([0, 1, 2, 3]), 'y': tensor([0., 0., 0., 0.])}
-
加載和保存模型參數(shù)
??保存單個權(quán)重向量(或其他張量)確實有用, 但是如果我們想保存整個模型,并在以后加載它們, 單獨保存每個向量則會變得很麻煩。 畢竟,我們可能有數(shù)百個參數(shù)散布在各處。 因此,深度學(xué)習(xí)框架提供了內(nèi)置函數(shù)來保存和加載整個網(wǎng)絡(luò)。 需要注意的一個重要細節(jié)是,這將保存模型的參數(shù)而不是保存整個模型。 例如,如果我們有一個3層多層感知機,我們需要單獨指定架構(gòu)。 因為模型本身可以包含任意代碼,所以模型本身難以序列化。 因此,為了恢復(fù)模型,我們需要用代碼生成架構(gòu), 然后從磁盤加載參數(shù)。 讓我們從熟悉的多層感知機開始嘗試一下。class MLP(nn.Module): def __init__(self): super().__init__() self.hidden = nn.Linear(20, 256) self.output = nn.Linear(256, 10) def forward(self, x): return self.output(F.relu(self.hidden(x))) net = MLP() X = torch.randn(size=(2, 20)) Y = net(X)
接下來,我們將模型的參數(shù)存儲在一個叫做“mlp.params”的文件中。
torch.save(net.state_dict(), 'mlp.params')
為了恢復(fù)模型,我們實例化了原始多層感知機模型的一個備份。 這里我們不需要隨機初始化模型參數(shù),而是直接讀取文件中存儲的參數(shù)。
clone = MLP() clone.load_state_dict(torch.load('mlp.params')) clone.eval() ''' MLP( (hidden): Linear(in_features=20, out_features=256, bias=True) (output): Linear(in_features=256, out_features=10, bias=True) ) '''
由于兩個實例具有相同的模型參數(shù),在輸入相同的X時, 兩個實例的計算結(jié)果應(yīng)該相同。 讓我們來驗證一下。
Y_clone = clone(X) Y_clone == Y ''' tensor([[True, True, True, True, True, True, True, True, True, True], [True, True, True, True, True, True, True, True, True, True]]) '''
卷積神經(jīng)網(wǎng)絡(luò)
從全連接層到卷積
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-neural-networks/why-conv.ipynb中
-
重新考察全連接層
??? -
平移不變性
??不管檢測對象出現(xiàn)在圖像中的哪個位置,神經(jīng)網(wǎng)絡(luò)的前面幾層應(yīng)該對相同的圖像區(qū)域具有相似的反應(yīng),即為“平移不變性”。
??? -
局部性
??? -
全連接層與卷積層的關(guān)系
???
圖像卷積
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-neural-networks/conv-layer.ipynb中
-
互相關(guān)運算
??在卷積層中,輸入張量和核張量通過互相關(guān)運算產(chǎn)生輸出張量。
?????
?????
??不同的卷積核可以帶來不同的效果:
????? -
交叉相關(guān)vs卷積
??? -
一維和三維交叉相關(guān)
??? -
一維和三維交叉相關(guān)
???
填充和步幅
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-neural-networks/padding-and-strides.ipynb中
??填充和步幅是卷積層的兩個控制輸出大小的超參數(shù)
-
填充
???
??由于卷積核的寬度和高度通常大于1,在應(yīng)用多層卷積時,我們常常丟失邊緣像素。 由于我們通常使用小卷積核,因此對于任何單個卷積,我們可能只會丟失幾個像素。 但隨著我們應(yīng)用許多連續(xù)卷積層,累積丟失的像素數(shù)就多了。 解決這個問題的簡單方法即為填充:
???
??填充原則:
????? -
步幅
???
??有時候為了高效計算或是縮減采樣次數(shù),卷積窗口可以跳過中間位置,每次滑動多個元素。
???
??步幅原則:
????? -
總結(jié)
???
多輸入多輸出通道
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-neural-networks/channels.ipynb中
-
多個輸入通道
???
??當(dāng)輸入包含多個通道時,需要構(gòu)造一個與輸入數(shù)據(jù)具有相同輸入通道數(shù)的卷積核,以便與輸入數(shù)據(jù)進行互相關(guān)運算。
???
??? -
多個輸出通道
??? -
多個輸入和輸出通道
??? -
1x1卷積層
??? -
二維卷積層
??? -
總結(jié)
???
池化層(匯聚層)
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-neural-networks/pooling.ipynb中
-
卷積層的缺點
??? -
二維最大池化層
???
??? -
池化層vs卷積層
??池化層沒有可學(xué)習(xí)的參數(shù),也不會融合多輸入通道。
??? -
平均池化層
??? -
總結(jié)
???
LeNet
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-neural-networks/lenet.ipynb中
-
手寫數(shù)字識別
??? -
MNIST數(shù)據(jù)集
??? -
LeNet
??LeNet是最早發(fā)布的卷積神經(jīng)網(wǎng)絡(luò)之一,因其在計算機視覺任務(wù)中的高效性能而受到廣泛關(guān)注。 這個模型是由AT&T貝爾實驗室的研究員Yann LeCun在1989年提出的(并以其命名),目的是識別圖像中的手寫數(shù)字。 當(dāng)時,LeNet取得了與支持向量機性能相媲美的成果,成為監(jiān)督學(xué)習(xí)的主流方法。 LeNet被廣泛用于自動取款機(ATM)機中,幫助識別處理支票的數(shù)字。 時至今日,一些自動取款機仍在運行Yann LeCun和他的同事Leon Bottou在上世紀(jì)90年代寫的代碼呢!
??總體來看,LeNet(LeNet-5)由兩個部分組成:
????①卷積編碼器:由兩個卷積層組成。
????②全連接層密集塊:由三個全連接層組成。
??? -
總結(jié)
???
現(xiàn)代卷積神經(jīng)網(wǎng)絡(luò)
深度卷積神經(jīng)網(wǎng)絡(luò)(AlexNet)
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-modern/alexnet.ipynb中
-
機器學(xué)習(xí)VS神經(jīng)網(wǎng)路
??在上世紀(jì)90年代初到2012年之間的大部分時間里,神經(jīng)網(wǎng)絡(luò)往往被其他機器學(xué)習(xí)方法超越,如支持向量機(support vector machines)。
??? -
計算機視覺與幾何學(xué)
??卷積神經(jīng)網(wǎng)絡(luò)通常用在計算機視覺,在2000年時,計算機視覺的知識主要來源于幾何學(xué)。
???? -
計算機視覺與特征工程
??15年前,計算機視覺中,最重要的是特征工程。
???? -
深度學(xué)習(xí)的崛起原因
??盡管一直有一群執(zhí)著的研究者不斷鉆研,試圖學(xué)習(xí)視覺數(shù)據(jù)的逐級表征,然而很長一段時間里這些嘗試都未有突破。深度卷積神經(jīng)網(wǎng)絡(luò)的突破出現(xiàn)在2012年。突破可歸因于兩個關(guān)鍵因素。
①硬件
??2012年,當(dāng)Alex Krizhevsky和Ilya Sutskever實現(xiàn)了可以在GPU硬件上運行的深度卷積神經(jīng)網(wǎng)絡(luò)時,一個重大突破出現(xiàn)了。他們意識到卷積神經(jīng)網(wǎng)絡(luò)中的計算瓶頸:卷積和矩陣乘法,都是可以在硬件上并行化的操作。 于是,他們使用兩個顯存為3GB的NVIDIA GTX580 GPU實現(xiàn)了快速卷積運算。他們的創(chuàng)新cuda-convnet幾年來它一直是行業(yè)標(biāo)準(zhǔn),并推動了深度學(xué)習(xí)熱潮。
???②數(shù)據(jù)
??2009年,ImageNet數(shù)據(jù)集發(fā)布,并發(fā)起ImageNet挑戰(zhàn)賽:要求研究人員從100萬個樣本中訓(xùn)練模型,以區(qū)分1000個不同類別的對象。ImageNet數(shù)據(jù)集由斯坦福教授李飛飛小組的研究人員開發(fā),利用谷歌圖像搜索(Google Image Search)對每一類圖像進行預(yù)篩選,并利用亞馬遜眾包(Amazon Mechanical Turk)來標(biāo)注每張圖片的相關(guān)類別。這種規(guī)模是前所未有的。這項被稱為ImageNet的挑戰(zhàn)賽推動了計算機視覺和機器學(xué)習(xí)研究的發(fā)展,挑戰(zhàn)研究人員確定哪些模型能夠在更大的數(shù)據(jù)規(guī)模下表現(xiàn)最好。
??? -
AlexNet vs LeNet
???
??? -
AlexNet
???
??? -
總結(jié)
???
使用塊的網(wǎng)絡(luò)(VGG)
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-modern/vgg.ipynb中
-
VGG 出現(xiàn)的背景
??? -
VGG 塊
??? -
VGG 架構(gòu)
??? -
進度(發(fā)展)
???
??下圖橫坐標(biāo)代表速率,縱坐標(biāo)代表準(zhǔn)確率,圓的大小代表內(nèi)存占用的大?。?/strong>
??? -
總結(jié)
???
網(wǎng)絡(luò)中的網(wǎng)絡(luò)(NiN)
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-modern/nin.ipynb中
-
全連接層的問題
??? -
NiN 塊
??? -
NiN 架構(gòu)
??? -
NiN 網(wǎng)絡(luò)
???
??? -
總結(jié)
???
含并行連結(jié)的網(wǎng)絡(luò)(GoogLeNet)
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-modern/googlenet.ipynb中
-
GoogLeNet 出現(xiàn)的背景
??我們往往不確定到底選取什么樣的層效果更好,到底是3X3卷積層還是5X5的卷積層,諸如此類的問題是GooLeNet選擇了另一種思路“小學(xué)生才做選擇,我全都要”,這也使得GooLeNet成為了第一個模型中超過1000個層的模型。
???
??? -
Inception 塊
??Inception塊由四條并行路徑組成。 前三條路徑使用窗口大小為1x1、3x3和5x5的卷積層,從不同空間大小中提取信息。 中間的兩條路徑在輸入上執(zhí)行1x1卷積,以減少通道數(shù),從而降低模型的復(fù)雜性。 第四條路徑使用3x3最大匯聚層,然后使用1x1卷積層來改變通道數(shù)。 這四條路徑都使用合適的填充來使輸入與輸出的高和寬一致,最后我們將每條線路的輸出在通道維度上連結(jié),并構(gòu)成Inception塊的輸出。在Inception塊中,通常調(diào)整的超參數(shù)是每層輸出通道數(shù)。
???
??? -
GoogLeNet
??GoogLeNet一共使用9個Inception塊和全局平均匯聚層(Global AvgPool)的堆疊來生成其估計值。Inception塊之間的最大匯聚層可降低維度。 第一個模塊類似于AlexNet和LeNet,Inception塊的組合從VGG繼承,全局平均匯聚層避免了在最后使用全連接層(FC)。
???
???
???
??? -
Inception 有各種后續(xù)變種
??v3是在v2基礎(chǔ)上變化的:
???
???
???
??? -
Inception與其他網(wǎng)絡(luò)的比較
??下圖橫坐標(biāo)代表速率,縱坐標(biāo)代表準(zhǔn)確率,圓的大小代表內(nèi)存占用的大小。由圖可見,Inception V3速率較低,占用內(nèi)存較大,但準(zhǔn)確率很高。
??? -
總結(jié)
???
批量規(guī)范化(歸一化)
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-modern/batch-norm.ipynb中
-
背景
??? -
批量歸一化
??? -
批量歸一化層
??? -
批量歸一化在做什么?
??? -
總結(jié)
???
殘差網(wǎng)絡(luò)(ResNet)
??本節(jié)代碼文件在源代碼文件的chapter_convolutional-modern/resnet.ipynb中
-
加更多的層總是改進精度嗎?
??? -
殘差塊
??? -
ResNet 塊細節(jié)
??? -
不同的殘差塊
??? -
ResNet 塊
??? -
ResNet 架構(gòu)
??? -
ResNet與其他網(wǎng)絡(luò)的比較
??下圖橫坐標(biāo)代表速率,縱坐標(biāo)代表準(zhǔn)確率,圓的大小代表內(nèi)存占用的大小。由圖可見,ResNet 152 速率較低,但占用內(nèi)存較小,且準(zhǔn)確率很高。
??? -
總結(jié)
???
計算性能
深度學(xué)習(xí)硬件(CPU和GPU)
-
電腦CPU、GPU、內(nèi)存之間的關(guān)系
??? -
CPU芯片圖
??? -
提升CPU利用率
???
???
???
??? -
GPU芯片圖
??? -
GPU vs CPU
??? -
提升GPU利用率
??? -
CPU/GPU 帶寬
??? -
更多的 CPUs 和 GPUs
??? -
CPU/GPU 高性能計算編程
??? -
總結(jié)
???
深度學(xué)習(xí)硬件(TPU和其他)
-
手機內(nèi)部的芯片
??? -
DSP:數(shù)字信號處理
??? -
可編程陣列(FPGA)
??? -
AI ASIC
??? -
Systolic Array
???
??? -
總結(jié)
??· 靈活性、易用性:Intel(CPU) > GPU > DSP > FPGA > ASIC
??· 性能功耗:Intel(CPU) < GPU < DSP < FPGA < ASIC
???
單機多卡并行
-
多GPU并行
??? -
單機多卡并行
??? -
數(shù)據(jù)并行 vs 模型并行
??? -
數(shù)據(jù)并行
??? -
總結(jié)
???
分布式訓(xùn)練
-
分布式計算
??本質(zhì)上來說和之前講的單機多卡并行沒有區(qū)別。二者之間的區(qū)別是分布式計算是通過網(wǎng)絡(luò)把數(shù)據(jù)從一臺機器搬到另一臺機器。
??? -
GPU機器架構(gòu)
??總的來說,gpu到gpu的通訊是很快的,gpu到cpu慢一點。機器到機器更慢。因而總體性能的關(guān)鍵就是盡量在本地做通訊而少在機器之間做通訊。
???
舉例:計算一個小批量:
???
???
???
??? -
同步 SGD
??? -
性能
??? -
性能的權(quán)衡
??? -
實踐時的建議
??? -
總結(jié)
???
計算機視覺
圖像增廣
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/image-augmentation.ipynb中
-
數(shù)據(jù)增廣
??? -
數(shù)據(jù)增強
??? -
使用增強數(shù)據(jù)訓(xùn)練
??? -
翻轉(zhuǎn)
??? -
切割
??? -
顏色
??? -
幾十種其他辦法
??? -
總結(jié)
???
微調(diào)
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/fine-tuning.ipynb中
-
微調(diào)的原因
??? -
神經(jīng)網(wǎng)絡(luò)的網(wǎng)絡(luò)架構(gòu)
???
???? -
微調(diào)中的權(quán)重初始化
??? -
訓(xùn)練時的微調(diào)
??? -
重用分類器權(quán)重
??? -
固定一些層
??? -
總結(jié)
???
物體檢測和數(shù)據(jù)集
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/bounding-box.ipynb中
-
圖片分類與目標(biāo)檢測的區(qū)別
??目標(biāo)檢測更加復(fù)雜,需要進行多個物體的識別,還要找出每個物體的位置。目標(biāo)檢測的應(yīng)用場景也更多。
??? -
邊緣框
??? -
目標(biāo)檢測數(shù)據(jù)集
??? -
總結(jié)
???
錨框
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/anchor.ipynb中
-
錨框
??? -
IoU - 交并比
??? -
賦予錨框標(biāo)號
???
??? -
使用非極大值抑制(NMS)輸出
??? -
總結(jié)
???
物體檢測算法:R-CNN,SSD,YOLO
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/rcnn.ipynb中
-
R-CNN
??? -
興趣區(qū)域(RoI)池化層
??目的:每個錨框都可以變成想要的形狀
??? -
Fast RCNN
??RCNN需要對每個錨框進行CNN運算,這些特征抽取計算有重復(fù),并且錨框數(shù)量大,特征抽取的計算量也大。Fast RCNN改進了這種計算量大的問題,使用CNN對整張圖片抽取特征(快的關(guān)鍵),再使用Rol池化層對每個錨框(將在原圖片中搜索到的錨框,映射到CNN得到的結(jié)果上),生成固定長度的特征。
??? -
Faster RCNN
??將CNN結(jié)果輸入到卷積層,然后用錨框去圈區(qū)域,這些錨框很多有好有壞,然后進行預(yù)測,binary 預(yù)測是預(yù)測這個錨框的好壞,即有沒有有效的圈住物體,bounding box prediction預(yù)測是對錨框進行一些改進,最后用NMS(非極大值抑制)對錨框進行合并。
??? -
Mask RCNN
???
??如圖,F(xiàn)aster RCNN精度高但是速度慢(貴):
??? -
總結(jié)
???
單發(fā)多框檢測(SSD)
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/ssd.ipynb中
-
生成錨框
??? -
SSD模型
???
??如圖,SSD速度快但精度不高:
??? -
總結(jié)
???
YOLO
-
YOLO(你只看一次)
???
??如圖,相同精度下YoLo比SSD速度快:
???
語義分割
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/semantic-segmentation-and-dataset.ipynb中
-
語義分割
??? -
應(yīng)用:背景虛化
??? -
應(yīng)用:路面分割
??? -
應(yīng)用:實例分割
???
轉(zhuǎn)置卷積
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/transposed-conv.ipynb中
-
轉(zhuǎn)置卷積
??? -
為什么稱之為“轉(zhuǎn)置”
??? -
轉(zhuǎn)置卷積是一種卷積
??? -
重新排列輸入和核
???
???
??? -
形狀換算
??? -
同反卷積的關(guān)系
??? -
總結(jié)
???
全連接卷積神經(jīng)網(wǎng)絡(luò) FCN
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/fcn.ipynb中
-
全連接卷積神經(jīng)網(wǎng)絡(luò)(FCN)
???
???
樣式遷移
??本節(jié)代碼文件在源代碼文件的chapter_computer-vision/neural-style.ipynb中
-
樣式遷移
???
??? -
基于CNN的樣式遷移
???
循環(huán)神經(jīng)網(wǎng)絡(luò)
序列模型
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-neural-networks/sequence.ipynb中
-
序列數(shù)據(jù)
??? -
序列數(shù)據(jù) - 更多例子
??? -
統(tǒng)計工具
???
??? -
序列模型
???
???
??? -
總結(jié)
???
語言模型
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-neural-networks/language-models-and-dataset.ipynb中
-
語言模型
???
??? -
使用計數(shù)來建模
??? -
N元語法
??? -
總結(jié)
???
循環(huán)神經(jīng)網(wǎng)絡(luò)
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-neural-networks/rnn.ipynb中
-
潛變量自回歸模型
??? -
循環(huán)神經(jīng)網(wǎng)絡(luò)
??? -
使用循環(huán)神經(jīng)網(wǎng)絡(luò)的語言模型
??? -
困惑度(perplexity)
??? -
梯度裁剪
??? -
更多的應(yīng)用RNNs
??? -
總結(jié)
???
現(xiàn)代循環(huán)神經(jīng)網(wǎng)絡(luò)
門控循環(huán)單元GRU
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-modern/gru.ipynb中
-
門控循環(huán)單元GRU
??? -
關(guān)注一個序列
??? -
門
??? -
候選隱狀態(tài)
??? -
隱狀態(tài)
??? -
總結(jié)
???
長短期記憶網(wǎng)絡(luò)(LSTM)
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-modern/lstm.ipynb中
-
長短期記憶網(wǎng)絡(luò)
??? -
門
??? -
候選記憶單元
??? -
記憶單元
??? -
隱狀態(tài)
??? -
總結(jié)
???
深度循環(huán)神經(jīng)網(wǎng)絡(luò)
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-modern/deep-rnn.ipynb中
-
回顧:循環(huán)神經(jīng)網(wǎng)絡(luò)
??? -
Plan A - Nonlinearity in the units
??? -
更深
???
??? -
總結(jié)
???
雙向循環(huán)神經(jīng)網(wǎng)絡(luò)
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-modern/bi-rnn.ipynb中
-
未來很重要
???
??? -
雙向RNN
???
??? -
推理
??? -
總結(jié)
???
編碼器-解碼器
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-modern/encoder-decoder.ipynb中
-
重新考察CNN
??? -
重新考察RNN
??? -
編碼器-解碼器架構(gòu)
??? -
總結(jié)
???
序列到序列學(xué)習(xí)
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-modern/seq2seq.ipynb中
-
序列到序列學(xué)習(xí)(seq2seq)
??? -
機器翻譯
??? -
Seq2seq
??? -
編碼器-解碼器細節(jié)
??? -
訓(xùn)練
??? -
衡量生成序列的好壞的BLEU
??? -
總結(jié)
???
束搜索
??本節(jié)代碼文件在源代碼文件的chapter_recurrent-modern/beam-search.ipynb中
-
貪心搜索
??? -
窮舉搜索
??? -
束搜索
???
??? -
總結(jié)
???
注意力機制
??本節(jié)代碼文件在源代碼文件的chapter_attention-mechanisms/attention-cues.ipynb中
-
心理學(xué)
??? -
注意力機制
??? -
非參注意力池化層
??? -
Nadaraya-Watson核回歸
??? -
參數(shù)化的注意力機制
??? -
總結(jié)
???
注意力分數(shù)
??本節(jié)代碼文件在源代碼文件的chapter_attention-mechanisms/attention-scoring-functions.ipynb中
-
注意力分數(shù)
??? -
拓展到高維度
??? -
Additive Attention
??? -
Scaled Dot-Product Attention
??? -
總結(jié)
???
使用注意力機制的seq2seq
??本節(jié)代碼文件在源代碼文件的chapter_attention-mechanisms/bahdanau-attention.ipynb中
-
動機
??? -
加入注意力
??? -
總結(jié)
???
自注意力
??本節(jié)代碼文件在源代碼文件的chapter_attention-mechanisms/self-attention-and-positional-encoding.ipynb中
-
自注意力
??? -
跟CNN,RNN對比
??? -
位置編碼
??? -
位置編碼矩陣
??? -
絕對位置信息
???
??? -
總結(jié)
???
Transformer
??本節(jié)代碼文件在源代碼文件的chapter_attention-mechanisms/transformer.ipynb中
-
Transformer架構(gòu)
??? -
多頭注意力
???
??? -
有掩碼的多頭注意力
??? -
基于位置的前饋網(wǎng)絡(luò)
??? -
層歸一化
??? -
信息傳遞
??? -
預(yù)測
??? -
總結(jié)
???
自然語言處理:預(yù)訓(xùn)練
BERT預(yù)訓(xùn)練
??本節(jié)代碼文件在源代碼文件的chapter_natural-language-processing-pretraining/bert-pretraining.ipynb中
-
NLP里的遷移學(xué)習(xí)
??? -
BERT的動機
??? -
BERT架構(gòu)
??? -
對輸入的修改
??? -
預(yù)訓(xùn)練任務(wù)1:帶掩碼的語言模型
??? -
預(yù)訓(xùn)練任務(wù)2:下一句子預(yù)測
??? -
總結(jié)
???
自然語言處理:應(yīng)用
BERT微調(diào)
??本節(jié)代碼文件在源代碼文件的chapter_natural-language-processing-applications/finetuning-bert.ipynb中文章來源:http://www.zghlxwxcb.cn/news/detail-599805.html
-
微調(diào) Bert
??? -
句子分類
??? -
命名實體識別
??? -
問題回答
??? -
總結(jié)
???
優(yōu)化算法
優(yōu)化算法
??本節(jié)代碼文件在源代碼文件的chapter_optimization/optimization-intro.ipynb中文章來源地址http://www.zghlxwxcb.cn/news/detail-599805.html
-
優(yōu)化問題
??? -
局部最小 vs 全局最小
??? -
凸集
??? -
凸函數(shù)
??? -
凸函數(shù)優(yōu)化
??? -
凸和非凸例子
??? -
梯度下降
??? -
隨機梯度下降
??? -
小批量隨機梯度下降
??? -
沖量法
??? -
Adam
???
??? -
總結(jié)
???
到了這里,關(guān)于【李沐】動手學(xué)深度學(xué)習(xí) 學(xué)習(xí)筆記的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!