如何更高效的自學(xué)機(jī)器學(xué)習(xí)?
機(jī)器學(xué)習(xí)的“難”通常不在于數(shù)學(xué),因?yàn)闄C(jī)器學(xué)習(xí)本身不需要很高強(qiáng)度的數(shù)學(xué)計(jì)算,而在于 debugging 難的問題。機(jī)器學(xué)習(xí) debug 要比普通計(jì)算機(jī)程序難得多:出現(xiàn)問題的情形多,而且調(diào)試周期長。本文深入討論了這個(gè)難題,提出了在 debug 時(shí)需要注意的要點(diǎn)。
在過去的幾年里,機(jī)器學(xué)習(xí)便捷化方面的技術(shù)已經(jīng)取得了顯著的發(fā)展:出現(xiàn)了很多相關(guān)的網(wǎng)絡(luò)在線課程、精編書籍和架構(gòu)理論。這些精編課程對前沿科技研究分析,分解成通俗易懂的語言。而架構(gòu)理論方面則將普通問題抽象化,與構(gòu)建機(jī)器學(xué)習(xí)系統(tǒng)相結(jié)合形成理論系統(tǒng)。這些發(fā)展某種程度上能夠使人們打破已有的認(rèn)知圖示,加強(qiáng)對算法工作原理和計(jì)算代碼的理解。
機(jī)器學(xué)習(xí)之難在于debug
盡管如此,機(jī)器學(xué)習(xí)仍是一個(gè)相對“難”的問題。毫無疑問,提高機(jī)器學(xué)習(xí)算法是一項(xiàng)艱難的科研課題,需要不斷的創(chuàng)新、反復(fù)的試驗(yàn)、不懈的韌性。而將現(xiàn)有算法和模式與機(jī)器學(xué)習(xí)貫通運(yùn)用則更難,這也解釋了為什么機(jī)器學(xué)習(xí)方面的專業(yè)工程師的工資相比普通軟件工程師要高出很多的原因。
這里的難通常不在于數(shù)學(xué)計(jì)算,機(jī)器學(xué)習(xí)應(yīng)用本身不需要高強(qiáng)度的數(shù)學(xué)計(jì)算,而在于前面提到的構(gòu)建系統(tǒng),包括如何為工具建立圖式以解決實(shí)際應(yīng)用中的問題,這就要對現(xiàn)有算法和模式,兩者權(quán)衡以及使用限制充分熟悉。機(jī)器學(xué)習(xí)技術(shù)是通過對不同類型的模式(比如課程、課本和論文等)進(jìn)行應(yīng)用的過程中,對這些模式進(jìn)行檢測。當(dāng)然,這種知識構(gòu)建形式存在于計(jì)算機(jī)科學(xué)的所有領(lǐng)域,而不僅僅是機(jī)器學(xué)習(xí)領(lǐng)域。一般的軟件工程項(xiàng)目都需要對其他的框架、工具、技術(shù)以及設(shè)計(jì)決策幾方面進(jìn)行權(quán)衡。
機(jī)器學(xué)習(xí)的難點(diǎn)在于根本性的調(diào)試(debug)難題。機(jī)器學(xué)習(xí)的調(diào)試一般發(fā)生在以下兩種情況:1)算法無法運(yùn)行,或者2)算法運(yùn)行不太完美。機(jī)器學(xué)習(xí)“難”的獨(dú)特性在于,當(dāng)運(yùn)行效果不如預(yù)期時(shí),想要檢測出哪里出了問題極其困難。如果這兩種困難同時(shí)發(fā)生,那么應(yīng)用修復(fù)、升級以及結(jié)果顯示方面的調(diào)試周期將會延長。很少會發(fā)生計(jì)算運(yùn)行從一開始直到最后,占用大部分時(shí)間去做構(gòu)建算法的情況。
機(jī)器學(xué)習(xí)相比傳統(tǒng)軟件,調(diào)試?yán)щy增加了兩個(gè)維度
標(biāo)準(zhǔn)的軟件工程中,遇到問題解決方案效果不如預(yù)期的情況時(shí),一般有兩種可能:算法問題和實(shí)施問題。舉一個(gè)簡單的遞歸算法的例子。
通過這種方法,列舉出運(yùn)行效果不好的故障分析圖,如下:
橫軸列出的是算法設(shè)計(jì)上可能會出現(xiàn)的問題,縱軸是在算法應(yīng)用上可能會出現(xiàn)的問題。兩個(gè)維度上都有可能出現(xiàn)問題(如多重應(yīng)用bug),只有保證算法和應(yīng)用兩方面都精確無誤,才能制定出正確的調(diào)試解決方案。
調(diào)試過程中,需要憑借直覺,結(jié)合不同的bug(如編譯錯(cuò)誤提示,程序輸出結(jié)果等)信息,去準(zhǔn)確判斷問題所在。這些信息和啟發(fā)式方法能幫助縮短鎖定范圍,快速處理問題。
機(jī)器學(xué)習(xí)有兩個(gè)方面的常見bug:實(shí)際模式和數(shù)據(jù)。最簡單的例子,就如用隨機(jī)梯度下降算法訓(xùn)練邏輯回歸。這里,算法準(zhǔn)確包含梯度下降更新方程式,應(yīng)用準(zhǔn)確包括對特性和參數(shù)更新的精確計(jì)算。數(shù)據(jù)方面的bug包括嘈雜標(biāo)簽(noisylabels)、預(yù)處理過程中由于缺乏監(jiān)控信號或數(shù)據(jù)不足導(dǎo)致的錯(cuò)誤。模式bug包括建模能力的實(shí)際限制。比如,下圖展示了在非線性決策邊界中使用線性分類器。
調(diào)試過程從2D網(wǎng)格到4D超立方體(這里只顯示了三個(gè)維度),第四個(gè)數(shù)據(jù)維度,我們可以想象成是這些立方體的序列(注意這里只有一個(gè)小立方體是正確的解決方案)。
機(jī)器學(xué)習(xí)極其“難”的原因在于,如果在一個(gè)維度上有 n 種錯(cuò)誤的可能,2D維度中的錯(cuò)誤就有 n*n 種可能,4D維度中的錯(cuò)誤就有 n*n*n*n 種可能。這種情況下,依據(jù)現(xiàn)有信息,建立直覺去發(fā)現(xiàn)bug就顯得尤為重要。
幸運(yùn)的是,機(jī)器學(xué)習(xí)算法中,有更多的信號可以用于判斷哪里出了bug,比較重要的有:訓(xùn)練集和測試集的功能缺失圖(plots)、開發(fā)數(shù)據(jù)集中算法的實(shí)際輸出結(jié)果,以及算法的中間計(jì)算匯總統(tǒng)計(jì)。
如何解決延遲的調(diào)試周期
另一個(gè)導(dǎo)致機(jī)器學(xué)習(xí)調(diào)試非常困難的因素是調(diào)試周期長。通常,從運(yùn)行潛在修復(fù)功能到得出結(jié)果是否可行,需要花上幾個(gè)小時(shí)甚至幾天的時(shí)間。網(wǎng)頁開發(fā)中,具備自動更新功能的開發(fā)模式可以極大地提高開發(fā)效率,因?yàn)檫@意味著可以最大限度地減少開發(fā)流程中出現(xiàn)的bug事件。而在機(jī)器學(xué)習(xí)中這很難實(shí)現(xiàn),因?yàn)樵跀?shù)據(jù)集中訓(xùn)練算法需要花上幾個(gè)小時(shí)甚至幾天的時(shí)間。而深度學(xué)習(xí)模式更有可能導(dǎo)致調(diào)試周期延長,這就必須要進(jìn)行“并行”試驗(yàn)范式。對于機(jī)器學(xué)習(xí)開發(fā)人員來說,同時(shí)運(yùn)行多個(gè)試驗(yàn),是因?yàn)樗惴ㄓ?xùn)練是開發(fā)中的主要難點(diǎn),通過多程序同時(shí)運(yùn)行以開發(fā)指令流水(對于程序開發(fā)者而不是應(yīng)用者)。強(qiáng)制性地多程序同時(shí)運(yùn)行的主要缺點(diǎn)在于順序調(diào)試和試驗(yàn)過程中,不能運(yùn)用累積經(jīng)驗(yàn)。
機(jī)器學(xué)習(xí)通常被歸結(jié)為一種直覺開發(fā)的藝術(shù),有了這種直覺,在很多維度都可能出現(xiàn)bug(或可以提高)時(shí),可以判斷出了bug(或需要提高)的地方在哪。這是構(gòu)建機(jī)器學(xué)習(xí)項(xiàng)目的一個(gè)重要技巧,即當(dāng)調(diào)試范圍內(nèi)呈現(xiàn)出的信號,你會開始利用這個(gè)信號嘗試判斷問題出在哪。我工作過程中經(jīng)常會出現(xiàn)類似的情況。
舉例來說,我最早遇到這樣的問題是在訓(xùn)練神經(jīng)網(wǎng)絡(luò)時(shí),總是出現(xiàn)周期性的訓(xùn)練功能損失。這些功能損失在經(jīng)過某些數(shù)據(jù)時(shí)會發(fā)生延遲,但很快便返回到一個(gè)很高的數(shù)值。經(jīng)過很多的試驗(yàn)和錯(cuò)誤之后,我意識到這通常是因?yàn)橛?xùn)練集沒有被正確地隨機(jī)化(這看似是一個(gè)數(shù)據(jù)問題,但實(shí)際上是一個(gè)應(yīng)用問題),還有一個(gè)問題就是,在使用隨機(jī)梯度算法時(shí),只處理小部分的數(shù)據(jù)。
總的來說,快速高效的調(diào)試是一個(gè)非常需要的技巧,可以應(yīng)用到現(xiàn)在的機(jī)器學(xué)習(xí)流水線中