天天看點

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

目錄:內建學習

  • 一、機器學習中的內建學習
    • 1.1 定義
    • 1.2 分類器(Classifier)
      • 1.2.1 決策樹分類器
      • 1.2.2 樸素貝葉斯分類器
      • 1.2.3 AdaBoost算法
      • 1.2.4 支援向量機
      • 1.2.5 K近鄰算法
    • 1.3 內建學習方法
      • 1.3.1 自助聚合(Bagging)
      • 1.3.2 提升法(Boosting)
        • 1.3.2.1 自适應adaboost
      • 1.3.3 堆疊法(Stacking)
    • 1.4 十折交叉驗證
  • 二、深度學習中的內建學習
    • 2.1 丢棄法Dropout
    • 2.2 測試集資料擴增TTA
    • 2.3 Snapshot

一、機器學習中的內建學習

1.1 定義

內建學習,即分類器內建,通過建構并結合多個學習器來完成學習任務。

一般結構是:先産生一組“個體學習器”,再用某種政策将它們結合起來。

結合政策主要有平均法、投票法和學習法等。

內建學習(ensemble learning)通過建構并結合多個學習器來完成學習任務,有時也被稱為多分類器系統(multi-classifier system)、基于委員會的學習(committee-based learning)。

內建學習是這樣一個過程,按照某種算法生成多個模型,如分類器或者稱為專家,再将這些模型按照某種方法組合在一起來解決某個智能計算問題。

內建學習主要用來提高模型(分類,預測,函數估計等)的性能,或者用來降低模型選擇不當的可能性。

內建算法本身是一種監督學習算法,因為它可以被訓練然後進行預測,組合的多個模型作為整體代表一個假設(hypothesis)。

內建方法是将幾種機器學習技術組合成一個預測模型的元算法,以達到減小方差(bagging)、偏差(boosting) 或改進預測(stacking) 的效果。

1.2 分類器(Classifier)

分類器是資料挖掘中對樣本進行分類的方法的統稱,包含決策樹、邏輯回歸、樸素貝葉斯、神經網絡等算法。分類是資料挖掘的一種非常重要的方法。分類的概念是在已有資料的基礎上學會一個分類函數或構造出一個分類模型(即分類器)。該函數或模型能夠把資料庫中的資料紀錄映射到給定類别中的某一個,進而可以應用于資料預測。

分類器的構造和實施大體會經過以下幾個步驟:

  • 標明樣本(包含正樣本和負樣本),将所有樣本分成訓練樣本和測試樣本兩部分
  • 在訓練樣本上執行分類器算法,生成分類模型
  • 在測試樣本上執行分類模型,生成預測結果
  • 根據預測結果,計算必要的評估名額,評估分類模型的性能

1.2.1 決策樹分類器

構造這個分類器不需要任何領域的知識,也不需要任何的參數設定。是以它特别适合于探測式的知識發現。此外,這個分類器還可以處理高維資料,而且采用的是類似于樹這種形式,也特别直覺和便于了解。是以,決策樹是許多商業規則歸納系統的基礎。

1.2.2 樸素貝葉斯分類器

樸素貝葉斯分類器是假設資料樣本特征完全獨立,以貝葉斯定理為基礎的簡單機率分類器。

1.2.3 AdaBoost算法

AdaBoost算法的自适應在于前一個分類器産生的錯誤分類樣本會被用來訓練下一個分類器,進而提升分類準确率,但是對于噪聲樣本和異常樣本比較敏感。

1.2.4 支援向量機

支援向量機是用過建構一個或者多個高維的超平面來将樣本資料進行劃分,超平面即為樣本之間的分類邊界。

1.2.5 K近鄰算法

基于k近鄰的K個樣本作為分析進而簡化計算提升效率,K近鄰算法分類器是基于距離計算的分類器。

1.3 內建學習方法

內建學習有許多內建模型,例如自助法、自助聚合(Bagging)、随機森林、提升法(Boosting)、 堆疊法(stacking) 以及許多其它的基礎內建學習模型。

