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

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

在這份筆記中,Wan Zhen 不只介紹了每一個課程的關鍵知識點,同時還詳細解釋了各課程的編程做業。在第一門課程《神經網絡與深度學習基礎》中,該課程筆記不只提供了最基礎的 Python 和 NumPy 操做筆記,同時還從最基礎的 Logistic 迴歸推導到最通常的深度全鏈接網絡。固然,還介紹了必要的損失函數與反向傳播方法。而在第二門課程中,該筆記詳細記錄了提高深度網絡性能所須要的技巧與基礎,例如初始化、正則化和梯度檢驗等在實踐上大大提高模型性能的方法,以及通常 SGD、動量法和適應性學習率方法等常見的最優化方法。最後,第二門課程重點介紹了 TensorFlow,包括該框架的經常使用函數和實際構建網絡的過程等。最後一章節主要記錄了卷積神經網絡,包括基本的卷積運算、殘差網絡和目標檢測框架等。python

如下是該課程筆記的簡要框架與一些詳細的知識點。算法


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 迴歸神經網絡的完整代碼。bash

其中 1.2.4 介紹的構建算法的基本步驟爲:網絡

  • 定義模型結構;session

  • 初始化模型參數;架構

  • 循環迭代結構:

  • 計算當前損失函數值(前向傳播)

  • 計算當前梯度值(反向傳播)

  • 更新參數(梯度降低)

一般 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 初始化,這一部分是課程做業的答案:

# GRADED FUNCTION: initialize_parameters_he
def initialize_parameters_he(layers_dims):
""" Arguments: layer_dims -- python array (list) containing the size of each ,→ layer. Returns: parameters -- python dictionary containing your parameters "W1", ,→ "b1", ..., "WL", "bL": W1 -- weight matrix of shape (layers_dims[1], ,→ layers_dims[0]) b1 -- bias vector of shape (layers_dims[1], 1) ... WL -- weight matrix of shape (layers_dims[L], ,→ layers_dims[L-1]) bL -- bias vector of shape (layers_dims[L], 1) """
np.random.seed(3)
parameters = {}
L = len(layers_dims) - 1 # integer representing the number of
,→ layers
for l in range(1, L + 1):
### START CODE HERE ### (
2 lines of code)
parameters['W' + str(l)] = np.random.randn(layers_dims[l],
,→ layers_dims[l-1]) * np.sqrt(2./layers_dims[l-1])
parameters['b' + str(l)] = np.zeros((layers_dims[l], 1))
### END CODE HERE ###
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 控制了這些移動均值的衰減率。

移動均值的初始值和 beta一、beta2 值接近於 1(推薦值),所以矩估計的誤差接近於 0。該誤差經過首先計算帶誤差的估計然後計算誤差修正後的估計而獲得提高。

正如該筆記所總結的,Adam 的計算更新過程可分爲三部分:

1. 計算曆史梯度的指數加權平均值,並將它儲存在變量 v 中(有偏估計),而後再計算 v^corrected(修正後得出的無偏估計)。

2. 計算曆史梯度平方的指數加權平均值,並將它儲存爲變量 s(有偏估計),而後計算 s^corrected(修正的無偏估計)。

3. 而後結合前兩步的信息更新參數。

這一更新過程如筆記所述可表示爲:

其中 t 會計算 Adam 所迭代更新的次數、L 爲層級數、β_1 和β_1 爲控制指數加權平均值得超參數、α 爲學習率,而 ε 爲避免分母爲零的小常數。

Wan Zhen 一樣給出了 Adam 的實現代碼或做業解讀:

