深度森林原理及實現

目錄

背景

級聯森林

多粒度掃描

代碼

總結


 

背景

深度森林(Deep Forest)是周志華教授和馮霽博士在2017年2月28日發表的論文《Deep Forest: Towards An Alternative to Deep Neural Networks》中提出來的一種新的可以與深度神經網絡相媲美的基於樹的模型,其結構如圖所示。


 

級聯森林

上圖表示gcForest的級聯結構。

每一層都由多個隨機森林組成。通過隨機森林學習輸入特徵向量的特徵信息,經過處理後輸入到下一層。爲了增強模型的泛化能力,每一層選取多種不同類型的隨機森林,上圖給了兩種隨機森林結構,分別爲completely-random tree forests(藍色)和random forests(黑色),每種兩個。其中,每個completely-random tree forests包含1000棵樹,每個節點通過隨機選取一個特徵作爲判別條件,並根據這個判別條件生成子節點,直到每個葉子節點只包含同一類的實例而停止;每個random forests同樣包含1000棵樹,節點特徵的選擇通過隨機選擇√d個特徵(d爲輸入特徵的數量),然後選擇基尼係數最大特徵作爲該節點劃分的條件。

級聯森林的迭代終止條件:迭代到效果不能提升就停止!!!

級聯森林中每個森林是如何決策的呢?

每個森林中都包括好多棵決策樹,每個決策樹都會決策出一個類向量結果(以3類爲例,下面也是),然後綜合所有的決策樹結果,再取均值,生成每個森林的最終決策結果——一個3維類向量!每個森林的決策過程如下圖所示。

這樣,每個森林都會決策出一個3維類向量,回到圖1中,級聯森林中的4個森林就都可以決策出一個3維類向量,然後對4個*3維類向量取均值,最後取最大值對應的類別,作爲最後的預測結果!

 

多粒度掃描

多粒度掃描是爲了增強級聯森林,爲了對特徵做更多的處理的一種技術手段,具體掃描過程如下圖所示。

上圖表示對輸入特徵使用多粒度掃描的方式產生級聯森林的輸入特徵向量。

對於400維的序列數據,採用100維的滑動窗對輸入特徵進行處理,得到301(400 - 100 + 1)個100維的特徵向量。對於20×20的圖像數據,採用10×10的滑動窗對輸入特徵進行處理,得到121((20-10+1)*(20-10+1))個10×10的二維特徵圖。然後將得到的特徵向量(或特徵圖)分別輸入到一個completely-random tree forest和一個random forest中(不唯一,也可使用多個森林),以三分類爲例,會得到301(或121)個3維類分佈向量,將這些向量進行拼接,得到1806(或726)維的特徵向量。

 

第一步:使用多粒度掃描對輸入特徵進行預處理。以使用三個尺寸的滑動窗爲例,分別爲100-dim,200-dim和300-dim。輸入數據爲400-dim的序列特徵,使用100-dim滑動窗會得到301個100-dim向量,然後輸入到一個completely-random tree forest和一個random forest中,兩個森林會分別得到的301個3-dim向量(3分類),將兩個森林得到的特徵向量進行拼接,會得到1806-dim的特徵向量。同理,使用200-dim和300-dim滑動窗會分別得到1206-dim和606-dim特徵向量。

第二步:將得到的特徵向量輸入到級聯森林中進行訓練。首先使用100-dim滑動窗得到的1806-dim特徵向量輸入到第一層級聯森林中進行訓練,得到12-dim的類分佈向量(3分類,4棵樹)。然後將得到的類分佈向量與100-dim滑動窗得到的特徵向量進行拼接,得到1818-dim特徵向量,作爲第二層的級聯森林的輸入數據;第二層級聯森林訓練得到的12-dim類分佈向量再與200-dim滑動窗得到的特徵向量進行拼接。作爲第三層級聯森林的輸入數據;第三層級聯森林訓練得到的12-dim類分佈向量再與300-dim滑動窗得到的特徵向量進行拼接,做爲下一層的輸入。一直重複上述過程,直到驗證收。

 

代碼:

去GitHub上下載源碼放在自己python文件夾下的site-packages裏面

from gcforest.gcforest import GCForest

運行沒有報錯,即安裝成功

參數配置

#訓練的配置,採用默認的模型-即原庫代碼實現方式
def get_toy_config():
    config = {}
    ca_config = {}
    ca_config["random_state"] = 0  # 0 or 1
    ca_config["max_layers"] = 100 # 最大的層數,layer對應論文中的level
    ca_config["early_stopping_rounds"] = 3 #如果出現某層的三層以內的準確率都沒有提升,層中止
    ca_config["n_classes"] = 2 #判別的類別數量
    ca_config["estimators"] = []
    
    ca_config["estimators"].append({"n_folds": 2, "type": "RandomForestClassifier", "n_estimators": 10, "max_depth": None, "n_jobs": -1})
    ca_config["estimators"].append({"n_folds": 2, "type": "ExtraTreesClassifier", "n_estimators": 10, "max_depth": None, "n_jobs": -1})
    ca_config["estimators"].append({"n_folds": 2, "type": "LogisticRegression"})
    config["cascade"] = ca_config #共使用了3個基學習器
    return config

本文只選擇了三個模型,沒有使用xgboost【xgboost輸入格式更加嚴格,需要調試】

config=get_toy_config()
gc = GCForest(config)
#X_train_enc是每個模型最後一層輸出的結果,每一個類別的可能性
X_train_enc = gc.fit_transform(data, label)
y_pred = gc.predict(X_test)
acc = accuracy_score(y_test, y_pred)

Test Accuracy of GcForest = 82.84 %

可以使用gcForest得到的X_enc數據進行其他模型的訓練比如xgboost/RF

clf = RandomForestClassifier(n_estimators=1000, max_depth=None, n_jobs=-1)
clf.fit(X_train_enc, label)
y_pred = clf.predict(X_test_enc)
acc1 = accuracy_score(y_test, y_pred)
print("Test Accuracy of Other classifier using gcforest's X_encode = {:.2f} %".format(acc1 * 100))

Test Accuracy of Other classifier using gcforest's X_encode = 79.48 %

完整代碼放在GitHub上:https://github.com/Andyszl/Recommendation_algorithm/blob/master/gcForest.py

 

總結

相比深度神經網絡,gcForest有如下若干有點:

1. 容易訓練,計算開銷小
2.天然適用於並行的部署,效率高
3. 超參數少,模型對超參數調節不敏感,並且一套超參數可使用到不同數據集
4.可以適應於不同大小的數據集,模型複雜度可自適應伸縮
5. 每個級聯的生成使用了交叉驗證,避免過擬合
6. 在理論分析方面也比深度神經網絡更加容易。

 


 

參考:

官方開源地址:https://github.com/kingfengji/gcForest

https://blog.csdn.net/zzc15806/article/details/80674992 

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