原標題:302頁吳恩達Deeplearning.ai課程筆記,詳記基礎知識與作業代碼
機器之心整理
作者:Wan Zhen
參與:機器之心編輯部
吳恩達的 DeepLearning.ai 已經於 1 月 31 日發布了最後一門課程。近日,來自重慶大學的 Wan Zhen 製作了一份深度學習專項課程筆記,該筆記從神經網絡與深度學習基礎、提升深度神經網絡性能和卷積神經網絡三門課程出發詳細解釋了關鍵概念與作業代碼。本文概括性地介紹了這三課的主要內容,並選擇每個課程主題比較有意思的知識點進行介紹。
在這份筆記中,Wan Zhen 不僅介紹了每個課程的關鍵知識點,同時還詳細解釋了各課程的編程作業。在第一門課程《神經網絡與深度學習基礎》中,該課程筆記不僅提供了最基礎的 Python 和 NumPy 操作筆記,同時還從最基礎的 Logistic 回歸推導到最一般的深度全連接網絡。當然,還介紹了必要的損失函數與反向傳播方法。而在第二門課程中,該筆記詳細記錄了提升深度網絡性能所需要的技巧與基礎,例如初始化、正則化和梯度檢驗等在實踐上大大提升模型性能的方法,以及一般 SGD、動量法和適應性學習率方法等常見的最優化方法。最後,第二門課程重點介紹了 TensorFlow,包括該框架的常用函數和實際構建網絡的過程等。最後一章節主要記錄了卷積神經網絡,包括基本的卷積運算、殘差網絡和目標檢測框架等。
以下是該課程筆記的簡要框架與一些詳細的知識點。
1. 神經網絡與深度學習
這一部分對應的是吳恩達深度學習課程的第一課,主要介紹必要的程式語言和編程工具,並逐步進階介紹線性網絡、非線性網絡、隱藏層網絡到深度網絡的實現方法,細節詳盡,附有完整的代碼。通過這一部分的學習,你將理解神經網絡的結構和數據流(前向傳播和反向傳播),非線性激活函數和隱藏層對學習複雜函數的作用,並知道如何一步步構建完整的(任意結構的、自定義的)神經網絡,體會向量化和模塊化編程思想的妙處。
1.1 Python 基礎和 Numpy
本章第一節介紹了如何使用 Python 的 Numpy 工具包、iPython Notebook 等基本的編程工具。然後介紹如何用這些工具構建神經網絡,特別是理解神經網絡計算的向量化思想和 Python 廣播的使用。
1.2 logistic 回歸
第 2 節介紹如何構建一個準確率為 70% 的 logistic 回歸神經網絡分類器(圖像識別網絡)來識別貓,並介紹如何進一步將準確率提高的方法,以及損失函數的偏導數更新參數的過程。其中特別強調了儘量用向量化結構而不要用循環結構,除非有必要(比如 epoch 的迭代就必須使用循環結構)。
1.2.1 介紹必要的 Python 工具包;1.2.2 介紹數據集的結構;1.2.3 介紹整個學習算法的宏觀架構;1.2.4 介紹構建算法的基本步驟;1.2.5 和 1.2.6 總結前述內容進行代碼實現,並進行了可視化分析;1.2.7 介紹如何用自己的數據集訓練該神經網絡;1.2.8 展示了 logistic 回歸神經網絡的完整代碼。
其中 1.2.4 介紹的構建算法的基本步驟為:
通常 1—3 部分是分開構建的,然後整合到一個函數 model() 中。
1.2.5 對 model() 進行了代碼實現,並畫出了損失函數和梯度的圖像。
圖 1.2.3:損失函數
圖 1.2.4:三種不同學習率的學習曲線對比
1.3 用隱藏層分類平面數據點
第 3 節介紹如何在神經網絡中添加隱藏層以對平面數據點進行分類,本節將教你理解反向傳播的工作過程、隱藏層對捕捉非線性關係的作用,以及構建輔助函數的方法。
重點內容包括:用單個隱藏層實現二分類器;使用非線性激活函數;計算交叉熵損失;實現前向和反向傳播。
1.3.1 介紹必要的工具包;1.3.2 介紹數據集的構成(平面上的紅點和藍點);1.3.3 介紹無隱藏層的 logistic 回歸對該數據集的分類結果;1.3.4 介紹添加了隱藏層的完整模型的實現過程和對該數據集的分類;1.3.5 展示了完整代碼。
其中 1.3.3 的分類結果如下圖所示:
圖 1.3.3:logistic 回歸
1.3.4 中使用的神經網絡的架構:
圖 1.3.4:神經網絡模型
1.3.4 構建神經網絡的方法和 1.2.4 基本相同,重點強調了如何定義隱藏層結構和非線性激活函數的使用,實現代碼後,得到的運行結果為:
圖 1.3.6:有隱藏層分類器的決策邊界
其中,添加了隱藏層之後,必須使用非線性激活函數,因為不使用非線性激活函數的線性層堆疊是無意義的,無法增大模型的複雜度和容量。
1.4 一步步構建完整的深度神經網絡
第 4 節介紹深度神經網絡的完整架構,以及如何構建自定義的模型。完成這部分後,你將學會:使用 ReLU 激活函數提升模型的性能、構建更深的模型(隱藏層數大於 1),以及實現易用的神經網絡(模塊化思想)。
1.4.1 介紹必要的工具包;1.4.2 介紹任務概述;1.4.3 介紹從 2 層網絡到 L 層網絡的初始化過程;1.4.4 介紹前向傳播模塊的構建,從線性前向傳播、線性+非線性激活前向傳播,再到 L 層網絡的前向傳播;1.4.5 介紹損失函數;1.4.6 介紹反向傳播模塊的構建,從線性反向傳播、線性+非線性激活反向傳播,再到 L 層網絡的反向傳播;1.4.7 展示了深度神經網絡的完整代碼。
圖 1.4.1:任務概述
圖 1.4.3:前向傳播和反向傳播的線性—ReLU—線性—sigmoid 的過程圖示。上方表示前向傳播,下方表示反向傳播。
1.5 深度神經網絡的圖像分類應用
通過前面四節的學習,你已學會如何一步一步構建完整的深度神經網絡。第 5 節介紹如何用深度神經網絡構建貓識別分類器。此前在 logistic 回歸網絡中,識別準確率只能達到 68%,而在完整的深度網絡中,識別準確率能達到 80%!
完成本節後,你將學會:用前面介紹的所有輔助函數構建任意結構的神經網絡;試驗不同結構的神經網絡,並進行分析;理解構建輔助函數對構建網絡的好處(對比從零開始)。
1.5.1 介紹必要的工具包;1.5.2 介紹數據集(貓 vs. 非貓);1.5.3 介紹模型架構,其中分別構建了 2 層和 L 層的神經網絡;1.5.4 介紹 2 層神經網絡的訓練和測試結果;1.5.5 介紹 2 層神經網絡的訓練和測試結果;1.5.6 對結果進行分析;1.5.7 介紹如何用你自己的圖像訓練分類模型;1.5.8 展示了完整代碼。
其中,2 層神經網絡的運行結果:
圖 1.5.4:2 層神經網絡的損失函數
運行結果:
圖 1.5.5:L 層神經網絡的損失函數
運行結果:
通過比較可知,更深的網絡有助於提高識別準確率(0.72 vs. 0.8;2 層 vs. 5 層)。
1.5.6 簡單總結了影響識別錯誤的因素:
這些識別錯誤可能跟全連接網絡自身的局限性有關,包括參數共享、過擬合傾向(參數數量)和層級特徵方面,而這些問題將在卷積神經網絡裡得到改善。
2. 提升深度神經網絡性能
這一部分對應吳恩達 deeplearning.ai 的第二門課程,重點從超參數調整、隨機和 Xavier 等參數初始化方法、Dropout 和 L2 範數等正則化方法、以及 1 維和 N 維梯度檢驗方法來描述深度學習在實踐上的性能提升方法。當然,這一部分不僅包含課程知識點,還展示了課後問答與實現作業。
最優化在這一部分課程中也得到了重點講解,Wan Zhen 的課程筆記從最基本的最速下降法到小批量隨機梯度下降介紹了基本的一階梯度法,然後再探討動量法與適應性學習率方法來利用歷史梯度獲得更好的下降方向。值得注意的是,該筆記詳細介紹了 Adam 最優化方法的更新過程與實現代碼。
這門課程最後一部分主要展現了 TensorFlow 的基本函數與實際構建神經網絡的過程。
在參數初始化、正則化和梯度檢驗中,比較有意思的是 He 初始化和 Dropout 的機制,下面我們將詳細探討這兩個組件。
He 初始化(He Initialization,He et al., 2015)是根據第一作者的名字而確定的。如果讀者了解 Xavier 初始化,那麼其實它們是非常相似的,只不過 Xavier 初始化會為權重 W^l 使用標量元素 sqrt(1./layers_dim[l-1]),而 He 初始化會使用 sqrt(2./layers_dims[l-1])。以下展示了如何實現 He 初始化,這一部分是課程作業的答案:
最後,該文檔還總結了三種初始化的效果。如下所示,它們都在相同迭代數、相同的超參數和相同網絡架構下進行測試:
Dropout
在正則化方法中,Dropout 是非常有用和成功的一種技術。雖然近來有研究者發現把它和批歸一化(BN)一起使用會產生一些衝突,但仍然不影響它作為一種強大的技術來控制模型過擬合。一般來說,Dropout 會隨機刪除一些神經元,以在不同批量上訓練不同的神經網絡架構。
Bagging 是通過結合多個模型降低泛化誤差的技術,主要的做法是分別訓練幾個不同的模型,然後讓所有模型表決測試樣例的輸出。而 Dropout 可以被認為是集成了大量深層神經網絡的 Bagging 方法,因此它提供了一種廉價的 Bagging 集成近似方法,能夠訓練和評估值數據數量的神經網絡。
圖:在第一層和第三層採用 Dropout。
在每一個批量的前向傳播與反向更新中,我們關閉每個神經元的概率為 1-keep_prob,且關閉的神經元不參與前向傳播計算與參數更新。每當我們關閉一些神經元,我們實際上修改了原模型的結構,那麼每次迭代都訓練一個不同的架構,參數更新也更加關注激活的神經元。這種正則化方法可以看成是一種集成方法,即集成每個批量所訓練的不同網絡架構。
在正則化方法中,該筆記也比較了 L2 正則化和 Dropout 的效果:
在後面的最優化方法中,我們比較感興趣的是 Adam 方法,因此下面我們也將重點描述該方法。
Adam
Adam 算法和傳統的隨機梯度下降不同。隨機梯度下降保持單一的學習率(即 alpha)更新所有的權重,學習率在訓練過程中並不會改變。而 Adam 通過計算梯度的一階矩估計和二階矩估計,為不同的參數設計獨立的自適應性學習率。
Adam 算法的提出者描述其為兩種隨機梯度下降擴展式的優點集合,即:
Adam 算法同時具備 AdaGrad 和 RMSProp 算法的優點。Adam 不僅如 RMSProp 算法那樣基於一階矩均值計算適應性參數學習率,它同時還充分利用了梯度的二階矩均值(即有偏方差/uncentered variance)。具體來說,算法計算了梯度的指數移動均值(exponential moving average),超參數 beta1 和 beta2 控制了這些移動均值的衰減率。
移動均值的初始值和 beta1、beta2 值接近於 1(推薦值),因此矩估計的偏差接近於 0。該偏差通過首先計算帶偏差的估計而後計算偏差修正後的估計而得到提升。
正如該筆記所總結的,Adam 的計算更新過程可分為三部分:
1. 計算歷史梯度的指數加權平均值,並將它儲存在變量 v 中(有偏估計),然後再計算 v^corrected(修正後得出的無偏估計)。
2. 計算歷史梯度平方的指數加權平均值,並將它儲存為變量 s(有偏估計),然後計算 s^corrected(修正的無偏估計)。
3. 然後結合前兩步的信息更新參數。
這一更新過程如筆記所述可表示為:
其中 t 會計算 Adam 所迭代更新的次數、L 為層級數、β_1 和β_1 為控制指數加權平均值得超參數、α 為學習率,而 ε 為避免分母為零的小常數。
Wan Zhen 同樣給出了 Adam 的實現代碼或作業解讀:
以下實現了上面描述的參數更新過程:
該章節同樣介紹和對比了這幾個最優化方法的優勢:
TensorFlow
最後一部分重點介紹了 TensorFlow 的函數與實踐。TensorFlow 是一種採用數據流圖(data flow graphs),用於數值計算的開源軟體庫。其中 Tensor 代表傳遞的數據為張量(多維數組),Flow 代表使用計算圖進行運算。數據流圖用「結點」(nodes)和「邊」(edges)組成的有向圖來描述數學運算。「結點」一般用來表示施加的數學操作,但也可以表示數據輸入的起點和輸出的終點,或者是讀取/寫入持久變量(persistent variable)的終點。邊表示結點之間的輸入/輸出關係。這些數據邊可以傳送維度可動態調整的多維數據數組,即張量(tensor)。
這一部分筆記重點介紹了課程的測試和實現代碼,例如以下構建了簡單的佔位符:
定義變量和常量的方法:
初始化參數的方法:
運行計算圖:
3. 卷積神經網絡
在大神吳恩達的第四課裡我們學習的是卷積神經網絡也就是 CNN,這一章的習題是讓你用 Numpy 實現一個卷積層和一個池化層同時還有前饋和反向傳播。你所能用到的包有:
列舉一下你將要學習實現的函數:
1. 卷積函數,包括:
2. 池化函數,包括:
第一個作業要求用 Numpy 一點點實現這些函數,下一個作業要求用 TensorFlow 裡的函數建立模型。
第三章裡講了卷積神經網絡、池化層和卷積神經網絡的反向傳播。卷積神經網絡這部分講了零填充、單步卷積和前饋卷積網絡;池化層這部分講了前向池化;卷積神經網絡的反向傳播這部分講了卷積層反傳和池化層反傳。
3.1.3 卷積網絡
雖然編程框架使卷積易於使用,但卷積仍是深度學習裡最難懂的一部分。卷積網絡大致上會像下圖一樣把輸入轉化成輸出:
為了幫助大家進一步理解卷積,小編在這裡著重寫一下卷積的操作。
在這部分,我們會實現一個單步的卷積,就是你用一個濾波器(filter)在輸入的單個位置上執行一下,然後整個的卷積結果就是不斷地拖動這個濾波器在輸入值的所有位置上執行。我們要做的:
1:拿到輸入數據;
2:使用濾波器在輸入數據的每一個位置上執行一下;
3:輸出另一個數據(一般和輸入數據大小不一樣)。
在計算機視覺裡,矩陣中每一個值對應的都是單個的像素值,我們用一個 3*3 大小的濾波器去捲圖片,就是在每一個位置上,用濾波器裡的每一個值去乘原始矩陣裡對應位置上的值,然後求和之後再加上一個偏差數值,然後再拖動這個濾波器去下一個位置上,這就是卷積,每一次拖動的距離叫做步長。在第一步練習裡,你將要實現一個一步的卷積,這個一步的卷積是使用一個濾波器在輸入數據一個位置上卷積得到的單個的實數輸出。
練習:實現 conv_single_step() 函數
代碼:
再大致講一下卷積神經網絡前傳(Forward pass)。
之前我們講了怎樣用一個濾波器去做卷積,在前傳裡是用好多個濾波器一個一個地卷積然後把結果(2D 的)一層一層地堆成一個 3D 的結構。
詳細信息更有意思,請學習吳恩達的課程。
3.1.4 池化層
池化層很好玩,為了降低輸入數據的大小,減少計算量,就有了池化層,同時池化層也會幫助特徵檢測器更獨立於位置信息。這裡介紹兩種池化層:
滑動一個 (f,f) 大小的窗口到輸入的數據上,在窗口裡取最大的一個值為輸出然後把這個值存到準備輸出的數據裡。
從名字就可以看出它需要同樣地滑動一個 (f,f) 大小的窗口到輸入數據上面,然後求窗口中數據的平均值,再把這個值儲存到要輸出的值裡。
這些池化層沒有參數可以被訓練,但對於窗口的大小 f,你可以自己去嘗試然後選擇最好的。
3.2 卷積神經網絡應用
在這一部分裡吳老師講了 TensorFlow 模型、創建佔位符、初始參數、前向傳播、計算損失及模型。
在這裡我們聊一聊怎麼初始化參數吧。你需要用 tf.contrib.layers.xavier_initializer(seed=0) 來初始化權重/濾波器 W1 和 W2。你不需要擔心偏重值因為很快你就能發現 TensorFlow 函數已經解決了這一點。注意,你只需初始 conv2d 函數的權重/濾波器,TensorFlow 會自動初始全連接部分的層。我們會在之後的作業裡看到更多。
練習:實現 initialize_parameters(). 每一組濾波器/權重的維度已經提供給大家。記住,在 TensorFlow 裡初始化一個形狀為 [1,2,3,4] 的參數 W 用:
More Info. 更多的信息:
3.3 Keras 教程:幸福家(Happy House)
這一部分講了一個作業(幸福家),怎樣用 Keras 建模型、總結、用自己的圖片去測試其他非常有用的 Keras 函數。在這裡我們著重講一下幸福家是什麼:
3.3.1 幸福家
下一次放假旅行,你決定和你的 5 個在學校認識的朋友一起度過一周。這附近有一個非常方便的房子可以做很多事情。但最重要的福利是在房子裡的時候每個人都必須要快樂。所以每個想進房間的人都要提供他們現在的幸福情形。
作為一個深度學習專家,要確保「開心」這一規則被堅決的執行了,你要去建一個算法來通過前門的攝像頭得到的照片來檢查這個人是不是開心。
你已經收集到了你和朋友在前門照的照片,資料庫已經被標註了。0 代表不開心,1 代表開心。
跑一下下面的程序讓資料庫更加標準化,然後學習一下它的形態。
幸福家資料庫的細節:
現在去解決「快樂」挑戰吧!
3.4 殘差網絡
這一部分介紹了非常深的深度神經網絡的問題,如何構建殘差模塊、殘差連接、卷積塊等,並組合它們而建造第一個殘差網絡模型以及用自己的圖片去實驗。
殘差網絡可以解決一些非常深的深度神經網絡所具有的問題,我們在這裡著重談一下非常深的深度網絡的問題。
近幾年,神經網絡變得越來越深了,最前沿的網絡有幾層的,也有超過一百層的。
深度神經網絡最主要的優勢是它可以表示非常複雜的函數。它也可以從不同的抽象等級去學習從邊緣特徵(淺層)到複雜的特徵(深層)。但是,用一個更深的神經網絡不總是有效。一個大缺點是訓練模型的時候梯度會消失:非常深的網絡經常會非常快地梯度下降到 0。這樣會讓梯度下降變得不可忍受的慢,因為每一次只會更新一點點。更具體地,在梯度下降的時候,當你反向傳播從最後一層一直到第一層的時候,每一步都在乘以權重矩陣,所以梯度會以指數函數的速率下降到 0(或者在有些極少的情況裡,梯度以指數函數的速率產生爆炸)。
在訓練的時候,你也能看到前面層的梯度數值非常快地下降到 0。
你現在可以用殘差網絡解決這個問題。
3.5 用 YOLOv2 檢測車輛
這一部分講了:問題敘述、YOLO、模型細節、用一個門檻來過濾一個班的分數、非最大抑制、包裝過濾器、在圖片上測試 YOLO 模型、定義類、轉折點和圖片大小、加載一個訓練好的模型、轉化輸出模型到一個可用的邊界盒張量、過濾盒及對圖片跑計算圖。
在這裡我們講一下問題是什麼:
你現在在做一個自動駕駛車,作為一個重要的部分,你想先建一個車輛檢測系統,當你開車時候這個系統會每隔幾秒照一下前面的路。
你現在已經收集了所有的這些圖片到一個文件夾裡然後也已經用框標註出了每一個你可以找到的車。這裡是例子:
p 代表了你有多自信圈出來的是什麼,c 代表了你認為圈出來的是什麼。
如果你想讓 YOLO 認出 80 種類別, 你可以讓 c 表示 1 到 80 中的一個數,或者 c 是一個 80 長度的矢量。視頻課裡已經用了後一種表示。在這個筆記裡,我們兩種都用了,這取決於哪種更好用。在這個練習裡,你將要學習 YOLO 怎樣工作,怎樣運用這個區檢測車。因為 YOLO 訓練的時候非常耗費計算量,我們將會加載訓練好的權重來用。
3.6 快樂家中的臉部識別
在這一張裡我們可以看到:簡略臉部識別,臉部圖片編成一個人 128 維度的矢量,使用 ConvNet 來計算編碼,三聯損失,加載訓練好的模型和運用訓練好的模型。
我們著重介紹一下簡略臉部識別:
在臉部識別裡,給你兩張圖片然後你必須告訴我兩個人是否是同一個。最簡單的做法是比較兩張圖片中的每一個像素,如果兩張原始圖片的比較結果小於一個門檻值則可以說兩張圖片是一個人。
當然,這個算法的性能非常差,因為像素的值會隨著光的改變,方向的改變,甚至鏡像改變頭的位置而劇烈的改變。你將看到除了用原始圖片你更願意編碼一個 f(image) 來比較每一個像素這樣會給你一個關於兩張照片是不是一個人的問題更準確的答案。
3.7 通過神經風格遷移生成藝術
在這一章節中,我們將嘗試實現神經風格遷移,並使用算法生成新穎的藝術風格圖像。在神經風格遷移中,重點是我們需要優化成本函數獲得像素的值。如下所示,我們使用某張圖像的風格,並遷移到需要這種風格的圖像中:
神經風格遷移主要使用預訓練的卷積神經網絡,並在它的頂部構建新的層級。這種使用預訓練模型,並將其應用到新任務的方法可以稱為遷移學習。卷積網絡的遷移學習非常簡單,一般來說,我們可以將最後幾個分類層的權重隨機初始化,再在新的數據集上訓練而快速獲得優秀的性能。
在 NST 原論文中,我們會使用 VGG-19 網絡,它會預先在 ImageNet 上實現訓練。因此在 Wan Zhen 的筆記中,我們可以運行以下命令下載模型及參數;
然後使用 assign 方法將圖像作為模型的輸入:
隨後,我們就能使用以下代碼獲取特定層級的激活值;
在神經風格遷移中,重點是以下三個步驟:
使用這樣的損失函數,最終我們能以遷移學習的方法實現神經風格遷移。
本文為機器之心整理,轉載請聯繫原作者獲得授權。返回搜狐,查看更多
責任編輯: