利用Keras中的權重約束減少深度神經網絡中的過擬合

2020-12-11 TechWeb

權重約束提供了一種方法,用於減少深度學習神經網絡模型對訓練數據的過度擬合,並改善模型對新數據(例如測試集)的性能。有多種類型的權重約束,例如最大和單位向量規範,有些需要必須配置的超參數。

在本教程中,您將發現Keras API,用於向深度學習神經網絡模型添加權重約束以減少過度擬合。

完成本教程後,您將了解:

 如何使用Keras API創建向量範數約束。  如何使用Keras API為MLP,CNN和RNN層添加權重約束。  如何通過向現有模型添加權重約束來減少過度擬合。

教程概述

本教程分為三個部分,他們是:

 Keras的重量約束  圖層上的權重約束  體重約束案例研究

Keras的重量約束

Keras API支持權重限制。約束是按層指定的,但是在層中應用和強制執行每個節點。

使用約束通常涉及在圖層上為輸入權重設置kernel_constraint參數,並為偏差權重設置bias_constraint。

通常,權重約束不用於偏差權重。一組不同的向量規範可以用作約束,作為keras.constraints模塊中的類提供。他們是:

 最大範數(max_norm),用於強制權重等於或低於給定限制。  非負規範(non_neg),強制權重具有正數。  單位範數(unit_norm),強制權重為1.0。  Min-Max範數(min_max_norm),用於強制權重在一個範圍之間。

例如,一個簡單的約束可以這樣被引入和實例化:

# import norm  from keras.constraints import max_norm  # instantiate norm  norm = max_norm(3.0)  # import norm  from keras.constraints import max_norm  # instantiate norm  norm = max_norm(3.0) 

圖層上的權重約束

權重規範可用於Keras的大多數層。在本節中,我們將看一些常見的例子。

MLP加權約束

以下示例在密集完全連接層上設置最大範數權重約束。

# example of max norm on a dense layer  from keras.layers import Dense  from keras.constraints import max_norm  ...  model.add(Dense(32, kernel_constraint=max_norm(3), bias_constraint==max_norm(3)))  ...  # example of max norm on a dense layer  from keras.layers import Dense  from keras.constraints import max_norm  ...  model.add(Dense(32, kernel_constraint=max_norm(3), bias_constraint==max_norm(3)))  ... 

CNN加權約束

下面的示例在卷積層上設置最大範數權重約束。

# example of max norm on a cnn layer  from keras.layers import Conv2D  from keras.constraints import max_norm ...  model.add(Conv2D(32, (3,3), kernel_constraint=max_norm(3), bias_constraint==max_norm(3)))  ... 

RNN權重約束

與其他圖層類型不同,遞歸神經網絡允許您對輸入權重和偏差以及循環輸入權重設置權重約束。通過圖層的recurrent_constraint參數設置重複權重的約束。以下示例在LSTM圖層上設置最大範數權重約束。

# example of max norm on an lstm layer  from keras.layers import LSTM  from keras.constraints import max_norm  ...  model.add(LSTM(32, kernel_constraint=max_norm(3), recurrent_constraint=max_norm(3), bias_constraint==max_norm(3)))  ...  # example of max norm on an lstm layer  from keras.layers import LSTM  from keras.constraints import max_norm  ...  model.add(LSTM(32, kernel_constraint=max_norm(3), recurrent_constraint=max_norm(3), bias_constraint==max_norm(3)))  ... 

現在我們知道如何使用權重約束API,讓我們看一個有效的例子。

加權約束案例研究

在本節中,我們將演示如何使用權重約束來減少MLP對簡單二元分類問題的過度擬合。此示例提供了一個模板,用於將權重約束應用於您自己的神經網絡以進行分類和回歸問題。

二元分類問題

我們將使用標準二進位分類問題來定義兩個半圓數據集,每個類一個半圓。每個觀測值都有兩個輸入變量,它們具有相同的比例,類輸出值為0或1.該數據集稱為「月球」數據集,因為繪製時每個類中的觀測值的形狀。我們可以使用make_moons()函數從這個問題中生成觀察結果。我們將為數據添加噪聲並為隨機數生成器播種,以便每次運行代碼時生成相同的樣本。

