302頁吳恩達Deeplearning.ai課程筆記,詳記基礎知識與作業代碼

2020-11-29 搜狐網

原標題:302頁吳恩達Deeplearning.ai課程筆記,詳記基礎知識與作業代碼

機器之心整理

作者:Wan Zhen

參與:機器之心編輯部

吳恩達的 DeepLearning.ai 已經於 1 月 31 日發布了最後一門課程。近日,來自重慶大學的 Wan Zhen 製作了一份深度學習專項課程筆記,該筆記從神經網絡與深度學習基礎、提升深度神經網絡性能和卷積神經網絡三門課程出發詳細解釋了關鍵概念與作業代碼。本文概括性地介紹了這三課的主要內容,並選擇每個課程主題比較有意思的知識點進行介紹。

  • 資源連結:https://pan.baidu.com/s/1oAqpmUe 提取密碼:5nmn

在這份筆記中,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 初始化,這一部分是課程作業的答案:

  1. # GRADED FUNCTION: initialize_parameters_he
  2. def initialize_parameters_he(layers_dims):
  3. """
  4. Arguments:
  5. layer_dims -- python array (list) containing the size of each
  6. ,→ layer.
  7. Returns:
  8. parameters -- python dictionary containing your parameters "W1",
  9. ,→ "b1", ..., "WL", "bL":
  10. W1 -- weight matrix of shape (layers_dims[1],
  11. ,→ layers_dims[0])
  12. b1 -- bias vector of shape (layers_dims[1], 1)
  13. ...
  14. WL -- weight matrix of shape (layers_dims[L],
  15. ,→ layers_dims[L-1])
  16. bL -- bias vector of shape (layers_dims[L], 1)
  17. """
  18. np.random.seed(3)
  19. parameters = {}
  20. L = len(layers_dims) - 1 # integer representing the number of
  21. ,→ layers
  22. for l in range(1, L + 1):
  23. ### START CODE HERE ### (
  24. 2 lines of code)
  25. parameters['W' + str(l)] = np.random.randn(layers_dims[l],
  26. ,→ layers_dims[l-1]) * np.sqrt(2./layers_dims[l-1])
  27. parameters['b' + str(l)] = np.zeros((layers_dims[l], 1))
  28. ### END CODE HERE ###
  29. return parameters

最後,該文檔還總結了三種初始化的效果。如下所示,它們都在相同迭代數、相同的超參數和相同網絡架構下進行測試:

Dropout

在正則化方法中,Dropout 是非常有用和成功的一種技術。雖然近來有研究者發現把它和批歸一化(BN)一起使用會產生一些衝突,但仍然不影響它作為一種強大的技術來控制模型過擬合。一般來說,Dropout 會隨機刪除一些神經元,以在不同批量上訓練不同的神經網絡架構。

Bagging 是通過結合多個模型降低泛化誤差的技術,主要的做法是分別訓練幾個不同的模型,然後讓所有模型表決測試樣例的輸出。而 Dropout 可以被認為是集成了大量深層神經網絡的 Bagging 方法,因此它提供了一種廉價的 Bagging 集成近似方法,能夠訓練和評估值數據數量的神經網絡。

圖:在第一層和第三層採用 Dropout。

在每一個批量的前向傳播與反向更新中,我們關閉每個神經元的概率為 1-keep_prob,且關閉的神經元不參與前向傳播計算與參數更新。每當我們關閉一些神經元,我們實際上修改了原模型的結構,那麼每次迭代都訓練一個不同的架構,參數更新也更加關注激活的神經元。這種正則化方法可以看成是一種集成方法,即集成每個批量所訓練的不同網絡架構。

在正則化方法中,該筆記也比較了 L2 正則化和 Dropout 的效果:

在後面的最優化方法中,我們比較感興趣的是 Adam 方法,因此下面我們也將重點描述該方法。

Adam

Adam 算法和傳統的隨機梯度下降不同。隨機梯度下降保持單一的學習率(即 alpha)更新所有的權重,學習率在訓練過程中並不會改變。而 Adam 通過計算梯度的一階矩估計和二階矩估計,為不同的參數設計獨立的自適應性學習率。

