【調參10】:如何通過組合多個神經網絡提高模型性能



前言

深度神經網絡是非線性的。它們提供了更大的靈活性,並且理論上隨着數據集的增多,其性能表現會越好。其缺點是通過隨機訓練算法進行學習,這意味着神經網絡對訓練數據很敏感,並且每次訓練時會得到不同的權重向量,從而產生不同的預測。通常,這被稱爲具有高方差的神經網絡,當使用其模型進行預測時,可能效果並不好。

減少神經網絡模型方差的成功方法是融合多個模型而不是單個模型,並結合這些模型的預測結果綜合判斷,這樣的模型稱爲融合模型(Aggregation Model),這種算法稱爲集成學習(Ensemble Learning)。融合模型不僅可以減少預測的方差,而且可以產生比任何單個模型都更好的預測。


1. 使用融合模型減少模型的方差

訓練深度神經網絡可能在計算上非常昂貴。在包含數百萬個樣本的數據集上訓練非常深的網絡可能需要花費數天,甚至數月的時間。

訓練許多不同的候選網絡,然後選擇最佳的網絡,並丟棄其餘的網絡。這種方法有兩個缺點。

  • 浪費在訓練其餘網絡上的所有精力。
  • 在驗證集上表現最佳的網絡可能不是在新測試數據上表現最佳的網絡。

神經網絡模型是一種非線性方法,可以學習數據中的複雜非線性關係。但是,這種學習算法具有很大的隨機性,可以將神經網絡視爲一種具有低偏差和高方差的學習方法。

解決神經網絡高方差的一種方案是訓練多個模型並融合它們的預測,之前的集成學習文章中提到過。一個好的模型,意味着它的預測要好於隨機預測的結果。重要的是,這些模型必須以不同的方式保持良好,並且產生不同的預測誤差。這正是融合模型性能表現好的原因。

融合來自多個神經網絡的預測會增加一個偏差,該偏差又會抵消單個訓練後的神經網絡模型的變化。融合模型的預測結果相對於擁有相同訓練數據集,模型配置的單個神經網絡模型來說,其預測對數據的敏感性很低,因爲減少的訓練房差,所以可以表現得更好。除了減少預測中的方差之外,集成模型可以比任何單個最佳模型產生更好的預測。

集成學習是融合模型充分利用針對同一問題準備的多個模型的預測的方法。通常,集成學習涉及在同一數據集上訓練多個網絡,然後使用每種訓練後的模型進行預測,然後再以某種方式組合預測以得出最終結果或預測。實際上,融合模型是應用機器學習中的一種標準方法,可確保做出最穩定,最好的預測。

例如,Alex Krizhevsky 在2012年的論文《深度卷積神經網絡Imagenet分類》中,介紹了用於照片分類的深度卷積神經網絡AlexNet,它使用了多個表現良好的CNN模型的模型平均,來獲得最好的結果。將一個模型的性能與在兩個,五個和七個不同模型上平均的總體預測進行比較。


2. 如何融合神經網絡模型

在同一數據集上訓練具有相同配置和不同初始隨機權重的網絡集合。然後,使用每個模型進行預測,並將實際預測計算爲預測的平均值。由於訓練模型中的計算開銷以及由於增加更多的神經網絡模型而導致的性能下降,因此融合模型的數量通常保持較小,集成的模型一般小於10個。

集成學習領域已得到很好的研究,並且有很多變體。考慮集成方法的配置主要有以下三種:

  • 訓練數據:每個模型使用不同的訓練數據。
  • 模型選擇:使用不同的神經網絡模型。
  • 融合模型:使用不同的模型融合方式。

2.1 使用不同的訓練數據

融合模型中,每個神經網絡模型的訓練數據可以不同。

最簡單的方法是使用k折交叉驗證來估計所選模型配置的泛化誤差。在此過程中,在訓練數據的k個不同子集上訓練了k個不同的模型。然後可以保存這k個模型並將其作爲融合模型中的神經網絡模型。

另一種流行的方法包括對替換後的訓練數據集進行重新採樣,然後使用重新採樣的數據集對網絡進行訓練。重採樣過程意味着每個訓練數據集的組成是不同的,存在重複示例的可能性,從而使在數據集上訓練的模型對樣本密度的期望稍有不同,進而產生不同的泛化誤差。這種方法稱爲自舉融合(bootstrap aggregation),或簡稱爲裝袋算法( bagging ),用於具有高方差和低偏差的未修剪決策樹。考慮到該方法預處理速度很快,通常會使用大量決策樹,例如數百或數千。

減少方差提高統計學習方法的預測準確性的自然方法是從總體中獲取許多訓練集,使用每個訓練集構建單獨的預測模型,並對得到的預測取平均。然而這是不切實際的,因爲通常無法訪問多個培訓集。相反,我們可以通過從(單個)訓練數據集中重複採樣來實現。

一種等效的方法是使用訓練數據集的較小子集,使用不進行正則化以允許更快的訓練和過擬合的模型。欠優化模型更普遍地適用於融合模型中神經網絡的選擇。

其它方法可能涉及選擇輸入空間的隨機子空間分配給每個模型,例如輸入空間中超參數的子集或輸入特徵的子集。


2.2 使用不同的模型

