使用PyTorch進行主動遷移學習:讓模型預測自身的錯誤
機器學習模型可以用來預測自身的錯誤,因此相信在未來,未標記的數據點以后會被正確地標記,而不是被定為錯誤。本文詳細說明主動遷移學習, 它是主動學習和遷移學習技術的結合,本文將實現書籍 Human-in-the-Loop Machine Learning 中的所有用到 PyTorch 的方法。
寫在開始之前
在我之前為 PyTorch 撰寫的文章《Active Learning with PyTorch》中,我介紹了主動學習的構建模塊。如果你不熟悉主動學習,你可以從這里開始了解,也可以看看我關于兩種主動學習——不確定性抽樣和多樣性抽樣的文章,以及相關的主動學習技術來將知識串聯起來:
在我的免費 PyTorch 庫中,也有所有主動學習算法的相關例子,包括本文中介紹的新算法:
理想情況下,你應該在接觸本文中更高級的方法之前,親自嘗試實現更簡單的主動學習策略。
什么是遷移學習?
遷移學習是將為一個特定任務建立的機器學習模型應用于另一個任務的過程。
「我們要去的地方不需要道路」。機械遷移學習:一輛車可以被改造成一臺時間機器,或者一艘船 (圖片來源:SF Chronicle)
將技術從一個用例調整到另一個用例是很有趣的。我永遠不會忘記,有一天,當我在 San Francisco 附近透過火車車窗看到一輛汽車在 Brisbane Lagoon 的水里與火車相撞時的激動心情。
每當為一個特定目的而構建的機器學習模型適應于一個全新的用例時,你都可以感受到同樣的喜悅。如果這個用例碰巧是主動學習,那么我們將把機器學習中最有趣的部分應用到解決機器學習中最重要的問題中:人類和人工智能如何一起解決問題?
在當前的機器學習中,遷移學習通常是指獲取一個現有的神經模型,然后對最后一層 (或最后幾層) 進行再訓練,以完成新的任務,它可以表示為:
遷移學習的一個例子。模型預測標簽為「a」、「B」、「C」或「D」,單獨的數據集標簽為「W」、「X」、「Y」和「Z」。再訓練模型的最后一層模型現在能夠預測標簽「W」、「X」、「Y」和「Z」。
遷移學習的最大優點是,與從頭開始訓練一個模型相比,你需要更少的人工標記的示例,這意味著你可以用更少的數據獲得更高精度的模型。如果你有計算機視覺背景,你可能已經用遷移學習來適應一個來自 ImageNet 分類任務的模型;如果你有自然語言處理背景,你可能已經用遷移學習來適應一個像 BERT 這樣的預先訓練過的模型。
讓你的模型預測它自己的錯誤
遷移學習的新標簽可以是任何你想要的類別,這包括任務本身的信息!這是主動遷移學習三個核心觀點中的第一個:
觀點 1:你可以使用遷移學習,通過讓你的模型預測自己的錯誤,來發現模型哪里被混淆了。
這篇文章涵蓋了三種主動遷移學習的變體,最簡單的一種是二進制的「correct/incorrect」任務,用來預測模型可能在哪里出錯:
不確定性抽樣的主動遷移學習。驗證項由模型預測,并根據分類是否正確將其劃分為「incorrect」或「incorrect」。然后對模型的最后一層進行重新訓練,以預測項目是「correct」還是「incorrect」,從而有效地將兩個 bucket 轉換為新的標簽。
這個過程有三個步驟:
將模型應用于驗證數據集,并捕獲哪些驗證項被正確分類了,哪些被錯誤分類了。這是你的新的訓練數據:你的驗證項現在有一個附加的「correct」或「incorrect」標簽。
為模型創建一個新的輸出層,并在新的訓練數據上訓練這個新層,預測新的「correct」/「incorrect」標簽。
在新模型中運行未標記的數據項,并對預測為「不正確」的數據項進行抽樣,這是最可靠的。
PyTorch 使這一過程變得非常簡單,它能夠將每個神經元的激活傳遞回其他進程,從而使我們能夠在原有模型的基礎上構建我們的主動遷移學習模型。假設我們有一個簡單的網絡,有一個隱含層,使用這個 forward() 函數:
def forward(self, feature_vec, return_all_layers=False):
hidden1 = self.linear1(feature_vec).clamp(min=0)
output = self.linear2(hidden1)
log_softmax = F.log_softmax(output, dim=1)
if return_all_layers:
return [hidden1, output, log_softmax]
else:
return log_softmax
然后我們可以迭代我們的驗證數據,并為每個驗證項分配一個值,即它是「correct」還是「incorrect」,并將其隱含層作為輸入存儲到我們的新模型中:
correct_predictions = [] # validation items predicted correctly
incorrect_predictions = [] # validation items predicted incorrectly
item_hidden_layers = {} # hidden layer of each item, by id
for item in validation_data:
# assume "item" contains id, label & features of each data point
id = item["id"]
label = item["label"]
feature_vector = item["feature_vector"]
hidden, logits, log_probs = model(feature_vector, True)
item_hidden_layers[id] = hidden # record hidden layer value
if is_correct(label, log_probs):
correct_predictions.append(item)
else:
incorrect_predictions.append(item)
然后我們可以訓練一個新的模型來預測「correct」或「incorrect」,使用隱藏層作為新的輸入 (特征) 向量。假設我們在代碼中調用了新模型 correct_model。
在這個新模型被訓練之后,唯一棘手的部分是,我們需要從兩個模型中得到未標記數據的預測:第一個預測從第一個模型中得到隱含層,然后第二個預測新的「correct/incorrect」模型:
active_transfer_preds = []
with torch.no_grad(): #A
v=0
for item in unlabeled_data:
id = item["id"]
label = item["label"]
feature_vector = item["feature_vector"]
# get prediction from initial model
hidden, logits, log_probs = model(feature_vector, True)
# get predictions from correct/incorrect model
correct_log_probs = correct_model(hidden, False)
此時,在代碼 correct_log_probs 中有未標記項被正確預測的概率。通過對被正確預測的置信度最低的項進行抽樣,就是對那些本應由人類檢查的應用標簽的項目進行抽樣。
這段代碼是免費 PyTorch 庫中的 advanced_active_learning.py 文件中的代碼的一個稍微簡化的版本:https://github.com/rmunro/pytorch_active_learning/blob/master/advanced_active_learning.py
你可以使用以下命令立即在用例——識別與災難相關的消息上運行它:
python advanced_active_learning.py——transfer_learned_uncertainty = 10
這將運行整個過程,然后給你提供 10 個最不確定的項目,以便你提供正確的標簽。
此時,該模型可能并不比簡單的不確定性抽樣算法更好,因此,首先實現簡單的方法作為基線也是一個好主意。但不要放棄:這是構建更強大的算法的第一步。
比起簡單的方法,我們從遷移學習中獲得的最大優勢是,它使我們的主動學習策略更容易適應。主動學習策略的一個常見問題是,它們會對未標記的項目進行抽樣,這些項目都來自特征空間的一部分,因此缺乏多樣性,因此需要使用像聚類這樣的多樣性抽樣方法來避免這個問題。有一些先進的主動學習技術將不確定性抽樣和多樣性抽樣單獨地結合起來,但是本文中的以下方法具有將這兩者結合成單一架構的優點。
通常情況下,實時的人類標簽很難獲得,更實際的做法是采樣大量未標記的物品,并將其標記為一批。所以在這些情況下,自適應代表性抽樣的主動遷移學習在抽樣過程中是合適的,即使我們還不知道標簽是什么。
代表性抽樣的主動遷移學習
對于許多實際的用例,你的數據會隨著時間而變化。例如,在自動駕駛汽車用例中,總是會遇到新類型的對象,并且對象的范圍可能會擴大,比如在道路之外的開闊水域駕駛。
代表性抽樣是多樣性抽樣的一種形式,其目的是對與當前機器學習模型的應用領域最相似的未標記項進行抽樣。
因為我們采樣的項目將獲得一個人工標簽,我們可以假設它們是訓練數據的一部分,而不需要知道標簽是什么。
自適應代表性抽樣的主動遷移學習
步驟如下:
從與訓練數據相同的分布中獲取驗證數據,并給它一個「Training」標簽。從我們的目標域獲取未標記的數據,并給它一個「Application」標簽。
訓練一個新的輸出層來預測訓練/應用程序標簽,讓它訪問模型的所有層。
將新模型應用于未標記的數據,并對最有可能被預測為「應用程序」的項目進行抽樣。
假設新抽樣的項目稍后將獲得標簽并成為訓練數據的一部分:將這些項目的標簽從「Application」更改為「training」,然后重復步驟 2。
這是一個非常強大的算法,因為它避免了只對特征空間的一部分進行采樣,在任何人為標記之前對一組不同的項目進行采樣。
觀點 2:即使你還不知道標簽是什么,你也可以假設一個未標記的項目以后會得到一個標簽。
自適應采樣的主動轉遷移學習 (ATLAS)
主動遷移學習最復雜的應用是自適應采樣 (ATLAS) 的主動學習。它綜合了本文中前面兩個模型的原則:在添加任何人工標記之前預測不確定性并適應數據。
我們用時間旅行來對此進行類比。想象一下,你把你的車變成了一臺時間機器,但你必須以每小時 88 英里的速度行駛,才能進行時空旅行。即使你還不知道未來的路會是什么樣子,你也可以把車開到未來。然后,即使沒有充分的知識背景,你也可以考慮汽車將會在哪里,開始制定未來的計劃。
我們可以對我們的模型做同樣的事情,假設我們有數據知識,我們將在以后標記并使用這些知識來采樣更多的數據供人類檢查:
用于自適應采樣的主動遷移學習
步驟如下:
將模型應用于驗證數據集,并捕獲哪些驗證項被正確分類了,哪些被錯誤分類了。這是你的新訓練數據:你的驗證項現在有一個附加的「correct」或「incorrect」標簽。
為模型創建一個新的輸出層,并在新的訓練數據上訓練這個新層,預測新的「correct」/「incorrect」標簽。
在新模型中運行未標記的數據項,并對預測為「incorrect」的數據項進行抽樣,這是最可靠的。
假設新抽樣的項目稍后將得到標簽,并且模型稍后將在對這些項目進行訓練后正確預測這些項目:將這些項目的標簽從「incorrect」更改為「correct」,然后重復步驟 2。
通過結合不確定性采樣和自適應代表性采樣的主動遷移學習技術,我們現在有了一個可以預測其未來狀態的模型。它不知道最初采樣的項目的標簽是什么,但它知道它們會得到一個標簽,然后它可以根據預期的未來事件做出更明智的抽樣決策。
觀點 3:你可以假設模型將正確預測未標記項的標簽,這些項和稍后將獲得標簽的項一樣,即使你還不知道標簽是什么。
此代碼與上述文件位于同一個免費 Pythorch 庫中的 advanced_active_learning.py 相同:https://github.com/rmunro/Pythorch_active_learning/blob/master/advanced_active_learning.py
你可以使用以下命令行運行它:
python advanced_active_learning.py --atlas=10
主動遷移學習備忘單
這是一個單頁的備忘單,你可以在構建本文中的算法時參考它:
主動遷移學習備忘單
如果你要開始學習這本書,以下有一些注意事項:
這本書中的方法在數學上相當于刪除最后一層并重新訓練一個新層(如上圖所示),或者取而代之的是從最后一個隱藏層獲取輸出并將其用作新模型的輸入(如代碼示例中所示)。我認為前者在視覺上更直觀,但后者不太容易出錯,因為它是純粹的加法,你不必擔心更改模型會對代碼的其他部分產生什么影響。如果你更喜歡在自己的代碼中實現遷移學習,那就沒問題了。如果你想用新的數據/標簽來調整現有的層,而不是完全移除層,那么這也是正確的。
注意,代表性采樣的示例使用所有隱藏層,并且還添加了額外的新層,而不確定性采樣和 ATLAS 示例是在最終隱藏層之后的簡單二進制預測。從設計上來說,這是架構的一個良好起點,但是你可以在所有情況下嘗試不同的架構。這背后的原因是,我們模型的最后一層沒有將數據中沒有很好表示的項與數據中很好表示的項區分開來,但是這些項具有與當前狀態下的模型基本無關的特征。因此,代表性抽樣應該更好地利用早期層的信息。相比之下,不確定性采樣和 ATLAS 示例只使用最后一層,因為模型的最后一層已經最小化不確定性,因此在較早的層中不太可能找到更多的信息,如果包含較早的層,則更容易過度擬合。
你可以考慮通過 Monte-Carlo 采樣從單個模型進行多個模型變量預測。這些示例依賴于與你的訓練域來自同一發行版的驗證數據,并且你可以輕松地對該驗證集中的特定項進行過擬合。如果要將訓練數據 90:10 拆分為 training:validation,就像這里的代碼示例一樣,那么一個簡單的方法是對所有 90:10 組合重復此操作。注意,對于不確定性采樣和 ATLAS 示例,你只創建了一個新的二進制預測器,因此不需要太多的數據就可以得到穩健的結果。這是這些模型的一個很好的特性:一個額外的二進制預測很容易用相對較少的數據進行訓練,而且通常不需要手動調整。
主動遷移學習可以用于更復雜的任務,如目標檢測、語義分割、序列標記和文本生成。幾乎任何類型的神經模型都可以添加一個新的層來預測「correct/Incorrect」標簽或「training/application」標簽,因此這是一種非常通用的技術。
- 免責聲明
- 本文所包含的觀點僅代表作者個人看法,不代表新火種的觀點。在新火種上獲取的所有信息均不應被視為投資建議。新火種對本文可能提及或鏈接的任何項目不表示認可。 交易和投資涉及高風險,讀者在采取與本文內容相關的任何行動之前,請務必進行充分的盡職調查。最終的決策應該基于您自己的獨立判斷。新火種不對因依賴本文觀點而產生的任何金錢損失負任何責任。