摘要:介紹權(quán)重正則化可以減輕深度神經(jīng)網(wǎng)絡(luò)模型的過(guò)擬合問(wèn)題,可以提升對(duì)新數(shù)據(jù)的泛化能力。代碼展示在卷積層中使用正則化。許多正則化方法通過(guò)向訓(xùn)練數(shù)據(jù)添加噪聲來(lái)防止過(guò)擬合。模型使用損失函數(shù),優(yōu)化器。
介紹
權(quán)重正則化可以減輕深度神經(jīng)網(wǎng)絡(luò)模型的過(guò)擬合問(wèn)題,可以提升對(duì)新數(shù)據(jù)的泛化能力。有多種正則方法可供選擇,如:L1,L2正則化,每種方法在使用前需要超參數(shù)配置。在這篇文章中,你將學(xué)習(xí)在keras如何使用權(quán)重正則化的方法來(lái)減輕模型過(guò)擬合問(wèn)題。
讀完本篇文章,你將學(xué)習(xí)到:
如何在keras中使用權(quán)重正則化應(yīng)用到MLP,CNN,或者LSTM神經(jīng)網(wǎng)絡(luò)任務(wù)中
一些常見(jiàn)論文在模型中使用權(quán)重正則化的方法和經(jīng)驗(yàn)
通過(guò)一個(gè)案例學(xué)習(xí)如何使用權(quán)重正則化解決過(guò)擬合問(wèn)題
## keras中權(quán)重正則化方法 ##
keras提供了權(quán)重正則化方法,可以在損失函數(shù)中通過(guò)添加懲罰系數(shù)來(lái)使用。keras提供了三種正則化方法:
L1:絕對(duì)值權(quán)重之和
L2:平方權(quán)重之和
L1L2:兩者累加之和
tf.keras.regularizers.l1(l=0.01) tf.keras.regularizers.l2(l=0.01) tf.keras.regularizers.l1_l2(l1=0.01,l2=0.01)
keras中,權(quán)重正則化可以應(yīng)用到任意一層,不過(guò),模型默認(rèn)不使用任何權(quán)重正則化。
全連接層使用權(quán)重正則化全連接層使用L2權(quán)重正則化:
import tensorflow as tf model=tf.keras.models.Sequential( # 權(quán)重正則化,bias正則化(應(yīng)用較少) tf.keras.layers.Dense(512,activation=tf.nn.relu,kernel_regularizer=tf.keras.regularizers.l2(l=0.001),bias_regularizer=tf.keras.regularizers.l2(l=0.001)) )卷積層使用權(quán)重正則化
同全連接層一樣,卷積層也使用kernel_regularizer和bias_regularizer參數(shù)添加正則化。代碼展示在卷積層中使用L2正則化。
import tensorflow as tf model=tf.keras.models.Sequential( tf.keras.layers.Conv2D(32,3,activation=tf.nn.relu,kernel_regularizer=tf.keras.regularizers.l2(l=0.001),bias_regularizer=tf.keras.regularizers.l2(l=0.001)) )RNN網(wǎng)絡(luò)中使用權(quán)重正則化
代碼展示在LSTM網(wǎng)絡(luò)中使用L2權(quán)重正則化
import tensorflow as tf model=tf.keras.models.Sequential( tf.keras.layers.LSTM(32,activation=tf.nn.tanh,recurrent_regularizer=tf.keras.regularizers.l2(l=0.001),kernel_regularizer=tf.keras.regularizers.l2(l=0.001),bias_regularizer=tf.keras.regularizers.l2(l=0.001)) )權(quán)重正則化使用經(jīng)驗(yàn)
最常見(jiàn)的權(quán)重正則化是L2正則化,數(shù)值通常是0-0.1之間,如:0.1,0.001,0.0001。
找到最優(yōu)的系數(shù)并不容易,需要嘗試不同的權(quán)重系數(shù),找到模型表現(xiàn)最平穩(wěn)優(yōu)秀的系數(shù)
L2正則化在CNN網(wǎng)絡(luò)中,建議系數(shù)設(shè)置小一些,如:0.0005
少量的權(quán)重正則對(duì)模型很重要,可以減少模型訓(xùn)練誤差
LSTM網(wǎng)絡(luò)中L2權(quán)重系數(shù)通常更小,如:10^-6
權(quán)重正則化案例學(xué)習(xí)我們將使用標(biāo)準(zhǔn)二元分類(lèi)問(wèn)題來(lái)定義兩個(gè)半圓觀察:每個(gè)類(lèi)一個(gè)半圓。每個(gè)觀測(cè)值都有兩個(gè)輸入變量,它們具有相同的比例,類(lèi)輸出值為0或1.該數(shù)據(jù)集稱(chēng)為“月亮”數(shù)據(jù)集,因?yàn)槔L制時(shí)每個(gè)類(lèi)中的觀測(cè)值的形狀。
# 導(dǎo)入sklearn中的數(shù)據(jù)集 from sklearn.datasets import make_moons from matplotlib import pyplot from pandas import DataFrame # 生成2分類(lèi)數(shù)據(jù)集 X, y = make_moons(n_samples=100, noise=0.2, random_state=1) print(X.shape) print(X[:6]) print(y.shape) print(y[:6]) 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(ax=ax, kind="scatter", x="x", y="y", label=key, color=colors[key]) pyplot.show()
sklearn常用數(shù)據(jù)集:
數(shù)據(jù)集格式:
matplot結(jié)果顯示:
如圖所示,該問(wèn)題是非線性問(wèn)題,可以使用神經(jīng)網(wǎng)絡(luò)來(lái)解決。我們只生成了100個(gè)樣本,對(duì)神經(jīng)網(wǎng)絡(luò)來(lái)說(shuō)數(shù)據(jù)量很少,這很容易造成過(guò)擬合問(wèn)題。我們使用正則化,添加噪聲數(shù)據(jù)來(lái)處理問(wèn)題。
雖然卷積神經(jīng)網(wǎng)絡(luò)(CNN)功能強(qiáng)大,并廣泛應(yīng)用于各種計(jì)算機(jī)視覺(jué)任務(wù)中,但由于參數(shù)過(guò)多而導(dǎo)致過(guò)度擬合[22]。神經(jīng)網(wǎng)絡(luò)的最初發(fā)展受到人腦機(jī)制的啟發(fā)[18],它不像計(jì)算機(jī)那樣精確。受到差異的啟發(fā),我們推斷在訓(xùn)練過(guò)程中添加噪音可能會(huì)指示CNN學(xué)習(xí)更強(qiáng)大的特征表示以抵消噪音的影響,從而降低過(guò)度擬合的風(fēng)險(xiǎn)。許多正則化方法通過(guò)向訓(xùn)練數(shù)據(jù)添加噪聲來(lái)防止過(guò)擬合。數(shù)據(jù)增強(qiáng)的輸入圖像,如隨機(jī)裁剪,翻轉(zhuǎn)和阻塞[9,21,30]已廣泛用于提高CNNs的泛化能力。 Adversarial Training [1]被提出來(lái)通過(guò)在圖像中添加基于梯度的擾動(dòng)來(lái)調(diào)整網(wǎng)絡(luò)。 DisturbLabel [26]隨機(jī)地將樣本的一小部分子集的標(biāo)簽改變?yōu)椴徽_的值,從而在損失層上規(guī)則化CNN。過(guò)擬合模型
我們創(chuàng)建一個(gè)只有一層隱藏層的MLP模型,并讓神經(jīng)元數(shù)量大于樣本數(shù)量,然后過(guò)長(zhǎng)時(shí)間訓(xùn)練模型,以此來(lái)人為造成過(guò)擬合問(wèn)題。訓(xùn)練模型之前,我們拆分下數(shù)據(jù)集,訓(xùn)練數(shù)據(jù)30%,驗(yàn)證數(shù)據(jù)70%,來(lái)訓(xùn)練模型表現(xiàn)。
X, y = make_moons(n_samples=100, noise=0.2, random_state=1) # 拆分?jǐn)?shù)據(jù)集 n_train = 30 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:]
模型隱藏層有500個(gè)神經(jīng)元,激活函數(shù)使用relu,輸出層使用sigmoid激活函數(shù),輸出一項(xiàng)類(lèi)別。模型使用bind_crossentropy損失函數(shù),adam優(yōu)化器。
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"])
模型迭代數(shù)據(jù)集400次,batch_size=32。
model.fit(trainX, trainy, epochs=4000, verbose=0)
在測(cè)試集上評(píng)估模型表現(xiàn):
# model.evaluate返回:loss value;metrics value _, 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))
模型輸出結(jié)果:
我們看到訓(xùn)練表現(xiàn)遠(yuǎn)大于測(cè)試表現(xiàn),這是過(guò)擬合問(wèn)題的典型標(biāo)志。我們將train和test訓(xùn)練精度過(guò)程圖形化展示出來(lái)。
from sklearn.datasets import make_moons from keras.layers import Dense from keras.models import Sequential from matplotlib import pyplot X, y = make_moons(n_samples=100, noise=0.2, random_state=1) n_train = 30 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 創(chuàng)建模型 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"]) # 返回訓(xùn)練,驗(yàn)證集的損失和準(zhǔn)確率 history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0) pyplot.plot(history.history["acc"], label="train") pyplot.plot(history.history["val_acc"], label="test") pyplot.legend() pyplot.show()
如圖所示,在某一點(diǎn),train和test的準(zhǔn)確率出現(xiàn)分叉口。
使用正則化的模型我們將在隱藏層中使用權(quán)重正則化,并設(shè)置系數(shù)為0.001,以此來(lái)減輕過(guò)擬合問(wèn)題。
model.add(Dense(500, input_dim=2, activation="relu", kernel_regularizer=l2(0.001)))
完整代碼如下:
from sklearn.datasets import make_moons from keras.layers import Dense from keras.models import Sequential from keras.regularizers import l2 # 創(chuàng)建數(shù)據(jù)集 X, y = make_moons(n_samples=100, noise=0.2, random_state=1) # 拆分?jǐn)?shù)據(jù)集 n_train = 30 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 創(chuàng)建模型 model = Sequential() # 設(shè)置權(quán)重正則化 model.add(Dense(500, input_dim=2, activation="relu", kernel_regularizer=l2(0.001))) model.add(Dense(1, activation="sigmoid")) model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"]) # 訓(xùn)練模型 model.fit(trainX, trainy, epochs=4000, verbose=0) # 評(píng)估模型 _, 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))
乍一看,好像除了test準(zhǔn)確率降低些,其它也沒(méi)什么了。讓我們畫(huà)圖看下train和test的訓(xùn)練過(guò)程。
from sklearn.datasets import make_moons from keras.layers import Dense from keras.models import Sequential from keras.regularizers import l2 from matplotlib import pyplot X, y = make_moons(n_samples=100, noise=0.2, random_state=1) n_train = 30 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] model = Sequential() model.add(Dense(500, input_dim=2, activation="relu", kernel_regularizer=l2(0.001))) model.add(Dense(1, activation="sigmoid")) model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"]) history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0 pyplot.plot(history.history["acc"], label="train") pyplot.plot(history.history["val_acc"], label="test") pyplot.legend() pyplot.show()
如圖所示,現(xiàn)在就很清楚了,test與train一致。
網(wǎng)格搜索正則化超參數(shù)當(dāng)確定權(quán)重正則化可以改善模型的時(shí)候,這時(shí)你可以嘗試不同的權(quán)重系數(shù)值。首先對(duì)0.0到0.1之間的一些數(shù)量級(jí)進(jìn)行網(wǎng)格搜索,然后再找到一個(gè)級(jí)別后進(jìn)行網(wǎng)格搜索,這是一個(gè)很好的做法。
# 待測(cè)權(quán)重正則化值 values = [1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6] all_train, all_test = list(), list() for param in values: ... model.add(Dense(500, input_dim=2, activation="relu", kernel_regularizer=l2(param))) ... all_train.append(train_acc) all_test.append(test_acc)
我們依然可以圖形化展示訓(xùn)練過(guò)程:
pyplot.semilogx(values, all_train, label="train", marker="o") pyplot.semilogx(values, all_test, label="test", marker="o")
完整代碼如下:
from sklearn.datasets import make_moons from keras.layers import Dense from keras.models import Sequential from keras.regularizers import l2 from matplotlib import pyplot # 創(chuàng)建數(shù)據(jù)集 X, y = make_moons(n_samples=100, noise=0.2, random_state=1) # 拆分?jǐn)?shù)據(jù)集 n_train = 30 trainX, testX = X[:n_train, :], X[n_train:, :] trainy, testy = y[:n_train], y[n_train:] # 待測(cè)權(quán)重系數(shù)值 values = [1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6] all_train, all_test = list(), list() for param in values: # 創(chuàng)建模型 model = Sequential() model.add(Dense(500, input_dim=2, activation="relu", kernel_regularizer=l2(param))) model.add(Dense(1, activation="sigmoid")) model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"]) # 訓(xùn)練模型 model.fit(trainX, trainy, epochs=4000, verbose=0) # 評(píng)估模型 _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) print("Param: %f, Train: %.3f, Test: %.3f" % (param, train_acc, test_acc)) all_train.append(train_acc) all_test.append(test_acc) # plot train and test means pyplot.semilogx(values, all_train, label="train", marker="o") pyplot.semilogx(values, all_test, label="test", marker="o") pyplot.legend() pyplot.show()總結(jié)
降低過(guò)擬合問(wèn)題,我們一般需要從“數(shù)據(jù)”,“模型結(jié)構(gòu)”,“模型參數(shù)”,“模型訓(xùn)練方法”等角度,采用的方法如下:
數(shù)據(jù)增強(qiáng):圖像的平移,旋轉(zhuǎn),裁剪等;利用GAN生成新數(shù)據(jù);利用機(jī)器翻譯生成新數(shù)據(jù)。
降低模型復(fù)雜度:減少網(wǎng)絡(luò)層數(shù),神經(jīng)元個(gè)數(shù);
添加正則化項(xiàng),如:L1,L2
集成學(xué)習(xí):神經(jīng)網(wǎng)絡(luò),dropout
避免過(guò)長(zhǎng)時(shí)間訓(xùn)練模型,設(shè)置提前終止。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/19965.html
摘要:下面介紹一些值得注意的部分,有些簡(jiǎn)單解釋原理,具體細(xì)節(jié)不能面面俱到,請(qǐng)參考專(zhuān)業(yè)文章主要來(lái)源實(shí)戰(zhàn)那我們直接從拿到一個(gè)問(wèn)題決定用神經(jīng)網(wǎng)絡(luò)說(shuō)起。當(dāng)你使用時(shí)可以適當(dāng)減小學(xué)習(xí)率,跑過(guò)神經(jīng)網(wǎng)絡(luò)的都知道這個(gè)影響還蠻大。 神經(jīng)網(wǎng)絡(luò)構(gòu)建好,訓(xùn)練不出好的效果怎么辦?明明說(shuō)好的擬合任意函數(shù)(一般連續(xù))(為什么?可以參考http://neuralnetworksanddeeplearning.com/),說(shuō)好的足夠...
摘要:以用于檢測(cè)垃圾郵件的邏輯回歸模型為例。邏輯回歸的損失函數(shù)線性回歸的損失函數(shù)是平方損失。正則化在邏輯回歸建模中極其重要。 正則化:簡(jiǎn)單性 查看以下泛化曲線,該曲線顯示的是訓(xùn)練集和驗(yàn)證集相對(duì)于訓(xùn)練迭代次數(shù)的損失。 showImg(https://segmentfault.com/img/bVbahiL?w=750&h=322);上圖顯示的是某個(gè)模型的訓(xùn)練損失逐漸減少,但驗(yàn)證損失最終增加。換...
閱讀 2630·2021-09-28 09:36
閱讀 2247·2021-09-07 09:58
閱讀 1504·2019-08-26 13:53
閱讀 1287·2019-08-23 17:53
閱讀 3035·2019-08-23 15:34
閱讀 1859·2019-08-23 15:34
閱讀 2876·2019-08-23 12:04
閱讀 3727·2019-08-23 10:56