# GRADED FUNCTION: initialize_adam
def initialize_adam(parameters) :
""" Initializes v and s as two python dictionaries with: - keys: "dW1", "db1", ..., "dWL", "dbL" - values: numpy arrays of zeros of the same shape as ,→ the corresponding gradients/parameters. Arguments: parameters -- python dictionary containing your parameters. parameters["W" + str(l)] = Wl parameters["b" + str(l)] = bl Returns: v -- python dictionary that will contain the exponentially weighted ,→ average of the gradient. v["dW" + str(l)] = ... v["db" + str(l)] = ... s -- python dictionary that will contain the exponentially weighted ,→ average of the squared gradient. s["dW" + str(l)] = ... s["db" + str(l)] = ... """
L = len(parameters) // 2 # number of layers in the neural networks
v = {}
s = {}
# Initialize v, s. Input: "parameters". Outputs: "v, s".
for l in range(L):
### START CODE HERE ### (approx. 4 lines)
v["dW" + str(l+1)] = np.zeros(parameters["W" + str(l+1)].shape)
v["db" + str(l+1)] = np.zeros(parameters["b" + str(l+1)].shape)
s["dW" + str(l+1)] = np.zeros(parameters["W" + str(l+1)].shape)
s["db" + str(l+1)] = np.zeros(parameters["b" + str(l+1)].shape)
### END CODE HERE ###
return v, s
複製代碼

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

# GRADED FUNCTION: update_parameters_with_adam
def update_parameters_with_adam(parameters, grads, v, s, t, learning_rate = 0.01, beta1 = 0.9, beta2 = 0.999, epsilon = 1e-8):

L = len(parameters) // 2 # number of layers in the neural networks
v_corrected = {} # Initializing first moment estimate, python, dictionary

s_corrected = {} # Initializing second moment estimate, python
,→ dictionary
# Perform Adam update on all parameters
for l in range(L):
# Moving average of the gradients. Inputs: "v, grads, beta1".
,→ Output: "v".
v["dW" + str(l+1)] = beta1*v["dW" +
,→ str(l+1)]+(1-beta1)*grads['dW' + str(l+1)]
v["db" + str(l+1)] = beta1*v["db" + str(l+1)]+(1-beta1)*grads['db' + str(l+1)]
# Compute bias-corrected first moment estimate. Inputs: "v, beta1, t". Output: "v_corrected".
v_corrected["dW" + str(l+1)] = v["dW" + str(l+1)]/(1-math.pow(beta1,t))
v_corrected["db" + str(l+1)] = v["db" + str(l+1)]/(1-math.pow(beta1,t))
# Moving average of the squared gradients. Inputs: "s, grads, beta2". Output: "s".
s["dW" + str(l+1)] = beta2*s["dW" + str(l+1)]+(1-beta2)*(grads['dW' + str(l+1)]**2)
s["db" + str(l+1)] = beta2*s["db" + str(l+1)]+(1-beta2)*(grads['db' + str(l+1)]**2)
# Compute bias-corrected second raw moment estimate. Inputs: "s, beta2, t". Output: "s_corrected".
s_corrected["dW" + str(l+1)] = s["dW" + str(l+1)]/(1-math.pow(beta2,t))
s_corrected["db" + str(l+1)] = s["db" + str(l+1)]/(1-math.pow(beta2,t))
# Update parameters. Inputs: "parameters, learning_rate, v_corrected, s_corrected, epsilon". Output: "parameters".
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)
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)

return parameters, v, s
複製代碼

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


TensorFlow

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

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

### START CODE HERE ### (approx. 2 lines)
X = tf.placeholder(tf.float32, [n_x, None], name = 'X')
Y = tf.placeholder(tf.float32, [n_y, None], name = 'Y')
### END CODE HERE ###
return X, Y


return parameters, v, s

複製代碼

定義變量和常量的方法:

a = tf.constant(2, tf.int16)
b = tf.constant(4, tf.float32)
g = tf.constant(np.zeros(shape=(2,2), dtype=np.float32))

d = tf.Variable(2, tf.int16)
e = tf.Variable(4, tf.float32)

h = tf.zeros([11], tf.int16)
i = tf.ones([2,2], tf.float32)

k = tf.Variable(tf.zeros([2,2], tf.float32))
l = tf.Variable(tf.zeros([5,6,5], tf.float32))


return parameters, v, s
複製代碼

初始化參數的方法:

W1 = tf.get_variable("W1", [25,12288], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
b1 = tf.get_variable("b1", [25,1], initializer = tf.zeros_initializer())


return parameters, v, s
複製代碼

運行計算圖:

a = tf.constant(2, tf.int16)
b = tf.constant(4, tf.float32)

graph = tf.Graph()
with graph.as_default():
a = tf.Variable(8, tf.float32)
b = tf.Variable(tf.zeros([2,2], tf.float32))

with tf.Session(graph=graph) as session:
tf.global_variables_initializer().run()
print(f)
print(session.run(a))
print(session.run(b))

#輸出:

>>> <tf.Variable 'Variable_2:0' shape=() dtype=int32_ref>
>>> 8
>>> [[ 0. 0.]
>>> [ 0. 0.]]


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() 函數

代碼:

# GRADED FUNCTION: conv_single_step
def conv_single_step(a_slice_prev, W, b): """ Apply one filter defined by parameters W on a single slice → (a_slice_prev)oftheoutputactivation of the previous layer. Arguments: a_slice_prev -- slice of input data of shape (f, f, n_C_prev) W -- Weight parameters contained in a window - matrix of shape (f, → f,n_C_prev) b -- Bias parameters contained in a window - matrix of shape (1, 1, → 1) Returns: Z -- a scalar value, result of convolving the sliding window (W, b) → onaslicexoftheinputdata """
### START CODE HERE ### ( 2 lines of code)
# Element-wise product between a_slice and W. Add bias. s = a_slice_prev * W + b
# Sum over all entries of the volume s
Z = np.sum(s)
### END CODE HERE ###
return Z


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 用:

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

More Info. 更多的信息:

More Info.更多的信息:
# GRADED FUNCTION: initialize_parameters
def initialize_parameters(): """ Initializes weight parameters to build a neural network with → tensorflow.Theshapesare: W1 : [4, 4, 3, 8] W2 : [2, 2, 8, 16] Returns: parameters -- a dictionary of tensors containing W1, W2 """
tf.set_random_seed(1) # so that your → "random"numbersmatchours
   ### START CODE HERE ### (approx. 2 lines of code)
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))
   ### END CODE HERE ###
   parameters = {"W1": W1,
                 "W2": W2}
return parameters
複製代碼

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

這一部分講了一個做業(幸福家),怎樣用 Keras 建模型、總結、用本身的圖片去測試其餘很是有用的 Keras 函數。在這裏咱們着重講一下幸福家是什麼:


3.3.1 幸福家

下一次放假旅行,你決定和你的 5 個在學校認識的朋友一塊兒度過一週。這附近有一個很是方便的房子能夠作不少事情。但最重要的福利是在房子裏的時候每一個人都必需要快樂。因此每一個想進房間的人都要提供他們如今的幸福情形。

做爲一個深度學習專家,要確保「開心」這一規則被堅定的執行了,你要去建一個算法來經過前門的攝像頭獲得的照片來檢查這我的是否是開心。

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

跑一下下面的程序讓數據庫更加標準化,而後學習一下它的形態。

X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = → load_dataset()
# Normalize image vectors
X_train = X_train_orig/255.
X_test = X_test_orig/255.
# Reshape
Y_train = Y_train_orig.T
Y_test = Y_test_orig.T
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))
print ("Y_train shape: " + str(Y_train.shape))
print ("X_test shape: " + str(X_test.shape)) print ("Y_test shape: " + str(Y_test.shape))
#output
number of training examples = 600
number of test examples = 150
X_train shape: (600, 64, 64, 3)
Y_train shape: (600, 1)
X_test shape: (150, 64, 64, 3)
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 的筆記中,咱們能夠運行如下命令下載模型及參數;

model = load_vgg_model("pretrained-model/imagenet-vgg-verydeep-19.mat")
print(model)複製代碼

而後使用 assign 方法將圖像做爲模型的輸入:

model["input"].assign(image)複製代碼

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

sess.run(model["conv4_2"])複製代碼

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

  • 構建須要遷移風格的圖片損失函數 J_content(C, G)

  • 構建風格損失函數 J_style(S, G)

  • 將它們組合爲最終的損失函數 J(G) =α J_content(C, G) +β J_style(S, G)

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

相關文章
相關標籤/搜索