Adam 算法的提出者描述其為兩種隨機梯度下降擴展式的優點集合,即:

  • 適應性梯度算法(AdaGrad)為每一個參數保留一個學習率,以提升在稀疏梯度(即自然語言和計算機視覺問題)上的性能。
  • 均方根傳播(RMSProp)基於權重梯度最近量級的均值為每一個參數適應性地保留學習率。這意味著算法在非穩態和在線問題上有很優秀的性能。

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 的實現代碼或作業解讀:

  1. # GRADED FUNCTION: initialize_adam
  2. def initialize_adam(parameters) :
  3. """
  4. Initializes v and s as two python dictionaries with:
  5. - keys: "dW1", "db1", ..., "dWL", "dbL"
  6. - values: numpy arrays of zeros of the same shape as
  7. ,→ the corresponding gradients/parameters.
  8. Arguments:
  9. parameters -- python dictionary containing your parameters.
  10. parameters["W" + str(l)] = Wl
  11. parameters["b" + str(l)] = bl
  12. Returns:
  13. v -- python dictionary that will contain the exponentially weighted
  14. ,→ average of the gradient.
  15. v["dW" + str(l)] = ...
  16. v["db" + str(l)] = ...
  17. s -- python dictionary that will contain the exponentially weighted
  18. ,→ average of the squared gradient.
  19. s["dW" + str(l)] = ...
  20. s["db" + str(l)] = ...
  21. """
  22. L = len(parameters) // 2 # number of layers in the neural networks
  23. v = {}
  24. s = {}
  25. # Initialize v, s. Input: "parameters". Outputs: "v, s".
  26. for l in range(L):
  27. ### START CODE HERE ### (approx. 4 lines)
  28. v["dW" + str(l+1)] = np.zeros(parameters["W" + str(l+1)].shape)
  29. v["db" + str(l+1)] = np.zeros(parameters["b" + str(l+1)].shape)
  30. s["dW" + str(l+1)] = np.zeros(parameters["W" + str(l+1)].shape)
  31. s["db" + str(l+1)] = np.zeros(parameters["b" + str(l+1)].shape)
  32. ### END CODE HERE ###
  33. return v, s

以下實現了上面描述的參數更新過程:

  1. # GRADED FUNCTION: update_parameters_with_adam
  2. def update_parameters_with_adam(parameters, grads, v, s, t, learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, epsilon = 1e-8):
  3. L = len(parameters) // 2 # number of layers in the neural networks
  4. v_corrected = {} # Initializing first moment estimate, python, dictionary
  5. s_corrected = {} # Initializing second moment estimate, python
  6. ,→ dictionary
  7. # Perform Adam update on all parameters
  8. for l in range(L):
  9. # Moving average of the gradients. Inputs: "v, grads, beta1".
  10. ,→ Output: "v".
  11. v["dW" + str(l+1)] = beta1*v["dW" +
  12. ,→ str(l+1)]+(1-beta1)*grads['dW' + str(l+1)]
  13. v["db" + str(l+1)] = beta1*v["db" + str(l+1)]+(1-beta1)*grads['db' + str(l+1)]
  14. # Compute bias-corrected first moment estimate. Inputs: "v, beta1, t". Output: "v_corrected".
  15. v_corrected["dW" + str(l+1)] = v["dW" + str(l+1)]/(1-math.pow(beta1,t))
  16. v_corrected["db" + str(l+1)] = v["db" + str(l+1)]/(1-math.pow(beta1,t))
  17. # Moving average of the squared gradients. Inputs: "s, grads, beta2". Output: "s".
  18. s["dW" + str(l+1)] = beta2*s["dW" + str(l+1)]+(1-beta2)*(grads['dW' + str(l+1)]**2)
  19. s["db" + str(l+1)] = beta2*s["db" + str(l+1)]+(1-beta2)*(grads['db' + str(l+1)]**2)
  20. # Compute bias-corrected second raw moment estimate. Inputs: "s, beta2, t". Output: "s_corrected".
  21. s_corrected["dW" + str(l+1)] = s["dW" + str(l+1)]/(1-math.pow(beta2,t))
  22. s_corrected["db" + str(l+1)] = s["db" + str(l+1)]/(1-math.pow(beta2,t))
  23. # Update parameters. Inputs: "parameters, learning_rate, v_corrected, s_corrected, epsilon". Output: "parameters".
  24. parameters["W" + str(l+1)] = parameters["W" + str(l+1)]-learning_rate * v_corrected["dW" + str(l+1)]/(np.sqrt(s_corrected["dW" + str(l+1)])+epsilon)
  25. parameters["b" + str(l+1)] = parameters["b" + str(l+1)]-learning_rate * v_corrected["db" + str(l+1)]/(np.sqrt(s_corrected["db" + str(l+1)])+epsilon)
  26. return parameters, v, s

