在深度神經(jīng)網(wǎng)絡(luò)中最常用的方法是Regularization和dropout。 在本文中,我們將一起理解這兩種方法并在python中實(shí)現(xiàn)它們 Regularization 正則化正則化通過在損失函數(shù)的末尾添加額外的懲罰項(xiàng)來幫助防止模型過度擬合。 其中m是批次大小。 所示的正則化稱為L2正則化,而L2對(duì)權(quán)重應(yīng)用平方,而L1正則化則采用絕對(duì)值,其形式為| W |。 當(dāng)權(quán)重過多或權(quán)重太大時(shí),附加的額外項(xiàng)會(huì)增加損失,并且可調(diào)整因子λ著重說明了我們要對(duì)權(quán)重進(jìn)行多少懲罰。 為什么添加懲罰會(huì)有助于防止過度擬合? 直觀的理解是,在最小化新?lián)p失函數(shù)的過程中,某些權(quán)重將減小至接近零,因此相應(yīng)的神經(jīng)元將對(duì)我們的結(jié)果產(chǎn)生非常小的影響,就好像我們正在使用 更少的神經(jīng)元。 前向傳播:在前進(jìn)過程中,我們只需更改損失函數(shù)。 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正則化的反向傳播實(shí)際上是直接的,我們只需要添加L2項(xiàng)的梯度即可。
訓(xùn)練過程:像往常一樣,我們?cè)诙诸惖那闆r下測(cè)試我們的模型,并比較有無正則化的模型。 沒有正則化的模型 有正則化的模型 實(shí)際上,當(dāng)?shù)螖?shù)增加時(shí),該模型將繼續(xù)過擬合,從而導(dǎo)致除法運(yùn)算出錯(cuò),造成這種問題的原因可能是在正向過程中,結(jié)果A太接近于0。 相反,具有正則化的模型不會(huì)過擬合。 DropoutDropout通過隨機(jī)關(guān)閉某些輸出單元來防止過度擬合。 在上述過程中,在每次迭代中,層[2]上的某些單元將被隨機(jī)關(guān)閉,這意味著在正向過程中將工作的神經(jīng)元更少,因此簡化了神經(jīng)網(wǎng)絡(luò)的整體結(jié)構(gòu)。 同時(shí),訓(xùn)練后的模型將更加健壯,因?yàn)樵撃P筒辉倏梢砸蕾嚾魏翁囟ǖ纳窠?jīng)元(因?yàn)樵诖诉^程中它們可能會(huì)被靜音),因此所有其他神經(jīng)元都需要在訓(xùn)練中學(xué)習(xí)。 前向傳播:你可以理解為Dropout是在前向傳播過程中增加了一層。 一般情況下,正向傳播方程如下: 其中g(shù)是激活函數(shù)。 現(xiàn)在,通過Dropout將一個(gè)額外的圖層應(yīng)用于A ^ [l]。 添加了Dropout如下: 其中D是Dropout層。 Dropout層中的關(guān)鍵因素是keepprob參數(shù),該參數(shù)指定保留每個(gè)單元的可能性。 假設(shè)keepprob = 0.8,我們將有80%的機(jī)會(huì)保持每個(gè)輸出單位不變,而有20%的機(jī)會(huì)將其設(shè)置為0。 該實(shí)現(xiàn)將為結(jié)果A添加一個(gè)額外的掩碼。假設(shè)我們有一個(gè)包含四個(gè)元素的輸出A ^ {[l]},如下所示, 我們希望在保持其余部分不變的情況下使第三個(gè)單元關(guān)閉,我們需要的是形狀相同的矩陣,并按以下方式進(jìn)行元素逐次乘法, 前向傳播: 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相同的形狀,并根據(jù)keep_prob將其轉(zhuǎn)換為0和1矩陣。 請(qǐng)注意,dropout后,結(jié)果A需要重新縮放! 由于在此過程中某些神經(jīng)元被靜音,因此需要增加左神經(jīng)元以匹配預(yù)期值。 反向傳播:過程是將相同的函數(shù)D屏蔽為相應(yīng)的dA。
反向傳播方程式與一般的神經(jīng)網(wǎng)絡(luò)網(wǎng)絡(luò)中引入的方程式相同。 唯一的區(qū)別在于矩陣D。 除最后一層外,所有其他具有丟失的層將對(duì)dA施加相應(yīng)的蒙版D。 注意,在反向傳播中,dA也需要重新縮放。 結(jié)論正則化和dropout都被廣泛采用以防止過度擬合,正則化通過在損失函數(shù)的末尾添加一個(gè)額外的懲罰項(xiàng)來實(shí)現(xiàn),并通過在正向過程中隨機(jī)地使某些神經(jīng)元靜音來使其退出以使網(wǎng)絡(luò)更加簡潔來實(shí)現(xiàn)正則化。 最后所有的代碼都可以在這里找到:https://github.com/MJeremy2017/deep-learning/tree/main/regularization |
|