你會給想學習機器學習的軟體工程師提出什麼建議?

lsvih發表於2017-07-10

你會給想學習機器學習的軟體工程師提出什麼建議?

這很大一部分都取決於這名軟體工程師的背景,以及他希望掌握機器學習的哪一部分。為了具體討論,現在假設這是一名初級工程師,他讀了 4 年本科,從業 2 年,現在想從事計算廣告學(CA)、自然語言處理(NLP)、影象分析、社交網路分析、搜尋、推薦排名相關領域。現在,讓我們從機器學習的必要課程開始討論(宣告:下面的清單很不完整,如果您的論文沒有被包括在內,提前向您抱歉)。

  • 線性代數
    很多的機器學習演算法、統計學原理、模型優化都依賴線性代數。這也解釋了為何在深度學習領域 GPU 要優於 CPU。線上性代數方面,你至少得熟練掌握以下內容:

    • 標量、向量、矩陣、張量。你可以將它們看成零維、一維、二維、三維與更高維的物件,可以對它們進行各種組合、變換,就像樂高玩具一樣。它們為資料變換提供了最基礎的處理方法。
    • 特徵向量、標準化、矩陣近似、分解。實質上這些方法都是為了方便線性代數的運算。如果你想分析一個矩陣是如何運算的(例如檢查神經網路中梯度消失問題,或者檢查強化學習演算法發散的問題),你得了解矩陣與向量應用了多少種縮放方法。而低階矩陣近似與 Cholesky 分解可以幫你寫出效能更好、穩定性更強的程式碼。
    • 數值線性代數
      如果你想進一步優化演算法的話,這是必修課。它對於理解核方法與深度學習很有幫助,不過對於圖模型及取樣來說它並不重要。
    • 推薦書籍
      《Serge Lang, Linear Algebra》
      很基礎的線代書籍,很適合在校學生。
      《Bela Bolobas, Linear Analysis》
      這本書目標人群是那些想做數學分析、泛函分析的人。當然它的內容更加晦澀難懂,但更有意義。如果你攻讀 PhD,值得一讀。
      《Lloyd Trefethen and David Bau, Numerical Linear Algebra》
      這本書是同類書籍中較為推薦的一本。《Numerical Recipes》也是一本不錯的書,但是裡面的演算法略為過時了。另外,推薦 Golub 和 van Loan 合著的書《Matrix Computations》
  • 優化與基礎運算

    大多數時候提出問題是很簡單的,而解答問題則是很困難的。例如,你想對一組資料使用線性迴歸(即線性擬合),那麼你應該希望資料點與擬合線的距離平方和最小;又或者,你想做一個良好的點選預測模型,那麼你應該希望最大程度地提高使用者點選廣告概率估計的準確性。也就是說,在一般情況下,我們會得到一個客觀問題、一些引數、一堆資料,我們要做的就是找到通過它們解決問題的方法。找到這種方法是很重要的,因為我們一般得不到閉式解。

    • 凸優化

      在大多情況下,優化問題不會存在太多的區域性最優解,因此這類問題會比較好解決。這種“區域性最優即全域性最優”的問題就是凸優化問題。

      (如果你在集合的任意兩點間畫一條直線,整條線始終在集合範圍內,則這個集合是一個凸集合;如果你在一條函式曲線的任意兩點間畫一條直線,這兩點間的函式曲線始終在這條直線之下,則這個函式是一個凸函式)

      Steven Boyd 與 Lieven Vandenberghe 合著的書可以說是這個領域的規範書籍了,這本書非常棒,而且是免費的,值得一讀;此外,你可以在 Boyd 的課程中找到很多很棒的幻燈片;Dimitri Bertsekas 寫了一系列關於優化、控制方面的書籍。讀通這些書足以讓任何一個人在這個領域立足。

    • 隨機梯度下降(SGD)

      大多數問題其實最開始都是凸優化問題的特殊情況(至少早期定理如此),但是隨著資料的增加,凸優化問題的佔比會逐漸減少。因此,假設你現在得到了一些資料,你的演算法將會需要在每一個更新步驟前將所有的資料都檢查一遍。

      現在,我不懷好意地給了你 10 份相同的資料,你將不得不重複 10 次沒有任何幫助的工作。不過在現實中並不會這麼糟糕,你可以設定很小的更新迭代步長,每次更新前都將所有的資料檢查一遍,這種方法將會幫你解決這類問題。小步長計算在機器學習中已經有了很大的轉型,配合上一些相關的演算法會使得解決問題更加地簡單。

      不過,這樣的做法對並行化計算提出了挑戰。我們於 2009 年發表的《Slow Learners are Fast》論文可能就是這個方向的先導者之一。2013 年牛峰等人發表的《Hogwild》論文給出了一種相當優雅的無鎖版本變體。簡而言之,這類各種各樣的演算法都是通過在單機計算區域性梯度,並非同步更新共有的引數集實現並行快速迭代運算。

      隨機梯度下降的另一個難題就是如何控制過擬合(例如可以通過正則化加以控制)。另外還有一種解決凸優化的懲罰方式叫近端梯度演算法(PGD)。最流行的當屬 Amir Beck 和 Marc Teboulle 提出的 FISTA 演算法_files/Breck_2009.pdf)了。相關程式碼可以參考 Francis Bach 的 SPAM toolbox

    • 非凸優化方法

      許多的機器學習問題是非凸的。尤其是與深度學習相關的問題幾乎都是非凸的,聚類、主題模型(topic model)、潛變數方法(latent variable method)等各種有趣的機器學習方法也是如此。一些最新的加速技術將對此有所幫助。例如我的學生 Sashank Reddy 最近展示瞭如何在這種情況下得到良好的收斂速率

      也可以用一種叫做譜學習演算法(Spectral Method)的技術。Anima Anandkumar 在最近的 Quora session 中詳細地描述了這項技術的細節。請仔細閱讀她的文章,因為裡面乾貨滿滿。簡而言之,凸優化問題並不是唯一能夠可靠解決的問題。在某些情況中你可以試著找出其問題的數學等價形式,通過這樣找到能夠真正反映資料中聚類、主題、相關維度、神經元等一切資訊的引數。如果你願意且能夠將一切託付給數學解決,那是一件無比偉大的事。

      最近,在深度神經網路訓練方面湧現出了各種各樣的新技巧。我將會在下面介紹它們,但是在一些情況中,我們的目標不僅僅是優化模型,而是找到一種特定的解決方案(就好像旅途的重點其實是過程一樣)。

  • (分散式)系統

    機器學習之所以現在成為了人類、測量學、感測器及資料相關領域幾乎是最常用的工具,和過去 10 年規模化演算法的發展密不可分。Jeff Dean 過去的一年發了 6 篇機器學習教程並不是巧合。在此簡單介紹一下他:點選檢視,他是 MapReduce、GFS 及 BigTable 等技術背後的創造者,正是這些技術讓 Google 成為了偉大的公司。

    言歸正傳,(分散式)系統研究為我們提供了分散式、非同步、容錯、規模化、簡單(Simplicity)的寶貴工具。最後一條“簡單”是機器學習研究者們常常忽視的一件事。簡單(Simplicity)不是 bug,而是一種特徵。下面這些技術會讓你受益良多:

    • 分散式雜湊表

      它是 memcacheddynamopastry 以及 ceph 等的技術基礎。它們所解決的都是同一件事情 —— 如何將物件分發到多臺機器上,從而避免向中央儲存區提出請求。為了達到這個目的,你必須將資料位置進行隨機但確定的編碼(即雜湊)。另外,你需要考慮到當有機器出現故障時的處理方式。

      我們自己的引數伺服器就是使用這種資料佈局。這個專案的幕後大腦是我的學生 Mu Li 。請參閱 DMLC 檢視相關的工具集。

    • 一致性與通訊

      這一切的基礎都是 Leslie Lamport 的 PAXOS 協議。它解決了不同機器(甚至部分機器不可用)的一致性問題。如果你曾經使用過版本控制工具,你應該可以直觀地明白它是如何執行的——比如你有很多機器(或者很多開發者)都在進行資料更新(或更新程式碼),在它們(他們)不隨時進行交流的情況下,你會如何將它們(他們)結合起來(不靠反覆地求 diff)?

      在(分散式)系統中,解決方案是一個叫做向量時鐘的東西(請參考 Google 的 Chubby)。我們也在引數伺服器上使用了這種向量時鐘的變體,這個變體與本體的區別就是我們僅使用向量時鐘來限制引數的範圍(Mu Li 做的),這樣可以確保記憶體不會被無限增長的向量時鐘時間戳給撐爆,正如檔案系統不需要給每個位元組都打上時間戳。

    • 容錯機制、規模化與雲

      學習這些內容最簡單的方法就是在雲伺服器上執行各種演算法,至於雲服務可以找 Amazon AWSGoogle GWCMicrosoft Azure 或者 其它各種各樣的服務商。一次性啟動 1,000 臺伺服器,意識到自己坐擁如此之大的合法“殭屍網路”是多麼的讓人興奮!之前我在 Google 工作,曾在歐洲某處接手 5,000 餘臺高階主機作為主題模型計算終端,它們是我們通過能源法案獲益的核電廠相當可觀的一部分資源。我的經理把我帶到一旁,偷偷告訴我這個實驗是多麼的昂貴……

      可能入門這塊最簡單的方法就是去了解 docker 了吧。現在 docker 團隊已經開發了大量的規模化工具。特別是他們最近加上的 Docker MachineDocker Cloud,可以讓你就像使用印表機驅動一樣連線雲服務。

    • 硬體

      說道硬體可能會讓人迷惑,但是如果你瞭解你的演算法會在什麼硬體上執行,對優化演算法是很有幫助的。這可以讓你知道你的演算法是否能在任何條件下保持巔峰效能。我認為每個入門者都應該看看 Jeff Dean 的 《每個工程師都需要記住的數值》。我在面試時最喜歡的問題(至少現在最喜歡)就是“請問你的膝上型電腦有多快”。瞭解是什麼限制了演算法的效能是很有用的:是快取?是記憶體頻寬?延遲?還是磁碟?或者別的什麼?Anandtech 在微處理器架構與相關方面寫了很多很好的文章與評論,在 Intel、ARM、AMD 釋出新硬體的時候不妨去看一看他的評論。

  • 統計學

    我故意把這塊內容放在文章的末尾,因為幾乎所有人都認為它是(它的確是)機器學習的關鍵因而忽視了其它內容。統計學可以幫你問出好的問題,也能幫你理解你的建模與實際資料有多接近。

    大多數圖模型、核方法、深度學習等都能從“問一個好的問題”得到改進,或者說能夠定義一個合理的可優化的目標函式。

這篇文章已經寫的夠久了,不知道有沒有人能讀到這裡,我要去休息啦。現在網上有很多很棒的視訊內容可以幫助你學習,許多教師現在都開通了他們的 Youtube 頻道,上傳他們的上課內容。這些課程有時可以幫你解決一些複雜的問題。這兒是我的 Youtube 頻道歡迎訂閱。順便推薦 Nando de Freitas 的 Youtube 頻道,他比我講得好多了。

最後推薦一個非常好用的工具:DMLC。它很適合入門,包含了大量的分散式、規模化的機器學習演算法,還包括了通過 MXNET 實現的神經網路。

雖然本文還有很多方面沒有提到(例如程式語言、資料來源等),但是這篇文章已經太長了,這些內容請參考其他文章吧~


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃

相關文章