該章節同樣介紹和對比了這幾個最優化方法的優勢:

TensorFlow

最後一部分重點介紹了 TensorFlow 的函數與實踐。TensorFlow 是一種採用數據流圖(data flow graphs),用於數值計算的開源軟體庫。其中 Tensor 代表傳遞的數據為張量(多維數組),Flow 代表使用計算圖進行運算。數據流圖用「結點」(nodes)和「邊」(edges)組成的有向圖來描述數學運算。「結點」一般用來表示施加的數學操作,但也可以表示數據輸入的起點和輸出的終點,或者是讀取/寫入持久變量(persistent variable)的終點。邊表示結點之間的輸入/輸出關係。這些數據邊可以傳送維度可動態調整的多維數據數組,即張量(tensor)。

這一部分筆記重點介紹了課程的測試和實現代碼,例如以下構建了簡單的佔位符:

  1. ### START CODE HERE ### (approx. 2 lines)
  2. X = tf.placeholder(tf.float32, [n_x, None], name = 'X')
  3. Y = tf.placeholder(tf.float32, [n_y, None], name = 'Y')
  4. ### END CODE HERE ###
  5. return X, Y
  6. return parameters, v, s

定義變量和常量的方法:

  1. a = tf.constant(2, tf.int16)
  2. b = tf.constant(4, tf.float32)
  3. g = tf.constant(np.zeros(shape=(2,2), dtype=np.float32))
  4. d = tf.Variable(2, tf.int16)
  5. e = tf.Variable(4, tf.float32)
  6. h = tf.zeros([11], tf.int16)
  7. i = tf.ones([2,2], tf.float32)
  8. k = tf.Variable(tf.zeros([2,2], tf.float32))
  9. l = tf.Variable(tf.zeros([5,6,5], tf.float32))
  10. return parameters, v, s