內建方法的思想是通過将這些個體學習器(個體學習器稱為“基學習器”,基學習器也被稱為弱學習器。)的偏置和/或方差結合起來,進而建立一個 強學習器(或 內建模型),進而獲得更好的性能。

我們可以用三種主要的旨在組合弱學習器的元算法:

  • 自助聚合(Bagging),該方法通常考慮的是同質弱學習器,互相獨立地并行學習這些弱學習器,并按照某種确定性的平均過程将它們組合起來
  • 提升法(Boosting),該方法通常考慮的也是同質弱學習器。它以一種高度自适應的方法順序地學習這些弱學習器(每個基礎模型都依賴于前面的模型),并按照某種确定性的政策将它們組合起來
  • 堆疊法(Stacking),該方法通常考慮的是異質弱學習器,并行地學習它們,并通過訓練一個 元模型 将它們組合起來,根據不同弱模型的預測結果輸出一個最終的預測結果

非常粗略地說,我們可以說Bagging的重點在于獲得一個方差比其組成部分更小的內建模型,而Boosting和Stacking則将主要生成偏置比其組成部分更低的強模型(即使方差也可以被減小)。

1.3.1 自助聚合(Bagging)

在并行化的方法 中,我們單獨拟合不同的學習器,是以可以同時訓練它們。最著名的方法是自助聚合(Bagging),它的目标是生成比單個模型更棒的內建模型。Bagging的方法實作。

自助法:這種統計技術先随機抽取出作為替代的 B B B個觀測值,然後根據一個規模為 N N N的初始資料集生成大小為 B B B的樣本(稱為自助樣本)。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

在某些假設條件下,這些樣本具有非常好的統計特性:在一級近似中,它們可以被視為是直接從真實的底層(并且往往是未知的)資料分布中抽取出來的,并且彼此之間互相獨立。是以,它們被認為是真實資料分布的代表性和獨立樣本(幾乎是獨立同分布的樣本)。

為了使這種近似成立,必須驗證兩個方面的假設:

  • 初始資料集的大小N應該足夠大,以捕獲底層分布的大部分複雜性。這樣,從資料集中抽樣就是從真實分布中抽樣的良好近似(代表性)
  • 與自助樣本的大小B相比,資料集的規模N應該足夠大,這樣樣本之間就不會有太大的相關性(獨立性)。注意,接下來我可能還會提到自助樣本的這些特性(代表性和獨立性),但讀者應該始終牢記:這隻是一種近似

舉例而言,自助樣本通常用于評估統計估計量的方差或置信區間。根據定義,統計估計量是某些觀測值的函數。是以,随機變量的方差是根據這些觀測值計算得到的。為了評估這種估計量的方差,我們需要對從感興趣分布中抽取出來的幾個獨立樣本進行估計。

在大多數情況下,相較于實際可用的資料量來說,考慮真正獨立的樣本所需要的資料量可能太大了。然而,我們可以使用自助法生成一些自助樣本,它們可被視為最具代表性以及最具獨立性(幾乎是獨立同分布的樣本)的樣本。這些自助樣本使我們可以通過估計每個樣本的值,近似得到估計量的方差。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

1.3.2 提升法(Boosting)

在順序化的方法中,組合起來的不同弱模型之間不再互相獨立地拟合。其思想是疊代地拟合模型,使模型在給定步驟上的訓練依賴于之前的步驟上拟合的模型。提升法(Boosting) 是這些方法中最著名的一種,它生成的內建模型通常比組成該模型的弱學習器偏置更小。

Boosting和Bagging的工作思路是一樣的:我們建構一系列模型,将它們聚合起來得到一個性能更好的強學習器。然而,與重點在于減小方差的Bagging不同,Boosting着眼于以一種适應性很強的方式順序拟合多個弱學習器:序列中每個模型在拟合的過程中,會更加重視那些序列中之前的模型處理地很糟糕的觀測資料。

