您的位置:首頁>科技>正文

新手教程:在新應用中實踐深度學習的最佳建議

選自arXiv

作者:Leslie N. Smith

機器之心編譯

參與:Jane W、黃小天

本報告針對的群體是應用程式的主題專家, 但是在深度學習方面還是新手。 它對希望在沒有用過深度學習演算法的應用軟體上進行深度神經網路嘗試的人群提供了實用建議。

為了使你的專案更易於管理, 我們建議將其分成幾個階段。 對於每個階段, 本報告包含了幫助新手的大量建議和見解。

導語

雖然我的研究重點是深度學習 ( DL ), 但是我發現我越發頻繁地被要求幫助沒有多少深度學習經驗卻想要在其全新應用中嘗試深度學習的團體。 這個 NRL 報告的動機來自於我注意到對所有這些群體的大部分建議和指導是相似的。 因此, 本報告討論了更普遍相關的深度學習應用的方面。

雖然有幾個有用的機器學習最佳實踐建議資源 [1-5], 但與本報告所涉及的深度學習有一些差異。 不過, 我建議讀者閱讀並熟悉這些參考資料,

因為其中包含許多寶貴的資訊。 此外, 有很多關於軟體工程和敏捷方法學(agile methodology)(我認為讀者已經熟悉)的最佳實踐資源(例如 [6,7])。 本報告中最為重要的內容可參見「深度學習」第 11 章「實踐方法論」, 但我在本報告中還討論了該教材未涵蓋的若干因素和見解。

你可以在下面看到, 一個深度學習的應用項目被分為若干個階段。 然而, 在實踐中, 你可能會發現回到較早的階段會更有幫助。 例如, 在階段 3 中找到類比時, 你可能會發現你在第 1 階段未考慮過的新指標。 在項目進行時所有這些最佳實踐都暗示著通過反覆運算返回某個階段以及持續的提升。

階段 1:開始準備

在本報告中, 我假設你是(或可以取得)應用程式的主題專家。

你應該熟悉解決相關問題的文獻和研究, 並瞭解最先進的解決方案和性能水準。 我建議你從一開始考慮這一點, 如果深度學習解決方案是值得的。 你必須考慮現有技術的性能水準很高, 是否值得在本報告中提出的建議下進行逐步改進。 不要因為只是看起來像最新最偉大的方法而進行深度學習。 你還應該考慮你是否有電腦資源, 因為每個訓練一個深度網路的進程可能需要幾天或幾周時間。 我在自己的研究中充分利用了國防部的 HPC 系統。 此外, 你應該考慮機器學習是否合適——請記住, 訓練深度網路需要大量標籤資料, 如階段 2 中所述。

第一步是量化地定義成功的情形。 無論是由人類還是機器完成,

如果它是成功的, 你會看到什麼?這有助於定義你的評估指標。 想想哪些指標很重要?哪些不太重要?你需要指定在本專案成功中發揮作用的所有定量值, 並確定如何權衡其中的每一個的權重。 你還需要為你的指標定義目標;你的目標是否超過了人類的表現?你的目標將強烈影響專案進展。 從數量上瞭解人在這一任務中的表現是什麼將有助於指導你的目標;最先進的技術與人類的表現相比如何?同樣, 瞭解人類如何解決這個任務將提供有關機器如何解決其任務的有價值資訊。

這些指標中的一些也可以用來設計損失函數(loss function), 這有助於指導網路訓練。 不要僅僅使用 softmax / cross 熵/ log, 因為這是最常見的損失函數, 儘管你應該從它們開始。

從定義上看, 你的評估指標是對你的應用程式重要的數量。 準備好將這些指標作為損失函數的加權組成部分進行測試, 以指導訓練(見階段 6)。

儘管你可能出於其強大能力而考慮深度學習, 那麼考慮一下如何使網路的「工作」盡可能簡單。 這是反直覺的, 但由於它是深度網路的力量, 可能會激勵你嘗試。 然而, 網路必須執行的工作越簡單, 訓練越容易, 性能越好。 你(或最先進的技術)目前使用的啟發法/物理學是否可以在這裡使用?可以預處理資料嗎?雖然網路可以學習複雜的關係, 但請記住:「網路工作越簡單, 執行效果就越好」。 所以值得花時間考慮從以前的工作你可以借鑒的內容以及網路需要為你做些什麼。 假設你希望改進物理學高度近似的複雜過程(即「球形牛」情況);你可以選擇將資料登錄深度網路,以便(希望)輸出所需的結果,或者你可以訓練網路以在近似結果中查找更正。後一種方法幾乎肯定會超過前者。另一方面,不要依賴人工努力來定義潛在的啟發法——最稀缺的資源是人力時間,所以讓網路學習它的表徵,而不需要任何固定的人工預處理。