初始化參數的方法:

  1. W1 = tf.get_variable("W1", [25,12288], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
  2. b1 = tf.get_variable("b1", [25,1], initializer = tf.zeros_initializer())
  3. return parameters, v, s

運行計算圖:

  1. a = tf.constant(2, tf.int16)
  2. b = tf.constant(4, tf.float32)
  3. graph = tf.Graph()
  4. with graph.as_default():
  5. a = tf.Variable(8, tf.float32)
  6. b = tf.Variable(tf.zeros([2,2], tf.float32))
  7. with tf.Session(graph=graph) as session:
  8. tf.global_variables_initializer().run()
  9. print(f)
  10. print(session.run(a))
  11. print(session.run(b))
  12. #輸出:
  13. >>> <tf.Variable 'Variable_2:0' shape=() dtype=int32_ref>
  14. >>> 8
  15. >>> [[ 0. 0.]
  16. >>> [ 0. 0.]]
  17. return parameters, v, s

3. 卷積神經網絡

在大神吳恩達的第四課裡我們學習的是卷積神經網絡也就是 CNN,這一章的習題是讓你用 Numpy 實現一個卷積層和一個池化層同時還有前饋和反向傳播。你所能用到的包有:

  • Numpy:一個基本的在 Python 裡用來做科學計算的包。
  • Matplotlib:用來畫圖。

列舉一下你將要學習實現的函數:

1. 卷積函數,包括:

  • 零填充(zero padding)
  • 卷積窗(convolve window)
  • 前向卷積(convolution forward)
  • 反向卷積(convolution backward)

2. 池化函數,包括:

  • 前向池化(Pooling forward)
  • 創建掩碼(create mask)
  • 分布值(distribute value)
  • 反向池化(Pooling backward)

第一個作業要求用 Numpy 一點點實現這些函數,下一個作業要求用 TensorFlow 裡的函數建立模型。

第三章裡講了卷積神經網絡、池化層和卷積神經網絡的反向傳播。卷積神經網絡這部分講了零填充、單步卷積和前饋卷積網絡;池化層這部分講了前向池化;卷積神經網絡的反向傳播這部分講了卷積層反傳和池化層反傳。

3.1.3 卷積網絡

雖然編程框架使卷積易於使用,但卷積仍是深度學習裡最難懂的一部分。卷積網絡大致上會像下圖一樣把輸入轉化成輸出:

為了幫助大家進一步理解卷積,小編在這裡著重寫一下卷積的操作。

在這部分,我們會實現一個單步的卷積,就是你用一個濾波器(filter)在輸入的單個位置上執行一下,然後整個的卷積結果就是不斷地拖動這個濾波器在輸入值的所有位置上執行。我們要做的:

1:拿到輸入數據;

2:使用濾波器在輸入數據的每一個位置上執行一下;

3:輸出另一個數據(一般和輸入數據大小不一樣)。

在計算機視覺裡,矩陣中每一個值對應的都是單個的像素值,我們用一個 3*3 大小的濾波器去捲圖片,就是在每一個位置上,用濾波器裡的每一個值去乘原始矩陣裡對應位置上的值,然後求和之後再加上一個偏差數值,然後再拖動這個濾波器去下一個位置上,這就是卷積,每一次拖動的距離叫做步長。在第一步練習裡,你將要實現一個一步的卷積,這個一步的卷積是使用一個濾波器在輸入數據一個位置上卷積得到的單個的實數輸出。

練習:實現 conv_single_step() 函數

代碼:

  1. # GRADED FUNCTION: conv_single_step
  2. def conv_single_step(a_slice_prev, W, b): """
  3. Apply one filter defined by parameters W on a single slice
  4. → (a_slice_prev)oftheoutputactivation
  5. of the previous layer.
  6. Arguments:
  7. a_slice_prev -- slice of input data of shape (f, f, n_C_prev)
  8. W -- Weight parameters contained in a window - matrix of shape (f,
  9. → f,n_C_prev)
  10. b -- Bias parameters contained in a window - matrix of shape (1, 1,
  11. → 1)
  12. Returns:
  13. Z -- a scalar value, result of convolving the sliding window (W, b)
  14. → onaslicexoftheinputdata
  15. """
  16. ### START CODE HERE ### ( 2 lines of code)
  17. # Element-wise product between a_slice and W. Add bias. s = a_slice_prev * W + b
  18. # Sum over all entries of the volume s
  19. Z = np.sum(s)
  20. ### END CODE HERE ###
  21. return Z
  22. return parameters, v, s

再大致講一下卷積神經網絡前傳(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 用:

  1. W = tf.get_variable("W", [1,2,3,4], initializer = ...)

More Info. 更多的信息:

  1. More Info.更多的信息:
  2. # GRADED FUNCTION: initialize_parameters
  3. def initialize_parameters(): """
  4. Initializes weight parameters to build a neural network with → tensorflow.Theshapesare:
  5. W1 : [4, 4, 3, 8]
  6. W2 : [2, 2, 8, 16]
  7. Returns:
  8. parameters -- a dictionary of tensors containing W1, W2
  9. """
  10. tf.set_random_seed(1) # so that your → "random"numbersmatchours
  11. ### START CODE HERE ### (approx. 2 lines of code)
  12. W1 = tf.get_variable("W1", [4, 4, 3, 8], initializer → =tf.contrib.layers.xavier_initializer(seed=0)) W2 = tf.get_variable("W2", [2, 2, 8, 16], initializer → =tf.contrib.layers.xavier_initializer(seed=0))
  13. ### END CODE HERE ###
  14. parameters = {"W1": W1,
  15. "W2": W2}
  16. return parameters

3.3 Keras 教程:幸福家(Happy House)

這一部分講了一個作業(幸福家),怎樣用 Keras 建模型、總結、用自己的圖片去測試其他非常有用的 Keras 函數。在這裡我們著重講一下幸福家是什麼:

3.3.1 幸福家

下一次放假旅行,你決定和你的 5 個在學校認識的朋友一起度過一周。這附近有一個非常方便的房子可以做很多事情。但最重要的福利是在房子裡的時候每個人都必須要快樂。所以每個想進房間的人都要提供他們現在的幸福情形。

作為一個深度學習專家,要確保「開心」這一規則被堅決的執行了,你要去建一個算法來通過前門的攝像頭得到的照片來檢查這個人是不是開心。

你已經收集到了你和朋友在前門照的照片,資料庫已經被標註了。0 代表不開心,1 代表開心。

跑一下下面的程序讓資料庫更加標準化,然後學習一下它的形態。

  1. X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = → load_dataset()
  2. # Normalize image vectors
  3. X_train = X_train_orig/255.
  4. X_test = X_test_orig/255.
  5. # Reshape
  6. Y_train = Y_train_orig.T
  7. Y_test = Y_test_orig.T
  8. print ("number of training examples = " + str(X_train.shape[0])) print ("number of test examples = " + str(X_test.shape[0])) print ("X_train shape: " + str(X_train.shape))
  9. print ("Y_train shape: " + str(Y_train.shape))
  10. print ("X_test shape: " + str(X_test.shape)) print ("Y_test shape: " + str(Y_test.shape))
  11. #output
  12. number of training examples = 600
  13. number of test examples = 150
  14. X_train shape: (600, 64, 64, 3)
  15. Y_train shape: (600, 1)
  16. X_test shape: (150, 64, 64, 3)
  17. Y_test shape: (150, 1)

幸福家資料庫的細節:

  • 圖片數據大小為 (64, 64, 3)
  • 訓練數據:600
  • 測試數據:150

現在去解決「快樂」挑戰吧!

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 的筆記中,我們可以運行以下命令下載模型及參數;

  1. model = load_vgg_model("pretrained-model/imagenet-vgg-verydeep-19.mat")
  2. print(model)

然後使用 assign 方法將圖像作為模型的輸入:

  1. model["input"].assign(image)

隨後,我們就能使用以下代碼獲取特定層級的激活值;

  1. sess.run(model["conv4_2"])

在神經風格遷移中,重點是以下三個步驟:

  • 構建需要遷移風格的圖片損失函數 J_content(C, G)
  • 構建風格損失函數 J_style(S, G)
  • 將它們組合為最終的損失函數 J(G) =α J_content(C, G) +β J_style(S, G)

使用這樣的損失函數,最終我們能以遷移學習的方法實現神經風格遷移。

本文為機器之心整理,轉載請聯繫原作者獲得授權。返回搜狐,查看更多

責任編輯:

相關焦點

  • 吳恩達deeplearning.ai五項課程完整筆記了解一下?
    自吳恩達發布 deeplearning.ai 課程以來,很多學習者陸續完成了所有專項課程並精心製作了課程筆記,在此過程中機器之心也一直在為讀者推薦優質的筆記。上個月,deep learning.ai 第五課發布,該系列課程最終結課。Mahmoud Badry 在 GitHub 上開源了五項課程的完整筆記,介紹了包括序列模型在內的詳細知識點。
  • 選機器學習課程怕踩雷?有人幫你選出了top 5優質課
    本文介紹了 top 5 機器學習課程:吳恩達《機器學習》課程:https://www.learndatasci.com/out/coursera-machine-learning/吳恩達《深度學習專項課程》:https://www.learndatasci.com/out/coursera-deep-learning-specialization/SAEED AGHABOZORGI
  • 深度學習自學指南:6個月,從基礎知識到模型構建
    當然,雖說的零基礎,但也有一個小門檻,你需要滿足以下條件:在接下來的6個月中,每天花費10-20小時學習已經具備一些編程技巧,懂一些Python和雲的基礎知識有一些數學基礎(代數、幾何等)有一臺計算機,並且能聯網量子位在這裡補充一句,想入門的小夥伴也可以現在開始準備英語了,畢竟……這些課程都是英文的。
  • 吳恩達悄然發布 AI 維基,另外他的技術崗已經招滿了-虎嗅網
    虎嗅註:似乎從百度離職之後,吳恩達回歸教育事業老本行,施展更加自如了。本文轉載自量子位,作者問耕。吳恩達又有新動作。wiki首先來說第一個。這個長假期間,吳恩達團隊在deeplearning.ai上悄然發布了一個新項目:AI維基百科。這個維基百科還向學習者們發出號召:一起來貢獻內容。目前這個維基有12個頁面,分別對應:歡迎、概述(神經網絡)、數學(導數、向量)、平臺和工具(Python、深度學習框架)、分類器、激活函數、超參數調整、代價函數等。
  • 吳恩達創業關你什麼事?
    來源:techcrunch.com作者:John Mannes譯者:劉小芹、張易【新智元導讀】百度前首席科學家吳恩達幾小時前剛剛在推特上宣布了他的下一個企業 Deeplearning.ai,據 Techcrunch 的 John Mannes 分析,Deeplearning.ai 應該是致力於開發 AI 基礎設施相關技術的公司
  • 這套1600贊的NLP課程已開放,面向實戰,視頻代碼都有丨資源
    一套面向實戰、號稱「代碼優先」的NLP課程來了,名字為A Code-First Introduction to Natural Language Processing,fast.ai出品,全程免費學習。不到半天點讚超過1600,轉發近500。
  • 這些優質的 AI 資源絕對不要錯過
    Coursera部分課程資料是免費提供的,但若想獲得證書必須付款。當中最著名和最受推崇的課程之一就是吳恩達的斯坦福機器學習課程。其他的Coursera課程在7天免費試用之後會收取費用,你可以免費收看課程視頻等內容。在這些課程中,我推薦以下這幾個好評最多的課程。
  • 高效「煉丹」必備技能:一文實現深度學習數學原理入門,還有吳恩達...
    但是,如果只做代碼「搬運工」,不了解神經網絡背後的數學原理,很難對項目有深刻全面的理解,debug反而會更難、耗時更長。下面的深度學習數學基礎詳解,以DLP為例,你讀完後會對它的數學基礎有全面的了解,並且熟悉用數學解釋算法的基本思路。除了DLP,文末還一併為你準備了RNN、CNN數學原理,以及吳恩達老師的AI數學基礎課程。一文實現AI數學基礎入門,還在等什麼?
  • 深度學習筆記8:利用Tensorflow搭建神經網絡
    個人公眾號:數據科學家養成記 (微信ID:louwill12)前文傳送門:深度學習筆記1:利用numpy從零搭建一個神經網絡深度學習筆記2:手寫一個單隱層的神經網絡深度學習筆記3:手動搭建深度神經網絡(DNN)深度學習筆記4:深度神經網絡的正則化深度學習筆記5:正則化與dr
  • ​大牛的《深度學習》筆記,Deep Learning速成教程
    聽起來感覺deeplearning很牛那樣。那什麼是deep learning?為什麼有deep learning?它是怎麼來的?又能幹什麼呢?目前存在哪些困難呢?這些問題的簡答都需要慢慢來。咱們先來了解下機器學習(人工智慧的核心)的背景。
  • 我在Google用AI研究基因,入門從吳恩達的課程開始
    於是在Google員工的推薦下,我把Coursera上吳恩達(Andrew Ng)的機器學習課程學習了一遍,有了不少入門知識和樂趣,如果現在讓我推薦入門課程,我想沒有比吳恩達的課程更好的了。其後,有了基礎知識和樂趣,我又開始學習MIT的機器學習課程,並閱讀基因組研究和深度學習結合的相關論文,這促使我進一步對想做的事情有了更深入的認知,並最終讓我在研究院畢業後能夠進入Google AI入駐計劃。
  • 吳恩達授課,斯坦福CS230深度學習課程資源開放
    機器之心整理參與:劉曉坤、雪、思源近日由吳恩達與 Kian Katanforoosh 指導的 CS230(深度學習)課程已經結束並放出了課程資料。這一門課程結合 Coursera 課外教學與課內教學展示了深度學習的基本概念與完整結構,機器之心簡要介紹了該課程及基本內容。
  • 1700頁數學筆記火了!全程敲代碼,速度飛快,硬核小哥教你上手
    數學課上,全程鍵盤手打1700頁筆記。速度緊追老師板書,公式、圖形一個不落。效果?請看下圖:不僅排版媲美教科書,而且還能夠批註,檢索關鍵詞……筆記被他Po到網上之後,便引來大量圍觀。不到一天,相關推文就已經有2000多贊,Hacker News論壇上蓋了200多樓。
  • 康奈爾法、思維導圖法等做筆記,提高做筆記效率!看完還想再寫三頁
    ——地科王若琦古代漢語古代漢語是一門艱深又有趣的課程。如果學的是文選,我會在課前儘量隔行抄好課文,再聽製作精良的慕課對照課本的注釋記筆記,上課的內容最後補充進去,課後讀一讀。用iPad記筆記的好處是,不用買彩筆也不用擔心寫錯字,有些形象的古漢字圖片可以直接截圖放到筆記中。
  • 吳恩達導師Michael I. Jordan剛去清華講了三天課,這有課程筆記
    Jordan教授課堂風格大數據文摘聯合清華數據派(ID:datapi)收集到了現場珍貴的乾貨筆記,珍貴筆記,請戳連結保存喔!連結: https://pan.baidu.com/s/1qYuQ4pA 密碼: iwfm 下載Michael本次系列講座筆記完整版。
  • 這是23門全世界最好的計算機科學課程
    評價:★★★★★課程連結:https://www.coursera.org/learn/interactive-python-12、零基礎程序設計(Python 入門)來自密西根大學,Coursera本課程旨在教大家使用 Python 編寫電腦程式的基礎知識。將介紹如何根據Python 中的一系列簡單指令開發程序的基礎知識。
  • 500頁內容帶你上手最流行框架
    書籍地址:https://pytorch.org/assets/deep-learning/Deep-Learning-with-PyTorch.pdfPyTorch 是當前最熱的深度學習框架之一。自 2016 年誕生以來,PyTorch 迅速發展,成為廣受開發者和研究人員喜愛的框架。