神經網絡中的損失函數正則化和 Dropout 並手寫代碼實現

2020-12-11 deephub

在深度神經網絡中最常用的方法是Regularization和dropout。 在本文中,我們將一起理解這兩種方法並在python中實現它們

Regularization 正則化

正則化通過在損失函數的末尾添加額外的懲罰項來幫助防止模型過度擬合。

其中m是批次大小。 所示的正則化稱為L2正則化,而L2對權重應用平方,而L1正則化則採用絕對值,其形式為| W |。

當權重過多或權重太大時,附加的額外項會增加損失,並且可調整因子λ著重說明了我們要對權重進行多少懲罰。

為什麼添加懲罰會有助於防止過度擬合?

直觀的理解是,在最小化新損失函數的過程中,某些權重將減小至接近零,因此相應的神經元將對我們的結果產生非常小的影響,就好像我們正在使用 更少的神經元。

前向傳播:在前進過程中,我們只需更改損失函數。

def compute_loss(A, Y, parameters, reg=True, lambd=.2):""" With L2 regularization parameters: dict with 'W1', 'b1', 'W2', ... """ assert A.shape == Y.shape n_layer = len(parameters)//2 m = A.shape[1] s = np.dot(Y, np.log(A.T)) + np.dot(1-Y, np.log((1 - A).T)) loss = -s/m if reg: p = 0 for i in range(1, n_layer+1): p += np.sum(np.square(parameters['W'+str(i)])) loss += (1/m)*(lambd/2)*p return np.squeeze(loss)

反向傳播:L2正則化的反向傳播實際上是直接的,我們只需要添加L2項的梯度即可。

def backward(params, cache, X, Y, lambd=0.2):""" params: weight [W, b] cache: result [A, Z] Y: shape (1, m) """ grad = {} n_layers = int(len(params)/2) m = Y.shape[1] cache['A0'] = X for l in range(n_layers, 0, -1): A, A_prev, Z = cache['A' + str(l)], cache['A' + str(l-1)], cache['Z' + str(l)] W = params['W'+str(l)] if l == n_layers: dA = -np.divide(Y, A) + np.divide(1 - Y, 1 - A) if l == n_layers: dZ = np.multiply(dA, sigmoid_grad(A, Z)) else: dZ = np.multiply(dA, relu_grad(A, Z)) # with an extra gradient at the end, other terms would remain the same dW = np.dot(dZ, A_prev.T)/m + (lambd/m)*W db = np.sum(dZ, axis=1, keepdims=True)/m dA = np.dot(W.T, dZ) grad['dW'+str(l)] = dW grad['db'+str(l)] = db return grad

訓練過程:像往常一樣,我們在二元分類的情況下測試我們的模型,並比較有無正則化的模型。

沒有正則化的模型

有正則化的模型

實際上,當迭代次數增加時,該模型將繼續過擬合,從而導致除法運算出錯,造成這種問題的原因可能是在正向過程中,結果A太接近於0。

相反,具有正則化的模型不會過擬合。

Dropout

Dropout通過隨機關閉某些輸出單元來防止過度擬合。

在上述過程中,在每次迭代中,層[2]上的某些單元將被隨機關閉,這意味著在正向過程中將工作的神經元更少,因此簡化了神經網絡的整體結構。

同時,訓練後的模型將更加健壯,因為該模型不再可以依賴任何特定的神經元(因為在此過程中它們可能會被靜音),因此所有其他神經元都需要在訓練中學習。

前向傳播:你可以理解為Dropout是在前向傳播過程中增加了一層。

一般情況下,正向傳播方程如下:

其中g是激活函數。 現在,通過Dropout將一個額外的圖層應用於A ^ [l]。

添加了Dropout如下:

其中D是Dropout層。 Dropout層中的關鍵因素是keepprob參數,該參數指定保留每個單元的可能性。 假設keepprob = 0.8,我們將有80%的機會保持每個輸出單位不變,而有20%的機會將其設置為0。

該實現將為結果A添加一個額外的掩碼。假設我們有一個包含四個元素的輸出A ^ {[l]},如下所示,