此外,你可能需要記下你對這一最先進的過程的任何假設或期望,因為它將證明自己的效果。

階段 2:準備你的資料

深度學習需要大量的訓練資料。你可能想知道「我需要多少訓練資料」。網路中的參數數量與訓練資料的數量相關。訓練樣本的數量將在第 6 階段限制你的架構選擇。訓練資料越多,網路就越大而準確。因此,訓練資料的數量取決於你在階段 1 中定義的目標。

除了訓練資料之外,你還需要更少的標籤驗證或測試資料。該測試資料應與訓練資料相似但不一樣。網路沒有對測試資料進行訓練,但它用於測試網路的泛化能力。

專案目標也指導訓練資料樣本的選擇。確保訓練資料與任務直接相關,並且它的多樣性足以覆蓋問題空間。研究每個類別的統計資料。例如,類別是否平衡?平衡類別的一個例子是貓與狗,而不平衡的類別是貓與所有其它哺乳動物(如果你的問題本質上是不平衡的,向深度學習專家請教)。

什麼預處理是可能的?你可以零均值並歸一化資料嗎?這使得網路的工作更容易,因為它消除了學習平均值的工作。通過在訓練樣本之間建立更大的相似性,歸一化也使網路的工作更容易。

如上所述,調查是否有辦法使用先驗知識或已知啟發法(heuristic)降低資料的維度。你不需要花時間人工確定啟發法,因為目標是節省人力時間,你可以讓網路學習自己的表徵。只要知道網路必須篩選的無關資料越多,需要的訓練資料就越多,訓練網路的時間就越長。所以充分利用現有的技術。

階段 3:找出你的應用程式與最相近的深度學習應用程式之間的相似點

專家知道不能每個專案都從頭開始。這就是為什麼他們被稱為專家的原因。他們再使用以前的解決方案、搜索其他研究人員的深度學習文獻來解決問題。即使沒有人做過你想做的事情,你仍然需要利用專家的長處。

深度學習已被應用于各種應用。為了創建你的基線模型(baseline model)——即你的起點——你需要找到與你的應用程式相似的應用程式。你應該搜索深度學習文獻,並考慮各種應用程式解決的「問題」與你在應用程式中需要解決的「問題」進行比較。找出這些問題之間的相似之處和類比。此外,請注意你的新應用程式與深度學習應用程式之間的差異,因為這些差異可能需要在階段 6 中更改架構。

