1. 程式人生 > >【轉】吳恩達新書《Machine Learning Yearning》翻譯連載_1

【轉】吳恩達新書《Machine Learning Yearning》翻譯連載_1

轉載 微信公眾號 “頂級程式設計師”

 1. 為什麼要學習機器學習策略?

機器學習眾多重要應用的基礎,包括搜尋引擎、垃圾郵件過濾、語音識別、商品推薦等。假設你或者你的團隊正在做機器學習應用專案,同時你想獲得快速進步。你可以從這本書中找到滿意的答案。

示例:建立一個識別含有貓影象的新興公司

你正在建立一個新興公司,該公司將給貓的愛好者提供大量的貓圖片。你計劃使用神經網路來建立一個計算機視覺系統用於識別圖片中的貓。

但不幸的是,你的學習演算法識別準確率不是足夠的好。所以你面臨具大的壓力來提高演算法的識別準確率。你應該做些什麼呢?

你的團隊有許多好的方法,比如:

l 獲得更多的資料:收集更多貓的圖上。

l 收集大量多樣化的訓練集。例如,貓在不同位置的圖片;不同毛色的貓;多種相機設定拍攝的圖片等。

l 通過加大梯度下降的迭代次數,來增加演算法的訓練時間。

l 嘗試更大的神經網路,擁有更多的層、隱藏單元和引數。

l 嘗試更小的神經網路。

l 嘗試增加正則化(比如L2正則)。

l 改變神經網路的架構(啟用函式、隱藏層的數量等)。

如果你能夠從以上方法中選擇一個好的方案,你將打造一個領先的貓圖片識別平臺以及帶領你的公司走向成功。如果你選擇了一個差的方案,你有可能要浪費數月時間。

我們應該怎麼選擇呢?

這本書將告訴你如何選擇。多數的機器學習問題會留下一些線索,而這些線索會告訴你哪些是有用的嘗試,哪些是無用的嘗試。學會使用這些線索將會節約你數月或數年的開發時間。

2. 怎麼使用這本書幫助你的團隊

學習完本書後,你將對如何制定機器學習專案技術方向有一個深刻理解。

你的團隊成員有可能不明白為什麼你會建議某一個具體的方向。或者你想你的團隊能夠定義一個單一數量評估指標,但他們並不信服。你應該如何去說服他們?

這就是設定短章節的原因:這樣你能夠將這些章節打印出來並且提供給你的團隊成員你想要團隊成員知道的1-2內容。

在優先次序上做一些調整,對於你團隊的生產率可能會產生巨大的影響。通過幫助你的團隊做出這樣的變化,我希望你能成為你們團隊的超級英雄。

3. 預備知識和符號約定

如果你已經學習了機器學習課程(比如在Coursera上我的機器學習慕課課程)或你有應用監督學習的經驗,你將能夠很容易明白下面的內容。

假設你熟悉監督學習演算法:使用標識的訓練樣例(x,y),學習一個從x到y的對映函式。監督學習演算法包含線性迴歸、邏輯迴歸和神經網路。機器學習的形式有多種,但是機器學習的主要實際應用都是監督學習。

我將會頻繁提及神經網路(同樣稱為“深度學習”)。你只需要對他們有一個基本瞭解即可。

如果你對在此提到的概念不熟悉,請到Coursera上觀看機器學習課程的前三週視訊。網址:http://ml-class.org

4. 規模推動機器學習的發展

深度學習(神經網路)的許多觀點已經存在了十幾年。為什麼這些觀點現在才得到重視?

有2個最為重要的因素推動了深度學習的發展:

l 大量可用資料。現在人們花費更多的時間使用數字裝置(膝上型電腦、移動裝置)。因此我可以將他們使用數字裝置產生的大量資料用於學習演算法訓練。

l 計算能力提升。僅僅在幾年前,我們才能夠訓練足夠大的神經網路,以利用我們現在擁有的龐大資料量。

具體來講,即使你收集了足夠多的資料,如果還使用傳統演算法(邏輯迴歸)來處理資料,依然會出現“停滯”現象。這就意為著即使你給演算法在多的資料,演算法的學習曲線也會變平,演算法效果不會在有所提升。

傳統演算法似乎不知道如何處理我們現在擁有的所有資料。