# generate 2d classification dataset  X, y = make_moons(n_samples=100, noise=0.2, random_state=1) 

我們可以繪製兩個變量在圖表上作為x和y坐標的數據集,並將類值作為觀察的顏色。下面列出了生成數據集並繪製數據集的完整示例。

# generate two moons dataset  from sklearn.datasets import make_moons  from matplotlib import pyplot  from pandas import DataFrame  # generate 2d classification dataset  X, y = make_moons(n_samples=100, noise=0.2, random_state=1)  # scatter plot, dots colored by class value  df = DataFrame(dict(x=X[:,0], y=X[:,1], label=y))  colors = {0:'red', 1:'blue'}  fig, ax = pyplot.subplots() grouped = df.groupby('label')  for key, group in grouped:      group.plot(axax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key])  pyplot.show()  # generate two moons dataset  from sklearn.datasets import make_moons  from matplotlib import pyplot  from pandas import DataFrame  # generate 2d classification dataset  X, y = make_moons(n_samples=100, noise=0.2, random_state=1)  # scatter plot, dots colored by class value  df = DataFrame(dict(x=X[:,0], y=X[:,1], label=y))  colors = {0:'red', 1:'blue'}  fig, ax = pyplot.subplots()  grouped = df.groupby('label')  for key, group in grouped:      group.plot(axax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key])  pyplot.show() 

運行該示例會創建一個散點圖,顯示每個類中觀察的半圓形或月亮形狀。我們可以看到點的分散中的噪音使得衛星不太明顯。

這是一個很好的測試問題,因為類不能用一行來分隔,例如不是線性可分的,需要非線性方法,如神經網絡來解決。我們只生成了100個樣本,這對於神經網絡而言很小,提供了過度擬合訓練數據集的機會,並且在測試數據集上具有更高的誤差:使用正則化的一個好例子。此外,樣本具有噪聲,使模型有機會學習不一致的樣本的各個方面。

過度多層感知器

我們可以開發一個MLP模型來解決這個二進位分類問題。該模型將具有一個隱藏層,其具有比解決該問題所需的節點更多的節點,從而提供過度擬合的機會。我們還將訓練模型的時間超過確保模型過度所需的時間。在我們定義模型之前,我們將數據集拆分為訓練集和測試集,使用30個示例來訓練模型,使用70個示例來評估擬合模型的性能。

X, y = make_moons(n_samples=100, noise=0.2, random_state=1)  # split into train and test  n_train = 30  trainX, testX = X[:n_train, :], X[n_train:, :]  trainy, testy = y[:n_train], y[n_train:] 

接下來,我們可以定義模型。隱藏層使用隱藏層中的500個節點和整流的線性激活函數。在輸出層中使用S形激活函數以預測0或1的類值。該模型使用二元交叉熵損失函數進行優化,適用於二元分類問題和梯度下降的有效Adam版本。

# define model  model = Sequential()  model.add(Dense(500, input_dim=2, activation='relu'))  model.add(Dense(1, activation='sigmoid'))  model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) 

然後,定義的模型擬合4,000個訓練數據,默認批量大小為32。我們還將使用測試數據集作為驗證數據集。

# fit model  history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0) 

我們可以在測試數據集上評估模型的性能並報告結果。

# evaluate the model  _, train_acc = model.evaluate(trainX, trainy, verbose=0)  _, test_acc = model.evaluate(testX, testy, verbose=0)  print('Train: %.3f, Test: %.3f' % (train_acc, test_acc)) 

最後,我們將在每個時期的訓練集和測試集上繪製模型的性能。如果模型確實過度擬合訓練數據集,我們將期望訓練集上的準確度線圖繼續增加並且測試設置上升然後隨著模型在訓練數據集中學習統計噪聲而再次下降。

# plot history  pyplot.plot(history.history['acc'], label='train')  pyplot.plot(history.history['val_acc'], label='test')  pyplot.legend()  pyplot.show() 

我們可以將所有這些部分組合在一起; 下面列出了完整的示例。