有幾種「經典」的深度學習應用程式和眾所周知的解決方案。這些包括圖像分類/物件識別(卷積網路)、處理如語言處理的順序資料(RNN/LSTM/GRU)和複雜的決策制定(深度強化學習)。還有一些常見的其它應用,如圖像分割(image segmentation)和超解析度(super-resolution)(全卷積網路)以及相似匹配(孿生網路/Siamese network)。附錄 A 列出了許多最近的深度學習應用程式和它們使用的架構以及描述應用程式的論文的連結。這些可以提供一些想法,但不應該作為尋找深度學習應用程式的來源。你應該仔細搜索穀歌學術(https://scholar.google.com)和 arXiv(https://arxiv.org)以獲取深度學習的應用程式。

階段 4:創建簡單的基線模型

開始時始終保持簡單、小巧和容易。使用比你預期需要的更小的架構。從共同的目標函數開始,使用超參數的常用設置,僅使用部分訓練資料。這是一個能夠部分實踐敏捷軟體方法論的好地方,如簡單設計、單元測試(unit testing)和簡短發佈(short release)。現在只需要獲得基本功能,並在階段 6 中進行改進。也就是說,計畫小步驟、持續更新、並反覆運算。

只選擇一種常見的框架,如 Caffe、TensorFlow 或 MXnet。計畫僅使用一種框架和一種電腦語言來最大限度地減少由不必要複雜度帶來的錯誤。選擇框架和語言可能會受到在階段 3 中執行的複製工作的驅動。

如果網路將成為較大的框架的一部分,那麼這裡是檢查框架 API 正常工作的好地方。

階段 5:創建視覺化和調試工具

瞭解模型中發生的情況將會影響專案的成功。木匠有一個說法「測量兩次,切割一次」。你應該「編碼一次,測量兩次」。除了評估輸出外,你還應該視覺化你的架構並測量內部實體(internal entity),以瞭解為什麼獲得這樣的結果。離開模型診斷,你將很難解決問題或提高性能。

你應該對與高偏差(收斂於錯誤的結果)對高方差(收斂差)相關的問題有一個一般的瞭解,因為每種類型的問題都有不同的解決方案;例如,你可能會用更大的網路修復高偏差問題,但是你可以通過增加訓練資料集的大小來處理高方差問題。

視覺化你的模型,以便你可以盡可能多地監視架構的進化過程。在可能的情況下,為每次代碼修改設置單元測試(unit test)。你應該將訓練錯誤與測試錯誤進行比較,並將兩者與人工表現進行比較。你可能會發現你的網路會表現得很奇怪,你需要確定架構進化中發生的事情以及原因。首先開始調試最差的問題。瞭解問題是否與訓練資料、架構或損失函數有關。

請記住,誤差分析會試圖解釋當前性能與完美性能之間的差異。銷蝕分析(ablative analysis)試圖解釋一些基線表現與當前表現之間的差異。使用一種或另一種或兩種分析可能是有用的。

使用 TensorFlow 作為框架的一個動機是它有一個名為 TensorBoard 的視覺化系統,它是框架的一部分。你可以從 TensorFlow 輸出必要的檔,TensorBoard 可用於視覺化你的架構,並監控權重和特徵映射(feature map),探索網路創建的嵌入空間(embedded space)。因此,在框架中可用調試和視覺化工具。如果使用其它框架,你需要找到這些工具(通常可以線上獲得)或創建自己的工具。

階段 6:微調你的模型

這個階段可能需要大部分時間。你應該廣泛地實驗。並且不要僅使用你認為會改善結果的因素,而是嘗試改變每一個因素以學習當其變化時發生了什麼。改變架構設計、深度、寬度、路徑、權重初始化、損失函數等。更改每個超參數,瞭解提高或降低數值時的效果。我建議使用學習速率範圍測試(learning rate range test)[12] 瞭解你的網路在不同學習速率下的行為。可以進行類似的程式來研究其它超參數的影響。

嘗試各種正則化方法,如數據增強(augmentation)、dropout 和權重衰減。泛化(generalization)是深度網路的關鍵優勢之一,所以一定要測試正則化方法,以便最大限度地提高概括不可見情況的能力。

你應該測試損失函數。你在基線中使用了簡單的損失函數,但也創建了多個你關心並達到(定義)成功的評估指標。評估指標和損失函數之間的唯一差異在於用於測試資料的測量指標和用於訓練網路的訓練資料的損失函數。更複雜的損失函數可以產生更成功的結果嗎?你可以向損失函數添加加權項,以反映每個指標對結果的重要性。但是要非常小心,不要因不重要的標準而使損失函數複雜化,因為它是你模型的核心。

早些時候,你發現應用程式與現有的深度學習應用程式之間的類比,並選擇最接近的作為你的基線。現在比較第二個或第三個最接近的應用程式。如果你按照另一個類比並使用該架構,會發生什麼?你能設想結合兩者來測試嗎?

一開始,你應該從一些容易的取得成功。隨著你不斷深入,提高性能將變得更加困難。你在階段 1 中定義的目標將決定你希望的性能改進的程度。或者你可能想要修改之前定義的目標。

階段 7:端到端訓練、集成與其他複雜度

如果你有時間和預算,你可以探索更複雜的方法,實際上有很多複雜的方法可供選擇。有大量深度學習的文獻,每天都在出現更多的論文。大多數這些論文以一種或另一種方式宣佈了新的最先進的結果,有些可能説明你提升性能。這個部分可以單獨作為一份長的報告,因為有這麼多架構和其它選擇可以考慮,但如果你處於這個階段,請考慮與具有大量深度學習專長的人交談,因為在這個階段的建議可能對你的應用程式是獨一無二的。

但是,你可能會考慮兩種常用的方法:端到端的訓練和集成。

作為一般規則,連接系統的端到端訓練將優於具有多個部分的系統,因為具有端到端訓練的組合系統允許每個部分獨立適應任務。因此,如果與你的應用相關,考慮這些組合的部分是有用的。

各種學習器的集合(即裝袋(bagging)、提升(boosting)、堆疊(stacking))也可以提高單個模型的性能。但是,這將需要你訓練和維護集合中的所有學習器。如果你的性能目標值得這樣做,那麼值得測試一個集合的方法。

總結

當你在以前沒有使用過深度學習的應用程式上實驗時,本報告為你提供了許多因素作為參考。並不是每個項目都與這些因素相關,但我希望本文能涵蓋在項目期間你應該考慮的大多數因素。祝你成功。

假設你希望改進物理學高度近似的複雜過程(即「球形牛」情況);你可以選擇將資料登錄深度網路,以便(希望)輸出所需的結果,或者你可以訓練網路以在近似結果中查找更正。後一種方法幾乎肯定會超過前者。另一方面,不要依賴人工努力來定義潛在的啟發法——最稀缺的資源是人力時間,所以讓網路學習它的表徵,而不需要任何固定的人工預處理。

此外,你可能需要記下你對這一最先進的過程的任何假設或期望,因為它將證明自己的效果。

階段 2:準備你的資料

深度學習需要大量的訓練資料。你可能想知道「我需要多少訓練資料」。網路中的參數數量與訓練資料的數量相關。訓練樣本的數量將在第 6 階段限制你的架構選擇。訓練資料越多,網路就越大而準確。因此,訓練資料的數量取決於你在階段 1 中定義的目標。

除了訓練資料之外,你還需要更少的標籤驗證或測試資料。該測試資料應與訓練資料相似但不一樣。網路沒有對測試資料進行訓練,但它用於測試網路的泛化能力。

專案目標也指導訓練資料樣本的選擇。確保訓練資料與任務直接相關,並且它的多樣性足以覆蓋問題空間。研究每個類別的統計資料。例如,類別是否平衡?平衡類別的一個例子是貓與狗,而不平衡的類別是貓與所有其它哺乳動物(如果你的問題本質上是不平衡的,向深度學習專家請教)。

什麼預處理是可能的?你可以零均值並歸一化資料嗎?這使得網路的工作更容易,因為它消除了學習平均值的工作。通過在訓練樣本之間建立更大的相似性,歸一化也使網路的工作更容易。

如上所述,調查是否有辦法使用先驗知識或已知啟發法(heuristic)降低資料的維度。你不需要花時間人工確定啟發法,因為目標是節省人力時間,你可以讓網路學習自己的表徵。只要知道網路必須篩選的無關資料越多,需要的訓練資料就越多,訓練網路的時間就越長。所以充分利用現有的技術。

階段 3:找出你的應用程式與最相近的深度學習應用程式之間的相似點

專家知道不能每個專案都從頭開始。這就是為什麼他們被稱為專家的原因。他們再使用以前的解決方案、搜索其他研究人員的深度學習文獻來解決問題。即使沒有人做過你想做的事情,你仍然需要利用專家的長處。

深度學習已被應用于各種應用。為了創建你的基線模型(baseline model)——即你的起點——你需要找到與你的應用程式相似的應用程式。你應該搜索深度學習文獻,並考慮各種應用程式解決的「問題」與你在應用程式中需要解決的「問題」進行比較。找出這些問題之間的相似之處和類比。此外,請注意你的新應用程式與深度學習應用程式之間的差異,因為這些差異可能需要在階段 6 中更改架構。

有幾種「經典」的深度學習應用程式和眾所周知的解決方案。這些包括圖像分類/物件識別(卷積網路)、處理如語言處理的順序資料(RNN/LSTM/GRU)和複雜的決策制定(深度強化學習)。還有一些常見的其它應用,如圖像分割(image segmentation)和超解析度(super-resolution)(全卷積網路)以及相似匹配(孿生網路/Siamese network)。附錄 A 列出了許多最近的深度學習應用程式和它們使用的架構以及描述應用程式的論文的連結。這些可以提供一些想法,但不應該作為尋找深度學習應用程式的來源。你應該仔細搜索穀歌學術(https://scholar.google.com)和 arXiv(https://arxiv.org)以獲取深度學習的應用程式。

階段 4:創建簡單的基線模型

開始時始終保持簡單、小巧和容易。使用比你預期需要的更小的架構。從共同的目標函數開始,使用超參數的常用設置,僅使用部分訓練資料。這是一個能夠部分實踐敏捷軟體方法論的好地方,如簡單設計、單元測試(unit testing)和簡短發佈(short release)。現在只需要獲得基本功能,並在階段 6 中進行改進。也就是說,計畫小步驟、持續更新、並反覆運算。

只選擇一種常見的框架,如 Caffe、TensorFlow 或 MXnet。計畫僅使用一種框架和一種電腦語言來最大限度地減少由不必要複雜度帶來的錯誤。選擇框架和語言可能會受到在階段 3 中執行的複製工作的驅動。

如果網路將成為較大的框架的一部分,那麼這裡是檢查框架 API 正常工作的好地方。

階段 5:創建視覺化和調試工具

瞭解模型中發生的情況將會影響專案的成功。木匠有一個說法「測量兩次,切割一次」。你應該「編碼一次,測量兩次」。除了評估輸出外,你還應該視覺化你的架構並測量內部實體(internal entity),以瞭解為什麼獲得這樣的結果。離開模型診斷,你將很難解決問題或提高性能。

你應該對與高偏差(收斂於錯誤的結果)對高方差(收斂差)相關的問題有一個一般的瞭解,因為每種類型的問題都有不同的解決方案;例如,你可能會用更大的網路修復高偏差問題,但是你可以通過增加訓練資料集的大小來處理高方差問題。

視覺化你的模型,以便你可以盡可能多地監視架構的進化過程。在可能的情況下,為每次代碼修改設置單元測試(unit test)。你應該將訓練錯誤與測試錯誤進行比較,並將兩者與人工表現進行比較。你可能會發現你的網路會表現得很奇怪,你需要確定架構進化中發生的事情以及原因。首先開始調試最差的問題。瞭解問題是否與訓練資料、架構或損失函數有關。

請記住,誤差分析會試圖解釋當前性能與完美性能之間的差異。銷蝕分析(ablative analysis)試圖解釋一些基線表現與當前表現之間的差異。使用一種或另一種或兩種分析可能是有用的。

使用 TensorFlow 作為框架的一個動機是它有一個名為 TensorBoard 的視覺化系統,它是框架的一部分。你可以從 TensorFlow 輸出必要的檔,TensorBoard 可用於視覺化你的架構,並監控權重和特徵映射(feature map),探索網路創建的嵌入空間(embedded space)。因此,在框架中可用調試和視覺化工具。如果使用其它框架,你需要找到這些工具(通常可以線上獲得)或創建自己的工具。

階段 6:微調你的模型

這個階段可能需要大部分時間。你應該廣泛地實驗。並且不要僅使用你認為會改善結果的因素,而是嘗試改變每一個因素以學習當其變化時發生了什麼。改變架構設計、深度、寬度、路徑、權重初始化、損失函數等。更改每個超參數,瞭解提高或降低數值時的效果。我建議使用學習速率範圍測試(learning rate range test)[12] 瞭解你的網路在不同學習速率下的行為。可以進行類似的程式來研究其它超參數的影響。

嘗試各種正則化方法,如數據增強(augmentation)、dropout 和權重衰減。泛化(generalization)是深度網路的關鍵優勢之一,所以一定要測試正則化方法,以便最大限度地提高概括不可見情況的能力。

你應該測試損失函數。你在基線中使用了簡單的損失函數,但也創建了多個你關心並達到(定義)成功的評估指標。評估指標和損失函數之間的唯一差異在於用於測試資料的測量指標和用於訓練網路的訓練資料的損失函數。更複雜的損失函數可以產生更成功的結果嗎?你可以向損失函數添加加權項,以反映每個指標對結果的重要性。但是要非常小心,不要因不重要的標準而使損失函數複雜化,因為它是你模型的核心。

早些時候,你發現應用程式與現有的深度學習應用程式之間的類比,並選擇最接近的作為你的基線。現在比較第二個或第三個最接近的應用程式。如果你按照另一個類比並使用該架構,會發生什麼?你能設想結合兩者來測試嗎?

一開始,你應該從一些容易的取得成功。隨著你不斷深入,提高性能將變得更加困難。你在階段 1 中定義的目標將決定你希望的性能改進的程度。或者你可能想要修改之前定義的目標。

階段 7:端到端訓練、集成與其他複雜度

如果你有時間和預算,你可以探索更複雜的方法,實際上有很多複雜的方法可供選擇。有大量深度學習的文獻,每天都在出現更多的論文。大多數這些論文以一種或另一種方式宣佈了新的最先進的結果,有些可能説明你提升性能。這個部分可以單獨作為一份長的報告,因為有這麼多架構和其它選擇可以考慮,但如果你處於這個階段,請考慮與具有大量深度學習專長的人交談,因為在這個階段的建議可能對你的應用程式是獨一無二的。

但是,你可能會考慮兩種常用的方法:端到端的訓練和集成。

作為一般規則,連接系統的端到端訓練將優於具有多個部分的系統,因為具有端到端訓練的組合系統允許每個部分獨立適應任務。因此,如果與你的應用相關,考慮這些組合的部分是有用的。

各種學習器的集合(即裝袋(bagging)、提升(boosting)、堆疊(stacking))也可以提高單個模型的性能。但是,這將需要你訓練和維護集合中的所有學習器。如果你的性能目標值得這樣做,那麼值得測試一個集合的方法。

總結

當你在以前沒有使用過深度學習的應用程式上實驗時,本報告為你提供了許多因素作為參考。並不是每個項目都與這些因素相關,但我希望本文能涵蓋在項目期間你應該考慮的大多數因素。祝你成功。

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