如果你在同一個監督學習任務訓練一個小的神經網路(NN),有可能獲得稍微好一點的效果:

這裡所說的“小型神經網路”是指一個神經網路擁有少數的隱藏單元/層/引數。最後,如果你訓練一個大型神經網路,你能夠獲得更好的效能表現。

因此,如果你想得到最好的效能表現,(i)你可以訓練一個非常大的神經網路,它效能表現將位於綠色曲線的上方;(ii)擁有更多的資料。

還有許多其它的細節(比如神經網路的結構)也是非常重要的,這些方面也有很多的創新。現階段提升演算法的效能最可靠的方法仍然是(i)訓練更大的網路和(ii)獲得更多的資料。

怎樣實現(i)和(ii)是非常複雜的。這本書將會詳細討論這些細節。我們將從對傳統學習演算法和神經網路都有用的一般策略開始,並建立對構建深度學習系統的最先進策略。

5. 你的開發集和測試集

讓我們回顧一下前面講過的貓影象例子:你開發了一款移動APP,使用者可以將多種型別的圖片上傳到APP。你希望APP能夠自動篩選貓的圖片。

你的團隊擁有一個龐大的訓練集,而這個訓練集是通過下載不同網站上含有貓的圖片(正樣本)和不含有貓的圖片(負樣本)組成。他們將該訓練集按照70%作為訓練集、30%作為測試集進行分割。使用這個資料,他們構建了一個在訓練集和測試集都表現很好的貓識別演算法。

但是當你將這個識別演算法部署到移動APP時,你會發現識別演算法表現非常差。

為什麼會這樣?

你發現使用者上傳的圖片與你從網站上下載的作為訓練集的圖片有些不同:使用者使用手機拍攝的圖片解析度低、模糊和光線較差。由於你們訓練集/測試集資料都來自於網站,而你的演算法對於手機拍攝的圖片缺乏較好的泛化能力。

在大資料時代之前,人們通常將資料集按照70%:30%隨機進行分割作為機器學習演算法的訓練集和測試集。但是在越來越多的應用中這不是一個好的方法,因為訓練集的分佈(上面例子中指網站影象)是不同於最終實際應用場景影象的分佈(手機影象)。

通常我們的定義:

l 訓練集—用於你的學習演算法中。

l 開發集—用於調整學習演算法的引數、特徵選擇以及做出其他的選擇。有時候將開發集稱為保留交叉驗證集。

l 測試集—用於評估演算法的效能,但是不要使用該資料集對學習演算法和引數做出任何決定。

當你定義了一個開發集和測試集,你的團隊將會嘗試多種方法(比如選擇不同的學習演算法引數)觀察哪種方法最好。開發集和測試集可以讓你的團隊看到你的演算法工作的如何。

換句話說,開發集和測試集目的是指導你的團隊對機器學習系統做出最重要的改變。

因此,你應該做到:

選擇開發集和測試集,反映未來你期望獲得的資料並在上面做的更好。

當你的實際資料(智慧手機影象)和測試集(網站影象)在性質上不一樣時,你的測試集不應該只有可用資料的30%那麼簡單。

如果你還沒有發你的APP,也就意味著沒有任何使用者,你將不能獲得使你未來做的更好的資料。但你仍然可以嘗試去接近這一點。例如,請你的朋友們用手機拍攝一些貓的影象發給你。當你的APP釋出後,你可以使用實際使用者資料更新程式的開發集/測試集。

如果你實在是沒有辦法去獲得你想要的資料,也許網站影象也是一個不錯的開始。但是,你應該關注這個系統缺乏好的泛化能力的風險。

有時候我們需要去決定投資多少去獲獲取發好的開發集和測試集。但是不要假設訓練集與測試集具有相同的分佈。嘗試去挑選能夠反映平臺實際應用場景的測試樣本,而不是你使用過的資料。

6. 你的開發集和測試集應該具有相同分佈

根據你的市場,你將你的貓APP影象資料分為四個區域:(i)美國、 (ii)中國、(iii) 印度和(iv)其他。構造一個開發集和一個測試集,我們可以將美國和印度看作開發集;中國和其他看作測試集。換句話說,我們可以隨機的分配2個區域作為開發集,而另外2個區域作為測試集。