直覺地說,每個模型都把注意力集中在目前最難拟合的觀測資料上。這樣一來,在這個過程的最後,我們就獲得了一個具有較低偏置的強學習器(我們會注意到,Boosting也有減小方差的效果)。和Bagging 一樣,Boosting也可以用于回歸和分類問題。由于其重點在于減小偏置,用于Boosting 的基礎模型通常是那些低方差高偏置的模型。例如,如果想要使用樹作為基礎模型,我們将主要選擇隻有少許幾層的較淺決策樹。而選擇低方差高偏置模型作為Boosting 弱學習器的另一個重要原因是:這些模型拟合的計算開銷較低(參數化時自由度較低)。實際上,由于拟合不同模型的計算無法并行處理(與Bagging 不同),順序地拟合若幹複雜模型會導緻計算開銷變得非常高。

一旦標明了弱學習器,我們仍需要定義它們的拟合方式和聚合方式。介紹兩個重要的Boosting算法:自适應提升(adaboost)和梯度提升(gradient boosting)。

簡而言之,這兩種元算法在順序化的過程中建立和聚合弱學習器的方式存在差異。自适應提升算法會更新附加給每個訓練資料集中觀測資料的權重,而梯度提升算法則會更新這些觀測資料的值。這裡産生差異的主要原因是:兩種算法解決優化問題(尋找最佳模型——弱學習器的權重和)的方式不同。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

1.3.2.1 自适應adaboost

在自适應adaboost中,我們将內建模型定義為L個弱學習器的權重和:

s L ( . ) = ∑ l = 1 L c l × w l ( . ) s_L(.)=\sum_{l=1}^Lc_l \times w_l(.) sL​(.)=l=1∑L​cl​×wl​(.)

其中 c l c_l cl​為系數, w l w_l wl​為弱學習器。尋找這種最佳內建模型是一個困難的優化問題。是以,我們并沒打算一次性地解決該問題(找到給出最佳整體加法模型的所有系數和弱學習器),而是使用了一種更易于處理的疊代優化過程(即使它有可能導緻我們得到次優解)。

另外,我們将弱學習器逐個添加到目前的內建模型中,在每次疊代中尋找可能的最佳組合(系數、弱學習器)。換句話說,我們循環地将 s l s_l sl​定義如下:

s l ( . ) = s l − 1 ( . ) + c l × w l ( . ) s_l(.)=s_{l-1}(.)+c_l \times w_l(.) sl​(.)=sl−1​(.)+cl​×wl​(.)

其中, c l c_l cl​和 w l w_l wl​被挑選出來,使得 s l s_l sl​是最适合訓練資料的模型,是以這是對 s l − 1 s_{l-1} sl−1​的最佳可能改進。我們可以進一步将其表示為:

( c l , w l ( . ) ) = arg ⁡ c , w ( . ) min ⁡ E ( s l − 1 ( . ) + c × w ( . ) ) = arg ⁡ c , w ( . ) min ⁡ ∑ n = 1 N e ( y n , s l − 1 ( x n ) + c × w ( x n ) ) (c_l,w_l(.))=\arg_{c,w(.)}\min E(s_{l-1}(.)+c\times w(.))\\ =\arg_{c,w(.)}\min \sum_{n=1}^Ne(y_n,s_{l-1}(x_n)+c\times w(x_n)) (cl​,wl​(.))=argc,w(.)​minE(sl−1​(.)+c×w(.))=argc,w(.)​minn=1∑N​e(yn​,sl−1​(xn​)+c×w(xn​))

其中, E ( . ) E(.) E(.)是給定模型的拟合誤差, e ( . , . ) e(.,.) e(.,.)是損失/誤差函數。是以,我們并沒有在求和過程中對所有 L L L個模型進行全局優化,而是通過局部優化來近似最優解并将弱學習器逐個添加到強模型中。

更特别的是,在考慮二分類問題時,我們可以将 adaboost 算法重新寫入以下過程:首先,它将更新資料集中觀測資料的權重,訓練一個新的弱學習器,該學習器重點關注目前內建模型誤分類的觀測資料。其次,它會根據一個表示該弱模型性能的更新系數,将弱學習器添加到權重和中:弱學習器的性能越好,它對強學習器的貢獻就越大。