我們希望在保持其餘部分不變的情況下使第三個單元關閉,我們需要的是形狀相同的矩陣,並按以下方式進行元素逐次乘法,

前向傳播:

def forward(X):# intermediate layer use relu as activation # last layer use sigmoid n_layers = int(len(params)/2) A = X cache = {} for i in range(1, n_layers): W, b = params['W'+str(i)], params['b'+str(i)] Z = np.dot(W, A) + b A = relu(Z) # dropout keep_prob = keep_probs[i-1] D = np.random.rand(A.shape[0], A.shape[1]) D = (D < keep_prob).astype(int) A = np.multiply(D, A) # rescale A = A/keep_prob cache['Z'+str(i)] = Z cache['A'+str(i)] = A cache['D'+str(i)] = D # last layer W, b = params['W'+str(i+1)], params['b'+str(i+1)] Z = np.dot(W, A) + b A = sigmoid(Z) cache['Z'+str(i+1)] = Z cache['A'+str(i+1)] = A return cache, A

在這裡,我們將D初始化為與A相同的形狀,並根據keep_prob將其轉換為0和1矩陣。

請注意,dropout後,結果A需要重新縮放! 由於在此過程中某些神經元被靜音,因此需要增加左神經元以匹配預期值。

反向傳播:過程是將相同的函數D屏蔽為相應的dA。

# dummy code, full version needs to be inside a Classdef backward(self, cache, X, Y, keep_probs):""" cache: result [A, Z] Y: shape (1, m) """ grad = {} n_layers = int(len(self.params)/2) m = Y.shape[1] cache['A0'] = X for l in range(n_layers, 0, -1): A, A_prev, Z = cache['A' + str(l)], cache['A' + str(l-1)], cache['Z' + str(l)] W = self.params['W'+str(l)] if l == n_layers: dA = -np.divide(Y, A) + np.divide(1 - Y, 1 - A) if l == n_layers: dZ = np.multiply(dA, self.sigmoid_grad(A, Z)) else: # dropout version D = cache['D' + str(l)] dA = np.multiply(dA, D) # rescale dA = dA/keep_probs[l-1] dZ = np.multiply(dA, self.relu_grad(A, Z)) dW = np.dot(dZ, A_prev.T)/m db = np.sum(dZ, axis=1, keepdims=True)/m dA = np.dot(W.T, dZ) grad['dW'+str(l)] = dW grad['db'+str(l)] = db return grad

反向傳播方程式與一般的神經網絡網絡中引入的方程式相同。 唯一的區別在於矩陣D。 除最後一層外,所有其他具有丟失的層將對dA施加相應的蒙版D。

注意,在反向傳播中,dA也需要重新縮放。

結論

正則化和dropout都被廣泛採用以防止過度擬合,正則化通過在損失函數的末尾添加一個額外的懲罰項來實現,並通過在正向過程中隨機地使某些神經元靜音來使其退出以使網絡更加簡潔來實現正則化。

最後所有的代碼都可以在這裡找到:github/MJeremy2017/deep-learning/tree/main/regularization

作者:Jeremy Zhang

deephub翻譯組