一旦你定義了開發集和測試集,你的團隊將專注於提高開發集的表現效能。因此,開發集應該反映你最想提升效能的任務:在四個地區做的最好,而不是二個。

開發集和測試集具有不同的分佈導致的第二個問題:你的團隊有可能在測試集上表現很好,而在測試集上表現很差。我曾經在很多的挫折和白費努力中看到過這個結果。應該避免這樣的事情發生在你的身上。

例如,你的開發團隊開發一個系統在開發集上表現很好,而在測試集上表現很差。而你的開發集和測試集都來自同一分佈,則你應該明確知道:你的演算法在開發集上過擬合了。通過獲得更多的開發集資料可以避免過擬合的產生。

如果開發集和測試集具有不同的分佈,則你的選擇就不太清楚了。可能會有以下幾個錯誤:

1. 你的演算法已經在開發集上過擬合了

2. 測試集比開發集更難識別。你的演算法效能表現達到了你預期的期望,因此沒有可能做出進一步顯著性的改進了。

3. 測試集不一定比開發集難,只是他們來自不同分佈。因此在開發集上表現很好的演算法在測試集上並不能表現很好。在這種情況下,把大量工作用於提高演算法在開發集上的表現效能是無意義的。

機器學習應該方面的工作已經很困難了。開發集和測試集的不匹配增加了額外的不確定性,關於是否改進開發集的分佈效能或提高測試集的表現效能。這使得很難找出什麼是起作用的和什麼不起作用的,因此很難去優先處理誰。

如果你面對的是第三方基準測試問題,他們的開發者有可能提供來自於不同分佈的開發集和測試集。在這種情形下,運氣的好壞將會很大程度上影響你演算法的表現效能。當然,開發能夠在一個分佈上訓練並推廣到另一個分佈上仍然表現很好的學習演算法是一個重要的研究方向。如果你的目標是做特定機器學習應用而不是學術研究,我建議選擇具有相同分佈的開發集和測試集。這會使你的團隊更有效率。

7. 需要多大開發集/測試集?

開發集應該足夠大,大到足以檢測你正在嘗試不同演算法之間的差異。例如,如果分類器有90.0%的準確率而分類器B有90.1%的準確率,則有100個樣本的開發集將不能區分0.1%的區別。與我看到的其他機器學習問題相比,一個100個樣本的開發集太小。開發集通常樣本數量應該在1000到10,000之間。在10000個樣本下,你將有可能檢測到0.1%的效能提升。

對於一些成熟和重要的應用(例如,廣告、搜尋引擎和商品推薦),我已經看到一些團隊為了提升0.01%的效能而不懈努力,因為這直接影響到公司的利益。在這種情況下,開發集有可能遠遠超過了10000個樣本,為了能夠找到更小的改進空間。

測試集的數量多少合適哪?應該足夠大,大到能夠對於你的系統性能全面評估,擁有足夠高的可靠性。一種流行的啟發式演算法使用資料集的30%用作測試集。當你擁有一個適中的資料量(100到10000之間)時,這個測試集將能很好的工作。在大資料時代,現在我們面對的機器學習問題有時候會超過10億樣本量,分配給開發集/測試集的比例一直在減少,雖然開發集/測試集樣本絕對數量在增長。在分配開發集和測試集資料時,開發集和測試集的數量沒必要超過其評估演算法效能所需的資料量。

8. 給你的團隊進行演算法優化建立單一數值評估指標

分類準確率是單一數字評估指標的示例:當你的演算法對開發集(或測試集)進行分類時,會得到一個樣本分類準確性的數字比例。根據這個指標,如果分類器A準確率為97%,分類器B準確率為90%,則分類器A的分類效果更好。

相比之下,查準率和查全率不屬於單一數字評估指標體系:它給出2個數字用於評估你的分類器效能。多數字評估指標使得我們很難去比較演算法的優勢。假設你的演算法效能指標如下:

在這種情況下,我們無法看出那一個分類器效能更好,因此多數字評估指標無法直觀指導你使用那一個更好的分類器。

在演算法開發期間,你的團隊會在演算法結構、模型引數調優和特徵選擇等方面進行多種方法的嘗試。單一數字評估指標(比如精度)允許你根據演算法的準確率將你的模型進行排序,以便於快速決定那一個演算法的效能更好。

