dropout正則化技術介紹
?
dropout技術是神經網絡和深度學習模型的一種簡單而有效的正則化方式。
本文將向你介紹dropout正則化技術,并且教你如何在Keras中用Python將其應用于你的模型。
讀完本文之后,你將了解:
dropout正則化的原理如何在輸入層使用dropout如何在隱藏層使用dropout如何針對具體問題對dropout調優
神經網絡的Dropout正則化
Dropout是Srivastava等人在2014年的一篇論文中提出的一種針對神經網絡模型的正則化方法 Dropout: A Simple Way to Prevent Neural Networks from Overfitting。
Dropout的做法是在訓練過程中隨機地忽略一些神經元。這些神經元被隨機地“拋棄”了。也就是說它們在正向傳播過程中對于下游神經元的貢獻效果暫時消失了,反向傳播時該神經元也不會有任何權重的更新。
隨著神經網絡模型不斷地學習,神經元的權值會與整個網絡的上下文相匹配。神經元的權重針對某些特征進行調優,具有一些特殊化。周圍的神經元則會依賴于這種特殊化,如果過于特殊化,模型會因為對訓練數據過擬合而變得脆弱不堪。神經元在訓練過程中的這種依賴于上下文的現象被稱為復雜的協同適應(complex co-adaptations)。
你可以想象一下,如果在訓練過程中隨機丟棄網絡的一部分,那么其它神經元將不得不介入,替代缺失神經元的那部分表征,為預測結果提供信息。人們認為這樣網絡模型可以學到多種相互獨立的內部表征。
這么做的效果就是,網絡模型對神經元特定的權重不那么敏感。這反過來又提升了模型的泛化能力,不容易對訓練數據過擬合。
Keras的Dropout 正則化
Dropout的實現很簡單,在每輪權重更新時隨機選擇一定比例(比如20%)的節點拋棄。Keras的Dropout也是這么實現的。Dropout技術只在模型訓練的階段使用,在評估模型性能的時候不需使用。
接下來我們看看Dropout在Keras中的一些不同用法。
本例子使用了聲吶數據集(Sonar dataset)。這是一個二分類問題,目的是根據聲吶的回聲來正確地區分巖石和礦區。這個數據集非常適合神經網絡模型,因為所有的輸入都是數值型的,且具有相同的量綱。
數據集可以從UCI機器學習代碼庫下載。然后把聲吶數據集放在當前工作路徑下,文件命名為sonar.csv。
我們會用scikit-learn來評價模型質量,為了更好地挑揀出結果的差異,采用了十折交叉驗證(10-fold cross validation)方法。
每條數據有60個輸入值和1個輸出值,輸入值在送入模型前做了歸一化。基準的神經網絡模型有兩個隱藏層,第一層有60個節點,第二層有30個。使用了隨機梯度下降的方法來訓練模型,選用了較小的學習率和沖量。
完整的基準模型代碼如下所示。
importnumpy importpandas fromkeras.models importSequential fromkeras.layers importDense fromkeras.layers importDropout fromkeras.wrappers.scikit_learn importKerasClassifier fromkeras.constraints importmaxnorm fromkeras.optimizers importSGD fromsklearn.cross_validation importcross_val_score fromsklearn.preprocessing importLabelEncoder fromsklearn.cross_validation importStratifiedKFold fromsklearn.preprocessing importStandardScaler fromsklearn.grid_search importGridSearchCV fromsklearn.pipeline importPipeline fromsklearn.grid_search importGridSearchCV # fix random seed for reproducibilityseed = 7numpy.random.seed(seed) # load datasetdataframe = pandas.read_csv(“sonar.csv”, header=None) dataset = dataframe.values # split into input (X) and output (Y) variablesX = dataset[:,0:60].astype(float) Y = dataset[:,60] # encode class values as integersencoder = LabelEncoder() encoder.fit(Y) encoded_Y = encoder.transform(Y) # baselinedefcreate_baseline():# create modelmodel = Sequential() model.add(Dense(60, input_dim=60, init=‘normal’, activation=‘relu’)) model.add(Dense(30, init=‘normal’, activation=‘relu’)) model.add(Dense(1, init=‘normal’, activation=‘sigmoid’)) # Compile modelsgd = SGD(lr=0.01, momentum=0.8, decay=0.0, nesterov=False) model.compile(loss=‘binary_crossentropy’, optimizer=sgd, metrics=[‘accuracy’]) returnmodel numpy.random.seed(seed) estimators = [] estimators.append((‘standardize’, StandardScaler())) estimators.append((‘mlp’, KerasClassifier(build_fn=create_baseline, nb_epoch=300, batch_size=16, verbose=0))) pipeline = Pipeline(estimators) kfold = StratifiedKFold(y=encoded_Y, n_folds=10, shuffle=True, random_state=seed) results = cross_val_score(pipeline, X, encoded_Y, cv=kfold) print(“Accuracy: %.2f%% (%.2f%%)”% (results.mean()*100, results.std()*100))
運行代碼,分類的準確率大概為82%。
Accuracy: 82.68% (3.90%)
在可見層使用Dropout
Dropout可用于輸入神經元,即可見層。
在下面這個例子里,我們在輸入(可見層)和第一個隱藏層之間加入一層Dropout。丟棄率設為20%,就是說每輪迭代時每五個輸入值就會被隨機拋棄一個。
另外,正如Dropout那篇論文中所推薦的,每個隱藏層的權重值都做了限制,確保權重范數的最大值不超過3。在構建模型層的時候,可以通過設置Dense Class的W_constraint參數實現。
學習率提高了一個數量級,沖量增加到0.9。這也是那篇Dropout論文的原文中所推薦的做法。
順著上面基準模型的例子,下面的代碼是包含輸入層dropout的網絡模型。
# dropout in the input layer with weight constraintdefcreate_model1():# create modelmodel = Sequential() model.add(Dropout(0.2, input_shape=(60,))) model.add(Dense(60, init=‘normal’, activation=‘relu’, W_constraint=maxnorm(3))) model.add(Dense(30, init=‘normal’, activation=‘relu’, W_constraint=maxnorm(3))) model.add(Dense(1, init=‘normal’, activation=‘sigmoid’)) # Compile modelsgd = SGD(lr=0.1, momentum=0.9, decay=0.0, nesterov=False) model.compile(loss=‘binary_crossentropy’, optimizer=sgd, metrics=[‘accuracy’]) returnmodel numpy.random.seed(seed) estimators = [] estimators.append((‘standardize’, StandardScaler())) estimators.append((‘mlp’, KerasClassifier(build_fn=create_model1, nb_epoch=300, batch_size=16, verbose=0))) pipeline = Pipeline(estimators) kfold = StratifiedKFold(y=encoded_Y, n_folds=10, shuffle=True, random_state=seed) results = cross_val_score(pipeline, X, encoded_Y, cv=kfold) print(“Accuracy: %.2f%% (%.2f%%)”% (results.mean()*100, results.std()*100))
運行這段代碼,分類準確率完美地提升到了86%。
Accuracy: 86.04% (6.33%)
在隱藏層使用Dropout
Dropout也可用于模型內的隱藏層節點。
下面這個例子里,Dropout被用于兩個隱藏層之間和隱藏層與輸出層之間。丟棄率同樣設為20%,且使用權重限制。
# dropout in hidden layers with weight constraintdefcreate_model2():# create modelmodel = Sequential() model.add(Dense(60, input_dim=60, init=‘normal’, activation=‘relu’, W_constraint=maxnorm(3))) model.add(Dropout(0.2)) model.add(Dense(30, init=‘normal’, activation=‘relu’, W_constraint=maxnorm(3))) model.add(Dropout(0.2)) model.add(Dense(1, init=‘normal’, activation=‘sigmoid’)) # Compile modelsgd = SGD(lr=0.1, momentum=0.9, decay=0.0, nesterov=False) model.compile(loss=‘binary_crossentropy’, optimizer=sgd, metrics=[‘accuracy’]) returnmodel numpy.random.seed(seed) estimators = [] estimators.append((‘standardize’, StandardScaler())) estimators.append((‘mlp’, KerasClassifier(build_fn=create_model2, nb_epoch=300, batch_size=16, verbose=0))) pipeline = Pipeline(estimators) kfold = StratifiedKFold(y=encoded_Y, n_folds=10, shuffle=True, random_state=seed) results = cross_val_score(pipeline, X, encoded_Y, cv=kfold) print(“Accuracy: %.2f%% (%.2f%%)”% (results.mean()*100, results.std()*100))
我們觀察到,對于這個問題以及所設置的模型配置參數,在隱藏層使用dropout并不能提升模型效果。事實上,效果反而比基準更差。
有可能需要增加訓練迭代次數,或者是更多地調優學習率。
Accuracy: 82.16% (6.16%)
使用Dropout的小技巧
提出Dropout的那篇論文提供了一些在標準機器學習問題上得到的實踐性結論。這些結論在dropout的實際應用中會帶來幫助。
通常丟棄率控制在20%~50%比較好,可以從20%開始嘗試。如果比例太低則起不到效果,比例太高則會導致模型的欠學習。在大的網絡模型上應用。當dropout用在較大的網絡模型時更有可能得到效果的提升,模型有更多的機會學習到多種獨立的表征。在輸入層(可見層)和隱藏層都使用dropout。在每層都應用dropout被證明會取得好的效果。增加學習率和沖量。把學習率擴大10~100倍,沖量值調高到0.9~0.99.限制網絡模型的權重。大的學習率往往導致大的權重值。對網絡的權重值做最大范數正則化等方法被證明會提升效果。
有關Dropout的更多資源
下面這些資料也是關于dropout在神經網絡和深度學習模型中應用。
Dropout: A Simple Way to Prevent Neural Networks from Overfitting(原論文)Improving neural networks by preventing co-adaptation of feature detectors.How does the dropout method work in deep learning?來自Quora
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%