您的位置:首頁>正文

教程|從零開始,瞭解元學習

本文介紹了元學習, 一個解決「學習如何學習」的問題。

元學習是目前機器學習領域一個令人振奮的研究趨勢, 它解決的是學習如何學習的問題。

傳統的機器學習研究模式是:獲取特定任務的大型資料集, 然後用這個資料集從頭開始訓練模型。 很明顯, 這和人類利用以往經驗, 僅僅通過少量樣本就迅速完成學習的情況相差甚遠。

因為人類學習了“如何學習”。

在這篇文章中, 我將從一個非常直觀的元學習簡介入手, 從它最早的起源一直談到如今的元學習研究現狀。 然後, 我會從頭開始, 在PyTorch中實現一個元學習模型,

同時會分享一些從該項目中學到的經驗教訓。

首先, 什麼是學習?

我們先來簡單瞭解一下, 當我們訓練一個用來實現貓狗圖像分類的簡單神經網路時, 到底發生了什麼。 假設我們現在有一張貓的圖像, 以及對應的表示“這是一隻貓”的標籤。 為簡潔起見, 我做了一個簡單的動畫來展示訓練的過程。

反向傳播是神經網路訓練中很關鍵的一步。 因為神經網路執行的計算和損失函數都是可微函數, 因此我們能夠求出網路中每一個參數所對應的梯度, 進而減少神經網路當前給出的預測標籤與真實/目標標籤之間的差異(這個差異是用損失函數度量的)。 在反向傳播完成後, 就可以使用優化器來計算模型的更新參數了。

而這正是使神經網路的訓練更像是一門“藝術”而不是科學的原因:因為有太多的優化器和優化設置(超參數)可供選擇了。

我們把該“單個訓練步”放在一張圖中展示, 如下所示:

現在, 訓練圖像是一隻, 表示圖像是一隻貓的標籤是 。 最大的這些 △ 表示我們的神經網路, 裡面的 ■ 表示參數和梯度, 標有L的四邊形表示損失函數, 標有O的四邊形表示優化器。

完整的學習過程就是不斷地重複這個優化步, 直到神經網路中的參數收斂到一個不錯的結果上。

上圖表示神經網路的訓練過程的三步, 神經網路(用最大的 △ 表示)用於實現貓狗圖像分類。

元學習

元學習的思想是學習“學習(訓練)”過程。

元學習有好幾種實現方法,

不過本文談到的兩種“學習‘學習’過程”的方法和上文介紹的方式很類似。

在我們的訓練過程中, 具體而言, 可以學習到兩點

神經網路的初始參數(圖中的藍色■);

優化器的參數(粉色的★)。

我會介紹將這兩點結合的情況, 不過這裡的每一點本身也非常有趣, 而且可獲得到簡化、加速以及一些不錯的理論結果。

現在, 我們有兩個部分需要訓練:

用“模型(M)”這個詞來指代我們之前的神經網路, 現在也可以將其理解為一個低級網路。 有時, 人們也會用“優化物件(optimizee)”或者“學習器(learner)”來稱呼它。 該模型的權重在圖中用 ■ 表示。

用“優化器(O)”或者“元學習器”來指代用于更新低級網路(即上述模型)權重的高級模型。 優化器的權重在圖中用 ★ 表示。

如何學習這些元參數?

事實上, 我們可以將訓練過程中的元損失的梯度反向傳播到初始的模型權重和/或優化器的參數。

現在, 我們有了兩個嵌套的訓練過程:優化器/元學習器上的元訓練過程, 其中(元)前向傳輸包含模型的多個訓練步:我們之前見過的前饋、反向傳播以及優化步驟。

現在我們來看看元訓練的步驟:

元訓練步(訓練優化器 O)包含3個模型(M)的訓練步。

在這裡, 元訓練過程中的單個步驟是橫向表示的。 它包含模型訓練過程中的兩個步驟(在元前饋和元反向傳播的方格中縱向表示), 模型的訓練過程和我們之前看到的訓練過程完全一樣。

可以看到, 元前向傳輸的輸入是在模型訓練過程中依次使用的一列樣本/標籤(或一列批次)。