# mlp overfit on the moons dataset  from sklearn.datasets import make_moons  from keras.layers import Dense  from keras.models import Sequential  from matplotlib import pyplot  # generate 2d classification dataset  X, y = make_moons(n_samples=100, noise=0.2, random_state=1)  # split into train and test  n_train = 30  trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:]  # define model  model = Sequential()  model.add(Dense(500, input_dim=2, activation='relu'))  model.add(Dense(1, activation='sigmoid'))  model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])  # fit model  history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)  # evaluate the model  _, train_acc = model.evaluate(trainX, trainy, verbose=0)  _, test_acc = model.evaluate(testX, testy, verbose=0)  print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))  # plot history  pyplot.plot(history.history['acc'], label='train')  pyplot.plot(history.history['val_acc'], label='test')  pyplot.legend()  pyplot.show() 

運行該示例報告列車和測試數據集上的模型性能。我們可以看到模型在訓練數據集上的性能優於測試數據集,這是過度擬合的一個可能標誌。鑑於神經網絡和訓練算法的隨機性,您的具體結果可能會有所不同。因為模型是過度擬合的,所以我們通常不會期望在相同數據集上重複運行模型的精度差異(如果有的話)。

Train: 1.000, Test: 0.914 

創建一個圖,顯示訓練集和測試集上模型精度的曲線圖。我們可以看到過度擬合模型的預期形狀,其中測試精度增加到一個點然後再次開始減小。

具有加權約束的Overfit MLP

我們可以更新示例以使用權重約束。有一些不同的加權限制可供選擇。這個模型的一個很好的簡單約束是簡單地標準化加權,使得範數等於1.0。此約束具有強制所有傳入權重較小的效果。我們可以通過在Keras中使用unit_norm來實現。可以將此約束添加到第一個隱藏層,如下所示:

model.add(Dense(500, input_dim=2, activation='relu', kernel_constraint=unit_norm())) 

我們也可以通過使用min_max_norm並將min和maximum設置為1.0來實現相同的結果,例如:

model.add(Dense(500, input_dim=2, activation='relu', kernel_constraint=min_max_norm(min_value=1.0, max_value=1.0))) 

我們無法通過最大範數約束獲得相同的結果,因為它允許規範等於或低於指定的限制; 例如:

model.add(Dense(500, input_dim=2, activation='relu', kernel_constraint=max_norm(1.0))) 

下面列出了具有單位規範約束的完整更新示例:

# mlp overfit on the moons dataset with a unit norm constraint  from sklearn.datasets import make_moons  from keras.layers import Dense  from keras.models import Sequential  from keras.constraints import unit_norm  from matplotlib import pyplot  # generate 2d classification dataset  X, y = make_moons(n_samples=100, noise=0.2, random_state=1)  # split into train and test  n_train = 30  trainX, testX = X[:n_train, :], X[n_train:, :]  trainy, testy = y[:n_train], y[n_train:]  # define model  model = Sequential()  model.add(Dense(500, input_dim=2, activation='relu', kernel_constraint=unit_norm()))  model.add(Dense(1, activation='sigmoid'))  model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])  # fit model  history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0)  # evaluate the model _, train_acc = model.evaluate(trainX, trainy, verbose=0)  _, test_acc = model.evaluate(testX, testy, verbose=0)  print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))  # plot history  pyplot.plot(history.history['acc'], label='train')  pyplot.plot(history.history['val_acc'], label='test')  pyplot.legend()  pyplot.show() 

運行該示例報告訓練集和測試數據集上的模型性能。我們可以看到,對權重大小的嚴格限制確實提高了模型在測試集上的性能,而不會影響訓練集的性能。

Train: 1.000, Test: 0.943 

回顧訓練集的曲線和測試精度,我們可以看到模型已經過度擬合訓練數據集了。訓練集和測試集的模型精度繼續提高到穩定水平。

 