是以,假設我們面對的是一個二分類問題:資料集中有N個觀測資料,我們想在給定一組弱模型的情況下使用adaboost算法。在算法的起始階段(序列中的第一個模型),所有的觀測資料都擁有相同的權重1/N。然後,我們将下面的步驟重複L次(作用于序列中的L個學習器):

  • 用目前觀測資料的權重拟合可能的最佳弱模型
  • 計算更新系數的值,更新系數是弱學習器的某種标量化評估名額,它表示相對內建模型來說,該弱學習器的分量如何
  • 通過添加新的弱學習器與其更新系數的乘積來更新強學習器計算新觀測資料的權重,該權重表示我們想在下一輪疊代中關注哪些觀測資料(聚和模型預測錯誤的觀測資料的權重增加,而正确預測的觀測資料的權重減小)

重複這些步驟,我們順序地建構出L個模型,并将它們聚合成一個簡單的線性組合,然後由表示每個學習器性能的系數權重。注意,初始adaboost算法有一些變體,比如LogitBoost(分類)或L2Boost(回歸),它們的差異主要取決于損失函數的選擇。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

1.3.3 堆疊法(Stacking)

堆疊法Stacking與Bagging和Boosting主要存在兩方面的差異。首先,堆疊法通常考慮的是異質弱學習器(不同的學習算法被組合在一起),而Bagging和Boosting主要考慮的是同質弱學習器。其次,stacking堆疊法學習用元模型組合基礎模型,而Bagging和Boosting則根據确定性算法組合弱學習器。

正如上文已經提到的,堆疊法的概念是學習幾個不同的弱學習器,并通過訓練一個元模型來組合它們,然後基于這些弱模型傳回的多個預測結果輸出最終的預測結果。

是以,為了建構Stacking模型,我們需要定義兩個東西:想要拟合的L個學習器以及組合它們的元模型。例如,對于分類問題來說,我們可以選擇KNN分類器、logistic回歸和SVM作為弱學習器,并決定學習神經網絡作為元模型。然後,神經網絡将會把三個弱學習器的輸出作為輸入,并傳回基于該輸入的最終預測。是以,假設我們想要拟合由L個弱學習器組成的Stacking內建模型。我們必須遵循以下步驟:

  • 将訓練資料分為兩組
  • 選擇 L 個弱學習器,用它們拟合第一組資料
  • 使 L 個學習器中的每個學習器對第二組資料中的觀測資料進行預測
  • 在第二組資料上拟合元模型,使用弱學習器做出的預測作為輸入

在前面的步驟中,我們将資料集一分為二,因為對用于訓練弱學習器的資料的預測與元模型的訓練不相關。是以,将資料集分成兩部分的一個明顯缺點是,我們隻有一半的資料用于訓練基礎模型,另一半資料用于訓練元模型。

為了克服這種限制,我們可以使用某種k-折交叉訓練方法(類似于 k-折交叉驗證中的做法)。這樣所有的觀測資料都可以用來訓練元模型:對于任意的觀測資料,弱學習器的預測都是通過在k-1折資料(不包含已考慮的觀測資料)上訓練這些弱學習器的執行個體來完成的。換句話說,它會在k-1折資料上進行訓練,進而對剩下的一折資料進行預測。疊代地重複這個過程,就可以得到對任何一折觀測資料的預測結果。這樣一來,我們就可以為資料集中的每個觀測資料生成相關的預測,然後使用所有這些預測結果訓練元模型。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

1.4 十折交叉驗證

由于深度學習模型一般需要較長的訓練周期,如果硬體裝置不允許建議選取留出法,如果需要追求精度可以使用交叉驗證的方法。

十折交叉驗證用來測試算法準确性。将資料集分成十份,輪流将其中九份作為訓練資料,一份作為測試資料,進行試驗。每次試驗都會得出相應的正确率(或差錯率)。十次的結果的正确率(或差錯率)的平均值作為對算法精度的估計,一般還需要進行多次十折交叉驗證(例如十次十折交叉驗證),再求其均值,作為對算法準确性的估計。