元訓練步中的輸入是一列樣本(、)及其對應的標籤(、)。

我們應該如何使用元損失來訓練元學習器呢?在訓練模型時, 我們可以直接將模型的預測和目標標籤做比較, 得到誤差值。

在訓練元學習器時, 我們可以用元損失來度量元學習器在目標任務——訓練模型——上的表現。

一個可行的方法是在一些訓練資料上計算模型的損失:損失越低,模型就越好。最後,我們可以計算出元損失,或者直接將模型訓練過程中已經計算得到的損失結合在一起(例如,把它們直接加起來)。

我們還需要一個元優化器來更新優化器的權重,在這裡,問題就變得很“meta”了:我們可以用另一個元學習器來優化當前的元學習器……不過最終,我們需要人為選擇一個優化器,例如SGD或者ADAM(不能像“turtles all the way down”一樣(注:turtles all the way down這裡大概是說,“不能一個模型套一個模型,這樣無限的套下去”)。

這裡給出一些備註,它們對於我們現在要討論的實現而言非常重要:

二階導數:將元損失通過模型的梯度進行反向傳播時,需要計算導數的導數,也就是二階導數(在最後一個動畫中的元反向傳播部分,這是用綠色的 ▲ 穿過綠色的 ■ 來表示的)。我們可以使用 TensorFlow 或 PyTorch 等現代框架來計算二階導數,不過在實踐中,我們通常不考慮二階導數,而只是通過模型權重進行反向傳播(元反向傳播圖中的黃色 ■),以降低複雜度。

座標共用:如今,深度學習模型中的參數數量非常多(在NLP任務中,很容易就有將近3000萬 ~2億個參數)。當前的GPU記憶體無法將這麼多參數作為單獨輸入傳輸給優化器。我們經常採用的方法是“座標共用”(coordinate sharing),這表示我們為一個參數設計一個優化器,然後將其複製到所有的參數上(具體而言,將它的權重沿著模型參數的輸入維度進行共用)。在這個方法中,元學習器的參數數量和模型中的參數數量之間並沒有函數關係。如果元學習器是一個記憶網路,如RNN,我們依然可以令模型中的每個參數都具有單獨的隱藏狀態,以保留每個參數的單獨變化情況。

一個可行的方法是在一些訓練資料上計算模型的損失:損失越低,模型就越好。最後,我們可以計算出元損失,或者直接將模型訓練過程中已經計算得到的損失結合在一起(例如,把它們直接加起來)。

我們還需要一個元優化器來更新優化器的權重,在這裡,問題就變得很“meta”了:我們可以用另一個元學習器來優化當前的元學習器……不過最終,我們需要人為選擇一個優化器,例如SGD或者ADAM(不能像“turtles all the way down”一樣(注:turtles all the way down這裡大概是說,“不能一個模型套一個模型,這樣無限的套下去”)。

這裡給出一些備註,它們對於我們現在要討論的實現而言非常重要:

二階導數:將元損失通過模型的梯度進行反向傳播時,需要計算導數的導數,也就是二階導數(在最後一個動畫中的元反向傳播部分,這是用綠色的 ▲ 穿過綠色的 ■ 來表示的)。我們可以使用 TensorFlow 或 PyTorch 等現代框架來計算二階導數,不過在實踐中,我們通常不考慮二階導數,而只是通過模型權重進行反向傳播(元反向傳播圖中的黃色 ■),以降低複雜度。

座標共用:如今,深度學習模型中的參數數量非常多(在NLP任務中,很容易就有將近3000萬 ~2億個參數)。當前的GPU記憶體無法將這麼多參數作為單獨輸入傳輸給優化器。我們經常採用的方法是“座標共用”(coordinate sharing),這表示我們為一個參數設計一個優化器,然後將其複製到所有的參數上(具體而言,將它的權重沿著模型參數的輸入維度進行共用)。在這個方法中,元學習器的參數數量和模型中的參數數量之間並沒有函數關係。如果元學習器是一個記憶網路,如RNN,我們依然可以令模型中的每個參數都具有單獨的隱藏狀態,以保留每個參數的單獨變化情況。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示