相關焦點

  • TensorFlow(Keras)中的正則化技術及其實現(附代碼)
    了解用於緩解深度神經網絡內過度擬合問題的常規技術。正則化深度神經網絡(DNN)在體系結構內部具有大量的權重參數,可以學習一系列值。這些值的範圍是使神經網絡能夠解決龐大的複雜功能的關鍵。神經網絡越深,其擁有的代表性越強,但是隨著權重參數數量的增加,就會出現一個缺點。缺點是神經網絡更容易過度擬合訓練數據集。過度擬合:此問題涉及算法過於精確地預測在訓練過程中觀察和學習到的模式實例,從而預測向其呈現的模式的新實例。
  • 理解神經網絡中的Dropout
    dropout是指在深度學習網絡的訓練過程中,對於神經網絡單元,按照一定的概率將其暫時從網絡中丟棄。注意是暫時,對於隨機梯度下降來說,由於是隨機丟棄,故而每一個mini-batch都在訓練不同的網絡。
  • Keras代碼實踐|過擬合?別老是dropout,試試權重限制
    點擊上方「AI公園」,關注公眾號作者:Jason Brownlee編譯:ronghuaiyang權值限制提供了一個方法減少了深度學習中的過擬合線性在這個指南中,你將會使用Keras的API對深度學習模型加入權值限制來減小過擬合。完成了之個指南之後,你會知道:我們開始!
  • 神經網絡中避免過擬合5種方法介紹
    本文介紹了5種在訓練神經網絡中避免過擬合的技術。 最近一年我一直致力於深度學習領域。這段時間裡,我使用過很多神經網絡,比如卷積神經網絡、循環神經網絡、自編碼器等等。我遇到的最常見的一個問題就是在訓練時,深度神經網絡會過擬合。 當模型試著預測噪聲較多的數據的趨勢時,由於模型參數過多、過於複雜,就會導致過擬合。過擬合的模型通常是不精確的,因為這樣的預測趨勢並不會反映數據的真實情況。
  • 人工智慧算法問題——正則化解決神經網絡中的過度擬合
    過度擬合是一個很大的問題,尤其是在深度神經網絡中。如果你正在懷疑你的神經網絡過度擬合了。有很多方法可以確定過度擬合了數據,也許有一個高方差問題,或者繪製了一個訓練圖和測試精度圖,然後發現過度擬合了。在這種情況下,我們應該怎麼辦呢?
  • 神經網絡的正則化(代碼篇)
    我們在這篇文章裡將會使用keras面對具體的任務添加不同的正則化手段。我們採用boston房價這一經典回歸問題的數據集,因為它包含404個訓練樣例,102個測試樣本,特徵維數為13。對於深度學習而言,這樣的數據量和特徵都少得可憐,用一個簡單的神經網絡可能就會發生過擬合,這正是我們需要的。
  • 深度學習中權重衰減的偶然效應
    權值衰減的最初依據在機器學習中,可以在損失函數 L(w)中加入超參數λ>0的權重衰減項λ║w║來懲罰模型參數w的範數,然後用L(w)+λ║w║的最小化來代替L(w)中的最小化。增加這樣的權重衰減可以被看作是對w的範數施加軟約束。這種軟約束降低了模型的有效容量(即它的表示能力),同時也降低了它的過擬合傾向。
  • 理解卷積神經網絡中的輸入與輸出形狀(Keras實現)
    即使我們從理論上理解了卷積神經網絡,在實際進行將數據擬合到網絡時,很多人仍然對其網絡的輸入和輸出形狀(shape)感到困惑。本文章將幫助你理解卷積神經網絡的輸入和輸出形狀。讓我們看看一個例子。CNN的輸入數據如下圖所示。
  • 《基於Scikit-Learn、Keras和TensorFlow的機器學習實戰》:人工神經網絡介紹
    使用這個規則的變體來訓練感知器,該變體考慮了網絡進行預測時所犯的錯誤;它加強減少錯誤輸出的連接權重。更具體地,感知器一次被輸入一個訓練實例,並且對於每個實例,它進行預測。對於每一個產生錯誤預測的輸出神經元,它加強有助於正確預測的輸入的連接權重。該規則在下式示出。
  • 用Keras進行深度學習模式的正則化方法:Dropout
    Dropout是神經網絡和深度學習模型的簡單而有效的正則化技術。在這篇文章中,你將發現Dropout正則化技術,以及如何使用Keras將其應用於Python中的模型。看完這篇文章後,你會知道:Dropout正則化的原理。如何在輸入層上使用Dropout。如何在隱藏的層上使用Dropout。
  • 【深度神經網絡 One-shot Learning】孿生網絡少樣本精準分類
    我並不是做的真正的單樣本學習,因為很多符號我本來就認識,因為我熟悉希臘字母、平假名和片假名,我把這些我本來就認識的移除,我還是得到了96.7%的精度。我認為是我從自己嚇人的字跡中練就了超人般的字符識別能力。如果我們單純的訓練一個用交叉熵損失的softmax分類器神經網絡來做單樣本學習,很明顯,網絡會嚴重過擬合。即便是每類給出上百個樣本,現代的神經網絡依然會過擬合。
  • 【DS】Keras深度學習介紹
    2 您用過Keras嗎?您用Keras解決什麼問題?在本文中,我們將使用Keras構建一個簡單的神經網絡。我們假設您對機器學習包(如scikit-learn)和其他科學包(如panda和Numpy)有一定的了解。
  • Keras入門系列教程:兩分鐘構建你的第一個神經網絡模型
    Keras主要用於快速原型設計,高級研究和生產中,具有三個主要優勢:用戶友好的Keras提供一致而簡潔的API, 能夠極大減少一般應用下用戶的工作量,同時,Keras提供清晰和具有實踐意義的bug反饋。
  • 用Keras從零開始6步驟訓練神經網絡
    Keras遵循減少認知困難的最佳實踐,它提供一致且簡單的 API,將常見用例所需的用戶操作數量降至最低,並且在用戶錯誤時提供清晰和可操作的反饋。功能強大:Keras同時支持卷積神經網絡和循環神經網絡,以及兩者的組合,它可以在CPU和GPU上無縫運行。
  • 入門| 一文了解神經網絡中的梯度爆炸
    本文將介紹深度神經網絡中的梯度爆炸問題。 閱讀本文,你將了解: 什麼是梯度爆炸,模型訓練過程中梯度爆炸會引起哪些問題; 如何確定自己的網絡模型是否出現梯度爆炸; 如何修復梯度爆炸問題。 什麼是梯度爆炸? 誤差梯度是神經網絡訓練過程中計算的方向和數量,用於以正確的方向和合適的量更新網絡權重。
  • 深度學習中Dropout原理解析
    Dropout簡介1.1 Dropout出現的原因在機器學習的模型中,如果模型的參數太多,而訓練樣本又太少,訓練出來的模型很容易產生過擬合的現象。在訓練神經網絡的時候經常會遇到過擬合的問題,過擬合具體表現在:模型在訓練數據上損失函數較小,預測準確率較高;但是在測試數據上損失函數比較大,預測準確率較低。過擬合是很多機器學習的通病。如果模型過擬合,那麼得到的模型幾乎不能用。
  • 初學AI神經網絡應該選擇Keras或是Pytorch框架?
    TensorFlow框架儘管意義非凡,引起極大關注和神經網絡學習風潮,但對一般開發者用戶太不友好。軟體開發者畢竟不是科學家,很多時候簡單易學易用是程式設計師選擇的第一要素。目前,兩個主要的深度學習庫Keras和Pytorch獲得了大量關注,主要是因為它們的使用比較簡單。
  • 深度神經網絡中的數學,對你來說會不會太難?
    在前饋神經網絡中,θ就是神經網絡,而該網絡由 d 個函數組成:大部分神經網絡都是高維的,因此其也可以通過以下結構圖表達:其中是向量值函數 f^(i) 的分量,也即第 i 層神經網絡的分量,每一個 是的函數。在上面的結構圖中,每一層函數 f^(i) 的分量數也稱為層級 i 的寬度,層級間的寬度可能是不一樣的。我們稱神經網絡的層級數 d 為網絡的深度。
  • Keras 教程: Python 深度學習終極入門指南
    在這篇 Keras 教程中, 你將學到如何用 Python 建立一個卷積神經網絡!事實上, 我們將利用著名的 MNIST 數據集, 訓練一個準確度超過 99% 的手寫數字分類器.開始之前, 請注意, 本指南是面向對應用深度學習感興趣的初學者的.
  • 基於Keras/Python的深度學習模型Dropout正則項
    Dropout的做法是在訓練過程中隨機地忽略一些神經元。這些神經元被隨機地「拋棄」了。也就是說它們在正向傳播過程中對於下遊神經元的貢獻效果暫時消失了,反向傳播時該神經元也不會有任何權重的更新。隨著神經網絡模型不斷地學習,神經元的權值會與整個網絡的上下文相匹配。神經元的權重針對某些特徵進行調優,具有一些特殊化。