下面假設建構了十折交叉驗證,訓練得到十個CNN模型。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

那麼在十個CNN模型可以使用如下方式進行內建:

  • 對預測的結果的機率值進行平均,然後解碼為具體字元
  • 對預測的字元進行投票,得到最終字元

二、深度學習中的內建學習

此外在深度學習中本身還有一些內建學習思路的做法,值得借鑒學習:

  • 丢棄法Dropout
  • 測試集資料擴增TTA
  • Snapshot

2.1 丢棄法Dropout

Dropout可以作為訓練深度神經網絡的一種技巧。在每個訓練批次中,通過随機讓一部分的節點停止工作。同時在預測的過程中讓所有的節點都其作用。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

Dropout經常出現在在先有的CNN網絡中,可以有效的緩解模型過拟合的情況,也可以在預測時增加模型的精度。加入Dropout後的網絡結構如下:

# 定義模型
class SVHN_Model1(nn.Module):
    def __init__(self):
        super(SVHN_Model1, self).__init__()
        # CNN提取特征子產品
        self.cnn = nn.Sequential(
            nn.Conv2d(3, 16, kernel_size=(3, 3), stride=(2, 2)),
            nn.ReLU(),
            nn.Dropout(0.25),
            nn.MaxPool2d(2),
            nn.Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2)),
            nn.ReLU(),
            nn.Dropout(0.25),
            nn.MaxPool2d(2),
        )
        #
        self.fc1 = nn.Linear(32*3*7, 11)
        self.fc2 = nn.Linear(32*3*7, 11)
        self.fc3 = nn.Linear(32*3*7, 11)
        self.fc4 = nn.Linear(32*3*7, 11)
        self.fc5 = nn.Linear(32*3*7, 11)
        self.fc6 = nn.Linear(32*3*7, 11)

    def forward(self, img):
        feat = self.cnn(img)
        feat = feat.view(feat.shape[0], -1)
        c1 = self.fc1(feat)
        c2 = self.fc2(feat)
        c3 = self.fc3(feat)
        c4 = self.fc4(feat)
        c5 = self.fc5(feat)
        c6 = self.fc6(feat)
        return c1, c2, c3, c4, c5, c6
           

2.2 測試集資料擴增TTA

測試集資料擴增(Test Time Augmentation,簡稱TTA)也是常用的內建學習技巧,資料擴增不僅可以在訓練時候用,而且可以同樣在預測時候進行資料擴增,對同一個樣本預測三次,然後對三次結果進行平均。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習
def predict(test_loader, model, tta=10):
   model.eval()
   test_pred_tta = None
   # TTA 次數
   for _ in range(tta):
       test_pred = []

       with torch.no_grad():
           for i, (input, target) in enumerate(test_loader):
               c0, c1, c2, c3, c4, c5 = model(data[0])
               output = np.concatenate([c0.data.numpy(), c1.data.numpy(),
                  c2.data.numpy(), c3.data.numpy(),
                  c4.data.numpy(), c5.data.numpy()], axis=1)
               test_pred.append(output)

       test_pred = np.vstack(test_pred)
       if test_pred_tta is None:
           test_pred_tta = test_pred
       else:
           test_pred_tta += test_pred

   return test_pred_tta
           

2.3 Snapshot

本章的開頭已經提到,假設我們訓練了10個CNN則可以将多個模型的預測結果進行平均。但是加入隻訓練了一個CNN模型,如何做模型內建呢?

在論文Snapshot Ensembles中,作者提出使用cyclical learning rate進行訓練模型,并儲存精度比較好的一些checkopint,最後将多個checkpoint進行模型內建。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

由于在cyclical learning rate中學習率的變化有周期性變大和減少的行為,是以CNN模型很有可能在跳出局部最優進入另一個局部最優。在Snapshot論文中作者通過使用表明,此種方法可以在一定程度上提高模型精度,但需要更長的訓練時間。

【機器學習 & 深度學習】通俗講解內建學習算法一、機器學習中的內建學習二、深度學習中的內建學習

繼續閱讀