如果你比較關注查準率和查全率這2個指標,建議你使用一種標準方法將這2個指標組合為單一數字指標。例如,你可以使用查準率和查全率的平均值作為單一數字指標。你也可以計算演算法的“F1度量”,它是一種計算二者平均值的改進方法,比簡單計算平均值方法效果要好。

當你正在選擇一個適合的分類演算法時,單一數字評價指標可以快速幫助你做出選擇。它給出了一個清晰的演算法優先順序排序,同時給出了明確的前進方向。

作為最後一個例子,假設你獲得了四個主要市場((i) 美國, (ii)中國, (iii)印度,和(iv) 其他地區)的貓分類器的準確率,會得到四個指標值。通過將這四個指標值求平均值或加權平均值,最後會得到一個單一數字指標。將多指標值合併為單一指標值最常用的方法之一是求多指標值的平均值或加權平均值。

9. 優化指標和滿意指標

這是將多指標值合併為單一數字指標的另一種方法。

假設你比較關注一個學習演算法的準確率和執行時間。現在你需要在下面的三個分類器中做出選擇:

如果通過下面的計算公式將準確率和執行時間合併為單一指標,在此看起來有些不自然:

準確率-0.5*執行時間

你可以這樣做:首先,定義一個“可接受”的執行時間範圍。假設我們說演算法在100ms內的執行時間是可接受的。則分類器在滿足可接受執行時間內,取最大準確率的演算法。在此,執行時間是一個“滿意指標”—你的分類演算法只需要在這個指標上做的“足夠好”即可,也就是演算法的執行時間滿足最多100ms。準確率是“優化指標”。

如果你正在權衡N個不同的指標,比如模型的二進位制檔案大小(因為使用者不想下載在大的APP檔案)、執行時間和準確率,你可以考慮將其中N-1個值作為“滿足度指標”,也就是說你只需要考慮他們滿足一個特定的值即可。定義最後一個值作為“優化指標”。例如,設定一個閾值作為二進位制檔案和執行時間的接受範圍,並且在這些限制下去優化演算法的準確率。

作為最後一個例子,假設你正在構建一個硬體系統,該系統使用一個麥克風監聽使用者說的特別“喚醒詞”,從而喚醒系統工作。比如Amazon Echo監聽“Alexa”;蘋果Siri監聽“Hey Siri”;安卓監聽“Okay Google”;百度APP監聽“Hello Baidu”。你同時關注假正例的比例—指當沒有人說喚醒詞時,系統被喚醒的頻率和假反例的比例—指當用戶說了喚醒詞時,系統沒有被喚醒的頻率。使這個系統性能達到的一個合理目標是減少負反值的比例(優化指標),在24時工作中沒有出現一個負正例(滿意度指標)。

一旦你的團隊開始對評估指標進行優化,他們將能夠獲得較快的進展。

10. 有一個開發集和度量指標來加速演算法的迭代

人們很難事先知道什麼方法能夠很好的解決新問題。即使是經驗豐富的機器學習研究者在給出滿意答案之前也需要進行多種方法的嘗試。在構建機器學習系統時,我通常會做以下的思考:

1. 首先想一些構造這個系統的想法。

2. 用程式碼實現這些想法。

3. 通過實驗來驗證我的想法如何(通常我前面的一些想法都沒有很好的表現)。

基於以上的學習,在回過頭來產生更多的想法,在進行驗證。以此類推進行不斷的迭代。

這是一個不斷迭代的過程。你迭代的過程越快,你進步的就會越快。這就是為什麼擁有開發集/測試集和一個度量指標是如此的重要:每次當你在開發集上驗證你的想法時,評價指標可以快速使你判斷自己是否在朝正確的方向前進。

假設你沒有一個具體的開發集和度量指標。因此你的團隊每次開發新的貓分類器時,你必將新的分類器移值進你的APP中,並親身體驗幾個小時從直觀上判斷新的分類器效能是否有所提升。這樣的開發效率極其低下!同時,如果你的團隊將分類器的準確率從95.0%提高到了95.1%,在你親身體驗過程中有可能無法感受到這0.1%的提升。然而,系統整體的準確率是由許多個0.1%構成的。有一個開發集和度量指標可以快速使你驗證那些成功的想法給你的系統帶來了小(或大)的提升,因此你可快速決定哪些想法還要繼續改進,那些想法可以拋棄。