相關焦點

  • 神經網絡的正則化(代碼篇)
    對於深度學習而言,這樣的數據量和特徵都少得可憐,用一個簡單的神經網絡可能就會發生過擬合,這正是我們需要的。我們首先嘗試常見的正則化手段,在keras中,添加懲罰項的方法非常簡單,它直接添加在層裡面,表示這一層的權重矩陣,偏置,激活函數的閾值這三類參數構成的懲罰項均可以被添加到損失函數中,而其他沒有設置正則化的層的參數不是添加到損失函數中。
  • 深度學習筆記5:正則化與dropout
    在筆記 4 中,詳細闡述了機器學習中利用正則化防止過擬合的基本方法,對 L1 和 L2 範數進行了通俗的解釋。為了防止深度神經網絡出現過擬合,除了給損失函數加上 L2 正則化項之外,還有一個很著名的方法——dropout.       廢話少說,咱們單刀直入正題。究竟啥是 dropout ?
  • TensorFlow(Keras)中的正則化技術及其實現(附代碼)
    該損失函數是一種方法,量化「 如何 」機器學習模型執行。量化是基於一組輸入的輸出(成本),這些輸入稱為參數值。參數值用於估計預測,「損失」是預測與實際值之間的差。本文將不關注正則化的數學。相反,本文介紹了一些標準的正則化方法以及如何使用TensorFlow(Keras)在神經網絡中實現它們。
  • 理解神經網絡中的Dropout
    dropout是指在深度學習網絡的訓練過程中,對於神經網絡單元,按照一定的概率將其暫時從網絡中丟棄。注意是暫時,對於隨機梯度下降來說,由於是隨機丟棄,故而每一個mini-batch都在訓練不同的網絡。
  • 在TensorFlow(Keras)中了解和實現Dropout
    在本文中,我們將探討Dropout的概念,並了解如何使用TensorFlow和Keras在神經網絡中實現該技術。簡單神經網絡一般的觀點是,神經網絡體系結構中的神經元和層越多,其表示能力就越強。表示能力的提高意味著神經網絡可以擬合更複雜的函數,並可以更好地泛化到訓練數據。
  • 驚為天人,NumPy手寫全部主流機器學習模型,代碼超3萬行
    平均每個模型的代碼行數在 500 行以上,在神經網絡模型的 layer.py 文件中,代碼行數接近 4000。這,應該是目前用 NumPy 手寫機器學習模型的「最高境界」吧。在每一個代碼集下,作者都會提供不同實現的參考資料,例如模型的效果示例圖、參考論文和參考連結等。如下所示,David 在實現神經網絡層級的過程中,還提供了參考論文。當然如此龐大的代碼總會存在一些 Bug,作者也非常希望我們能一起完善這些實現。
  • 深度學習筆記4:深度神經網絡的正則化
    如何我們在正則化過程中選擇了 L0 範數,那該如何理解這個 L0 呢?其實非常簡單,L0 範數就是希望要正則化的參數矩陣 W 大多數元素都為 0。如此簡單粗暴,讓參數矩陣 W 大多數元素為 0 就是實現稀疏而已。說到這裡,權且打住,想必同樣在機器學習領域摸爬滾打的你一定想問,據我所知稀疏性不通常都是用 L1 來實現的嗎?
  • 深度學習中Dropout原理解析
    Dropout簡介1.1 Dropout出現的原因在機器學習的模型中,如果模型的參數太多,而訓練樣本又太少,訓練出來的模型很容易產生過擬合的現象。在訓練神經網絡的時候經常會遇到過擬合的問題,過擬合具體表現在:模型在訓練數據上損失函數較小,預測準確率較高;但是在測試數據上損失函數比較大,預測準確率較低。過擬合是很多機器學習的通病。如果模型過擬合,那麼得到的模型幾乎不能用。
  • 李理:卷積神經網絡之Dropout
    上圖a是標準的一個全連接的神經網絡,b是對a應用了dropout的結果,它會以一定的概率(dropout probability)隨機的丟棄掉一些神經元。因此越大,U1中1越多,也就keep的越多,反之則dropout的越多。然後我們用U1乘以H1,這樣U1中等於0的神經元的激活就是0,其餘的仍然是H1。第二層也是一樣的道理。predict函數我們需要注意一下。
  • 筆記(乾貨):dropout原理總結
    在說這個之前,我們不得不說先說一下正則化,畢竟要說明白一件事,還是要有頭有尾,不至於讓看筆記的人,看到莫名其妙。在dropout提出之前,學院派和工業屆在深度學習消除過擬合的研究方向(領域)是--正則化。 最早是在2000年初,開始被引入,然後在神經網絡中被廣泛使用。eg:L1,L2,Ln正則化。
  • 超參數調試、Batch正則化和程序框架——吳恩達DeepLearning.ai深度學習筆記之改善深層神經網絡(三)
    ,不利於訓練非線性神經網絡,從而得到效果較差的模型。類似於 dropout,這種噪聲會使得神經元不會再特別依賴於任何一個輸入特徵。因為 Batch Normalization 只有微弱的正則化效果,因此可以和 dropout 一起使用,以獲得更強大的正則化效果。通過應用更大的 mini-batch 大小,可以減少噪聲,從而減少這種正則化效果。
  • TF2.0-五種優化器,激活函數(sigmoid,tanh,relu,leaky relu的優缺點),損失函數,正則化等
    >    主要關於正則化L1和L2正則化,含實現Ⅵ.五種優化器(用來更新權重)的計算方式和實現    模型優化算法的選擇直接關係到最終模型的性能     SGD【最常用】,SGDM,Adagrad,RMSProp,Adam   【文中圖因尺寸較大,放大可能不清晰,點擊原文連結獲取腦圖和代碼(含注釋),本文的代碼較多,文章內不附代碼,針對iris數據集,手動實現五種優化器,手動構建神經網絡加入激活函數】我們構建神經網絡模型的時候
  • CS231N 06: 神經網絡、損失函數
    神經網絡在實踐中之所效果很好,是因為它們表達出的函數不僅平滑,而且對於數據的統計特性有很好的擬合。同時,網絡通過最優化算法(例如梯度下降)能比較容易地學習到這個函數。雖然理論上深層網絡(多個隱層)和單層網絡的表達能力是一樣的,但實踐中深度網絡效果比單層網絡好。在實踐中,三層神經網絡通常會勝過兩層網絡,然而繼續加深(4,5,6層)則很少有太大幫助。
  • 神經網絡中的各種損失函數介紹
    不同的損失函數可用於不同的目標。在這篇文章中,我將帶你通過一些示例介紹一些非常常用的損失函數。這篇文章提到的一些參數細節都屬於tensorflow或者keras的實現細節。損失函數的簡要介紹損失函數有助於優化神經網絡的參數。
  • CS231N 07: 數據處理、權重初始化、正則化
    Setting up the data and the model上一節介紹了神經元模型和神經網絡模型,神經元模型根據非線性計算點積,而神經網絡將神經元排列成層。這些選擇共同定義了得分函數的新形式,這是我們從「線性分類」部分中看到的簡單線性映射擴展而來的。特別地,神經網絡執行具有交織非線性的一系列線性映射。
  • 入門| Tensorflow實戰講解神經網絡搭建詳細過程
    【IT168 技術】之前我們講了神經網絡的起源、單層神經網絡、多層神經網絡的搭建過程、搭建時要注意到的具體問題、以及解決這些問題的具體方法。本文將通過一個經典的案例:MNIST手寫數字識別,以代碼的形式來為大家梳理一遍神經網絡的整個過程。
  • 深度學習筆記13:Tensorflow實戰之手寫mnist手寫數字識別
    作者:魯偉一個數據科學踐行者的學習日記。
  • 深度學習(二十二)Dropout淺層理解與實現
    Network In Network》的,結果發現maxout和dropout有點類似,所以就對dropout做一下相關的總結,了解一下其代碼層面的實現。當時要麼就是模仿別人,要麼就是直接用別人的網絡,被領導鄙視了一番……還是不囉嗦了,說多了都是淚。    網上都說dropout是讓某些神經元以一定的概率不工作,但是具體代碼怎麼實現?
  • CS231N 02: 損失函數和正則化
    在這些方法中,零均值居中(zero mean centering)是比較重要的,但要等到理解梯度下降後再來說明它的合理性。3. Loss function在上一節中,我們定義了一個從像素值到分類分數的函數,這個函數的參數是由一組權重 W 確定的,數據 (xi,yi) 是固定的,但是我們可以控制這些權重,使預測的分類分數與訓練數據中的真實標籤一致。
  • 深度學習三人行(第10期)----CNN經典網絡之LeNet-5和AlexNet
    上一期,我們一起學習了深度學習卷積神經網絡中的代碼實現,內存計算以及池化層的原理等,深度學習三人行(第9期)----卷積神經網絡實戰進階