大多數神經網絡,特別是由於存在大量的次優局部最小值而實現次優性能的神經網絡。如果採用一組已收斂到局部極小值的神經網絡並應用平均,可以構建一個改進的估計。一種理解方法是,考慮到一般而言,落入不同局部最小值的網絡在特徵空間的不同區域中將表現較差,因此它們的誤差項將不會強烈相關。

這可能會導致方差減小,但可能不會顯着改善泛化誤差。由於模型都學習了相似的映射功能,因此模型所產生的錯誤可能仍然過於相關。一種替代方法可能是更改每個集成模型的配置,例如使用具有不同容量的網絡(例如,層或節點的數量)或在不同條件下訓練的模型(例如,學習率或正則化)。其結果可能是這些異構的模型已經學習了具有不同地映射關係的集合,進而在其預測和預測誤差中具有較低的相關性。

可以通過開發網絡和調整其超參數實現這種具有不同配置模型的集成。可以在選擇子模型的過程中過程中每個模型,並選擇一部分更好的模型來構成最後的融合模型。

如果單個模型可能需要花費數週或數月的時間進行訓練,另一種選擇是在訓練過程中定期保存最佳模型(檢查點模型),然後在已保存的模型中選擇需要融合的模型。

非常深的神經網絡的一個好處是,中間的隱藏層提供了低分辨率輸入數據的學習表示。隱藏層可以直接輸出其內部表示,並且來自一個非常深的網絡的一個或多個隱藏層的輸出可以用作新分類模型的輸入。當使用自動編碼器模型訓練深度模型時,這可能是最有效的。這種類型的融合稱爲垂直融合。


2.3 使用不同的融合方式

簡單的融合方式是直接對各個神經網絡模型的預測進行平均。

一種改進方法是使用驗證數據集選擇子模型,然後通過對每個模型的預測進行加權平均。這種方法稱爲加權平均集成(weighted average ensemble),有時稱爲模型混合(model blending)

更進一步,可以使用更復雜的非線性方法。除了每個子模型提供的預測之外,該方法還考慮特定的輸入樣本。這種方法一般被稱爲模型堆疊(model stacking)堆疊泛化(stacked generalization)

有許多用於堆疊模型的更復雜的方法,例如增強功能,一次可以添加一個集成子模型,以糾正先前模型的錯誤。增加的複雜性意味着這種方法很少用於大型神經網絡模型。

另一個略有不同的組合是將具有相同結構的多個神經網絡的權重進行組合。可以對多個網絡的權重進行平均,以期產生一個新的單一模型,該模型具有比任何原始模型都更好的整體性能。這種方法稱爲模型權重平均(model weight averaging)


3. tensorflow keras 實現模型平均

在Keras中開發模型平均合奏的最簡單方法是在同一數據集上訓練多個模型,然後組合來自每個訓練模型的預測。

3.1 訓練多種模型

訓練多個模型可能會佔用大量資源,具體取決於模型的大小和訓練數據的大小。

集成所需的模型數量可能會根據問題和模型的複雜性而有所不同。這種方法的好處是可以繼續創建模型,將其添加到集合中,並通過對保持測試集進行預測來評估它們對性能的影響。

小型模型可以全部同時加載到內存中,而超大型模型可能必須一次加載一個模型才能進行預測,然後再組合預測。

from tensorflow.keras.models import load_model
...
n_members = 10
models = list()
for i in range(n_members):
	# load model
	filename = 'model_' + str(i + 1) + '.h5'
	model = load_model(filename)
	# store in memory
	models.append(model)
...

3.2 融合模型

對於迴歸問題,可以對預測計算平均值。

...
# make predictions
yhats = [model.predict(testX) for model in models]
yhats = array(yhats)
# calculate average
outcomes = mean(yhats)

對於分類問題,有兩種選擇。

一種是計算預測的整數類別出現次數。

...
from scipy.stats import mode
# make predictions
yhats = [model.predict_classes(testX) for model in models]
yhats = array(yhats)
# calculate mode
outcomes, _ = scipy.stats.mode(yhats)

這種方法的缺點是,對於較小的融合和興或具有大量類別的數據集,預測結果可能不準確。

在二分類問題中,輸出層上使用了S形激活函數,可以像迴歸問題一樣計算預測概率的平均值。在具有兩個以上類別的多類別分類問題的情況下,在輸出層上使用softmax激活函數,可以在採用argmax獲得類別值之前計算每個預測類別的概率之和。

...
# make predictions
yhats = [model.predict(testX) for model in models]
yhats = array(yhats)
# sum across ensembles
summed = numpy.sum(yhats, axis=0)
# argmax across classes
outcomes = argmax(summed, axis=1)

對於多分類的情況,可以使用MLP等神經網絡。

# define model
model = Sequential()
model.add(Dense(15, input_dim=2, activation='relu'))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=200, verbose=0)
# evaluate the model
_, train_acc = model.evaluate(trainX, trainy, verbose=0)
_, test_acc = model.evaluate(testX, testy, verbose=0)

參考:
https://machinelearningmastery.com/ensemble-methods-for-deep-learning-neural-networks/
https://machinelearningmastery.com/model-averaging-ensemble-for-deep-learning-neural-networks/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章