標籤:

面向前端工程師的機器學習引導課

面向前端工程師的機器學習引導課

來自專欄 攜程技術中心

本文面向前端工程師,使用熟悉的前端技術 JavaScript,講解機器學習里的基礎概念和演算法。

演示可在瀏覽器里運行的機器學習 DEMO,包括擬合線段中心點,擬合矩形中心點,線性回歸,AI玩Flappy-Bird和2048遊戲,識別手寫數字等效果。

1、什麼是人工智慧(AI)?

智能行為和現象,有不同的來源。有的來自生物,有的來自機器。

我們可以把那些來生物的智能,稱之為自然智能。它們是通過自然選擇逐步演化而來的智能。

而另外一些由人類設計的機器所表現的智能,就是人工智慧,簡稱 AI。

2、人工智慧的兩大分類

按照解決問題的能力,我們可以把人工智慧,分成兩類:

  • 強人工智慧:擁有自我意識,具備解決通用問題的能力
  • 弱人工智慧:沒有自我意識,具備解決特定問題的能力

目前,我們能看到的人工智慧,幾乎都是弱人工智慧,在解決特定問題的能力上,超越了人類。

2.1、強智能之拉普拉斯妖

我們可以通過物理學裡的一個思想實驗,來側面理解強智能,是怎樣的。

拉普拉斯是著名的數學家,他提出了一個看法:如果一個智能體,知道宇宙中每個原子確切的位置和動量,那麼就可以通過牛頓定律推演出宇宙的過去以及未來;宇宙中的一切問題,都可以得到精確的解答。

然拉普拉斯妖,後來被證明是不可能的。但它確實反映了解決通用問題的一種做法。

2.2、弱智能之麥克斯韋妖

另一個物理學的思想實驗,來自麥克斯韋。這個思想實驗的目的,是為了挑戰熱力學第二定律。該定律指出,封閉系統最終會達到熱平衡。

於是,麥克斯韋假設存在一種智能體:麥克斯韋妖,看守暗門,觀察分子運動速度。使較快的向某側流動,較慢向另一側流動。經過充分長的時間,兩側溫差會越來越大 。溫度高低是分子運動劇烈程度的宏觀表現,通過分隔不同運動速率的分子,就讓系統的兩個部分的分子有了不同的劇烈程度。

3、什麼是機器學習?

機器學習,是英文 Machine Learning 的直譯。它是實現人工智慧的其中一種方式。前面說過的拉普拉斯妖就是不是機器學習的方式。

人類的學習,可以歸納為這種現象:隨著經驗的增加,解決問題的能力得到提升。

對機器而言,經驗其實就是數據。機器學習就是:用數據訓練程序以優化其表現的演算法。

機器學習是一個相對寬泛的概念,只要滿足它的定義,就屬於機器學習。並不是一定要 GPU/TPU 訓練,一定要多少行代碼,一定要解決多宏大的難題,才叫機器學習。用數據訓練一個模型,擬合一個點,也是機器學習的體現。

4、機器學習的分類?

機器學習有兩種分類:監督學習和非監督學習。

區分這兩種學習方式的依據很簡單,就是訓練數據是否包含了答案。包含答案,就是監督學習;不包含答案,就是非監督學習。當然,這裡也存在中間狀態,包含一個漸進式答案,或者其它形式的間接答案等,就叫半監督學習。

5、什麼是深度學習?

深度學習,是英文 Deep Learning 的直譯。它是實現機器學習的其中一種方式。機器學習還包含其它實現方案。

深度學習里,用到了人工神經網路,這是一個用計算機模擬大腦神經元運作模式的演算法。同時,這個人工神經網路的隱藏層數量還必須足夠多,才能構成深度神經網路。然後喂之以大量的訓練數據,就是深度學習了。

換一個角度,如果隱藏層數量不多,而是每個隱藏層里包含的神經元數量很多,在形態上,它就是一個往寬度發展的神經網路結構。這時,可能就叫廣度學習了。

目前,深度學習還是主流,它的訓練效率,優於廣度學習。

6、AI & ML & DL & GA 的關係

下圖展示了人工智慧,機器學習,人工神經網路,深度學習和遺傳演算法之間的關係。我們可以看到,除了遺傳演算法是交集關係意外,其餘的是分離出一個個子集的關係。

7、前端工程師與人工智慧

前端工程師跟人工智慧,有什麼關係呢?

這個問題應該反過來問,首先,按照目前的發展,將來人工智慧會跟所有人產生緊密關聯。前端工程師也是人類,作為人類,應該在某種程度上了解人工智慧,而後能更好地使用人工智慧的產品。

其次,前端工程師,也是程序員。我們可以在程序員的層面,比普通人更好地理解人工智慧背後的機制。

再次,我們才是前端工程師。在前端工程師的角度,去審視人工智慧未來是否會取代我們的工作。它取代我們之後,會不會有新的工作崗位出來,比如 AI 前端工程師。這時,那些對人工智慧更加了解的前端工程師,就更容易得到相關的崗位了。

更何況,了解人工智慧,說不定有機會轉型成 AI 程序員。

編程語言、開源社區、IDE 等持續發展,會不斷降低人工智慧的開發門檻。過去的經驗告訴我們,五年前高級程序員才能做到的事情,現在一個的普通程序員也有望做到。

人工智慧這個概念,是在上世紀 50~60 年代提出的。當時,關心人工智慧的那幫人,都是計算機里的鼻祖人物和數學家們。但是現在,作為前端工程師的我,居然也能寫上一些代碼,在 web 頁面上跑起機器學習的 DEMO,這正是反映了門檻的降低趨勢。

8、UI 開發的三種模式

  • 手寫標籤和樣式代碼,生成頁面
  • 可視化拖拽 UI 組建,生成頁面
  • 直接輸入設計稿,輸出可用頁面(github.com/tonybeltrame)

要想在前端自動化上做到極致,也無法跳開人工智慧環節。pix2code 這個項目就是一個案例。雖然現在它的能力還很弱,使用場景很有限。但我們不要忘記,人工智慧的發展速度,可能是指數級的。谷歌的阿爾法狗,一開始只是打敗了人類業餘圍棋玩家,後面戰勝了人類頂尖玩家李世石,再後面擊敗了當時的世界第一柯潔。然後,再無對手,又開始拋棄人類經驗,通過自我對弈的方式,打敗之前的版本。再到後面,竟已不局限於圍棋,拓展到了國際象棋,日本將棋等其它棋類遊戲里。這裡的發展速度,是非常快的。

所以,不能因為 pix2code 目前的能力,而盲目樂觀。

9、數學知識回顧:什麼是導數?

霍金在寫《時間簡史》時說過,書里每出現一個公式,書的銷量就減半。這反映了公式在科普和推廣階段的負面作用。

但是,不用公式和代碼,又要講明白機器學習,幾乎是不可能的。聽著玩兒的話,我們提供的 DEMO 和前面的概念介紹,也足夠滿足要求了。

接下來,是直面公式和代碼的時刻,不能逃避,在真正理解後,你會發覺,原來公式才是最簡單、最容易理解的那個。那些比喻、類比和段子,最後都不會在頭腦里保留多久,只是在短時間內,營造了學到東西的虛假體驗。

上面是導數的代數形式,下面是導數的幾何形式。我們可以看到,導數,其實是圍繞一個點來談論的。當我們說一條線的導數是多少多少時,只是一個特例,恰好那條線上的每個點的導數都是同一個值。

當我們選取了一個點 x0 之後,在 X 軸上追加一個無窮小的增量,然後用 X 加上無窮小增量得到 x1,求得 x1 對應的 Y 軸的值 y1 之後,通過 x1 - x0 和 y1 - y0,我們得到了一個小三角形。這個小三角形的 y 軸長度,除以 x 軸長度,就時這個點 x0 的導數值。

關鍵點有兩個。一個是找到小三角形,它是直角三角形。第二個除法,是用兩個直角邊相除,就得到了導數。導數反映了這個點跟下一個點的變化幅度和趨勢。

10、數學知識回顧:什麼是複合函數?

不是所有函數都那麼簡單,很多函數很複雜,甚至不能寫在一條公式內,甚至不能用公式表達出來。

不過,我們還是可以從函數組合的角度,對許多複雜函數進行解構。

比如上面的第一條函數,雖然它本身已經夠簡單了。但其實還可以拆分成兩個子函數的組合。

先計算第三條公式的結果 Y,在把 Y 作為 X 值,帶入第二條公式內,求得另一個 Y 值。這個過程就相當於對第一條公式進行 Y 值計算。

11、數學知識回顧:什麼是鏈式法則?

簡單函數,有一些導數計算公式可以套用。那複雜函數里,又應該如何求導呢?

前面我們了解了複合函數的概念,它可以拆分成簡單函數之間的組合關係。通過這個組合關係,我們可以用簡單函數的導數,計算出複雜函數的導數。

在介紹導數時,我們特彆強調了「除法」,鏈式法則就是利用,除法和函數組合時產生的分子和分母的顛倒關係,不斷地鏈式相乘,消掉中間變數,最後得到我們想要的目標導數值。

12、數學知識回顧:什麼是梯度下降?

前面的數學知識部分,已經是本次分享里最難的環節了。後面是相對輕鬆的部分。

梯度下降,是機器學習里的重要概念。不管你去看誰的書或者視頻,都繞不開這個概念。可能其中有些老師會打個比方說:假設你在一座山的山頂或者山腰上,你周圍瀰漫著渾厚的迷霧,無法看清下山的路,這是你要下山,要用什麼方式?就是用腳探索更低點,然後逐步走下來。這就是梯度下降。

聽了這個比喻,你理解了梯度下降嗎?

反正我沒有,下山我會,梯度下降嘛,還是不懂。

我們可以看到,比喻終究是間接的,含混的。還是要直面更直接和純凈的知識。

梯度下降,緣於這麼個觀測事實:

1)當我的導數是一個正數時,更低點在 -X 軸的方向; 2)當我的導數是一個負數時,更低點在 +X 軸的方向; 3)那麼,不管我的導數是正數還是負數,它的反方向,就是更低點的方向。 4)沿著導數的反方向走,必將走到一個相對最低點。

這就是梯度下降。如果你理解了它,那你可以很容易地理解,什麼是梯度上升。就是更高點,在沿著導數的方向嘛。

上圖是一個 U 形圖,只有一個最低點。如果是一個波浪圖,那就有很多個局部最低點,如何找到全局最低點,目前也沒有完美解決方案,還是一個難題。

13、數學知識回顧:什麼是學習率?

梯度下降,只是為我們指明了更低點的方向,但卻沒有告訴我們距離。所以我們必須選擇一個步伐大小,這個步伐大小,被稱之為學習率。

如果設置的學習率過大,步伐太大,一下子跨到對面去了,下次又走導數的反方向跨回來。就這樣來來回回地振蕩,沒有走到一個令人滿意的低點。

如果設置的學習率過小,走了很久,也彷彿在原地踏步。這也不行。

所以,選擇一個合適的學習率,很重要。如何自動選擇最優學習率,目前也是一個難題。

14、前端人工智障之擬合線段中心點

在線 DEMO(lucifier129.github.io/s) 和 源代碼(github.com/Lucifier129/)

要擬合一個點,先要設置一個預測模型,在這裡用 x = a 就可以了。最初 a 的值是隨機的,或者設置為 0,也可以,權當瞎猜。

然後我們用生成的訓練數據來餵給學習演算法。數據里都包含了答案,我們就可以得到一個上圖誤差公式。它叫均方誤差。用正確答案減去瞎猜的答案,得到一個值,再對其求平方,保證是正數。

有了均方誤差公式,我們就可以用之前學到鏈式法則求導技巧,把 Y 軸設置成誤差值 e,把 X 軸設置成參數 a,然後用梯度下降尋找誤差最小的點,下一個 a 參數就是: a + 學習率 * -1 * 導數值。其中,(學習率 * -1 * 導數值)得到的就是往導數反方向走的那一小步的步長。

當誤差最小點為 y = 0 點時,可以說,我們找到了理想的參數 a,它完美的,零誤差地擬合了目標點。

值得一提的是,你可以看到誤差 e 對模型輸出的 y 的導數,由鏈式法則計算出來,恰好包含了一個 -1,而找最低點,是用導數的反方向,也包含一個 -1,這相乘就是負負得正,可以消掉。在有些機器學習的介紹公式和代碼實現里,它們就省略這兩個語義不同的 -1。這對於初學者來說,是非常要不得的。它使得梯度下降的形式,看起來像梯度上升,容易混淆概念,徒增學習難度。

15、前端人工智障之擬合矩形中心點

矩形中心點,無非就是上面的 X 軸坐標點的基礎上,增加一個 Y 軸的維度嘛。

在線 DEMO(lucifier129.github.io/s) 和 源代碼(github.com/Lucifier129/)

每個訓練數據,都包含了 (x, y) 兩個數據,我們增加一個對 y 軸的參數 y = b。然後用相同的套路,分別同步訓練即可。

  • a = a + learningRate * - gradientA
  • b = b + learningRate * - gradientB

16、前端人工智障之線性回歸

在線 DEMO(lucifier129.github.io/s) 和 源代碼(github.com/Lucifier129/)

線性回歸也是,除了預測模型的公式變成了 y = a * x + b,其它套路都一樣。

在預測時,a 是常量係數,x 是自變數,y 是因變數。當調整參數 a 時,預測時輸入的 x 成了 a 的常量係數了。所以對 y 求導 a,得到的值是 x 。

這裡存在一個正向計算預測結果,反向修復參數誤差的過程。

17、什麼是感知機(Perceptrons)?

在線 DEMO(lucifier129.github.io/s) 和 源代碼(github.com/Lucifier129/)

線性回歸的公式是 y = a * x + b,從數學角度,很明顯可以推廣一下,成為 y = w1 * x1 + w2 * x2 + w3 * x3 + ... + wn * xn + b 的多因素形式。

在上面的基礎上,再增加一個激活函數,就構造了一個被稱之為感知機的模式。它最初是模擬大腦神經元在接受到刺激之後,根據是否達到閾值,來決定是否放電,刺激其它神經元。

感知機可以對多因素的事物,進行線性分類。比如對腫瘤進行良性腫瘤和惡性腫瘤的分類,對郵件進行垃圾郵件和非垃圾郵件的分類。不過,感知機的分類實現線性的,如果一個分類無法用線性分割出來,感知機就無法解決它。著名的"與或問題",就曾經打擊到了人工神經網路的研究熱度。

18、什麼是人工神經網路(ANN)?

感知機是線性回歸里的公式推廣後的形態,而人工神經網路,則可以看成是感知機的推廣形態。不只是一個人工神經元,而是多個神經元以某種網路結構鏈接在一起,配合非線性的激活函數,它可以實現更強大的分類和擬合能力。

反向傳播演算法,就是一種對多層人工神經網路進行調參的演算法。它的原理,正如我們前面介紹的求導、鏈式法則和梯度下降。感興趣的同學,可以嘗試自行推導和實現一下反向傳播演算法。

19、什麼是遺傳演算法(GA)?

遺傳演算法是一個偉大的演算法。對人類而言,可能是最偉大的演算法。

因為,廣義上的演算法,不局限於編程領域。任何確定性的、在有限步驟下完成的特定步驟序列,都可以稱之為演算法。它可以是代碼形式的,也可以是物理形式的。

人類本身,就可以看成遺傳演算法跑在大自然這個生態系統平台上的產物。

現在我們人類,又把遺傳演算法應用到了計算機平台上。所有能編碼到一個序列的問題,都可以用遺傳演算法解決。區別在於,遺傳演算法未必是最好最經濟的解決方案罷了。

像太陽系,或者宇宙,擁有龐大的資源,可以花費數十億年的時間,跑遺傳演算法(自然選擇),最後演化出人類智能。我們人類的算力,卻著實有限,所以我們通常需要更高性能的演算法。

遺傳演算法模擬了自然選擇里的幾個概念,基因、染色體以及種群,通過讓兩個染色體按照某個突變率交換基因位的編碼,來不斷得到新的,可能更好的解決方案。

遺傳演算法和人工神經網路結合起來,產生了一個被成為神經進化的演算法。後面我們可以看到這個演算法應用在玩 Flappy-bird 遊戲的效果。

20、前端人工智障 DEMO

  • 神經網路 + 遺傳演算法,玩 Flappy-Bird(lucifier129.github.io/f)
  • 神經網路 + 反向傳播,玩 Flappy-Bird(lucifier129.github.io/f)
  • 神經網路 + 遺傳演算法 + 變種,玩 Flappy-Bird(lucifier129.github.io/f)
  • 十大高手,玩 Flappy-Bird(lucifier129.github.io/f)
  • 反向傳播,識別手寫數字(lucifier129.github.io/f)

Flappy-bird 等遊戲,在每一幀里,都沒有包含明顯的正確決策,所以監督學習在這裡比較難以派上用場。我們要用非監督的方式來學習。

第一個 DEMO,遺傳演算法 + 神經網路,生成一批神經網路模型,指導每隻小鳥是否 flap 飛起來的決策。當鳥兒碰壁死絕,用每隻鳥兒得到的 score 分數進行排名,然後讓排名靠前的神經網路,繁殖更多,而排名靠後的繁殖更少,或者淘汰。經過 N 代的演化,最後得到優秀的神經網路參數模型。

第二個 DEMO,用第一個 DEMO 訓練出來的優秀模型,作為正確答案的生成器,我們就可以得到一個監督學習的用場了。把優秀 Bird 的決策當作正確答案,喂數據給反向傳播演算法,當兩者的誤差趨於一個很小的值時,另一個優秀的模型就訓練出來了。

第三個 DEMO,還是遺傳演算法 + 神經網路,只是這次,不是用分數高低來進行排名。分數不是答案,所以是非監督學習。這次,我們用第一個 DEMO 訓練出來的優秀模型,作為正確答案的生成器。然後計算每隻演化中的 Bird 模型的誤差,誤差大,排名靠後,誤差小,排名靠前。由於訓練包含了正確答案,所以是監督學習。最後,我們演化出了一個跟第一個 DEMO 訓練出的優秀模型誤差很小的新模型。

如此可見,遺傳演算法 + 神經網路擁有更強的解決問題的能力,既可以監督學習,也可以非監督學習。但反向傳播演算法,只需要調整一個神經網路參數模型,而遺傳演算法的版本,卻動輒成百上千個模型,性能自然不那麼好。

第四個 DEMO,是用訓練的 10 只優秀 Bird 模型角逐。目前為止,跑到 1 億分,我也沒見它們任何一個倒下。

第五個 DEMO,是機器學習里經典的 MNIST 手寫數字訓練集,採用的是反向傳播演算法的監督學習。可以識別你寫在畫板上的數字。

21、結語

儘管前端並非機器學習的主場,但作為學習,它可能挺適用的。起碼我們可以更容易地在網頁上看到效果。

當然,如果想更深入理解機器學習,需要去看更專業的書籍或教程。本次分享,主要是作為一個引導,激發大家對機器學習的興趣。

[作者簡介]古映傑,攜程度假研發部高級研發經理。負責前端框架和基礎設施的設計、研發與維護。開源庫 react-lite 作者。本文來自古映傑在「攜程技術沙龍——新一代前端技術實踐」上的分享。

更多來自攜程技術人的一手乾貨,歡迎搜索關注「攜程技術中心」微信公號。


推薦閱讀:

機器學習+AI技術,碰撞出什麼你不知道事
打開機器學習的黑盒——卷積神經網路原理介紹
隨機森林,gbdt,xgboost的決策樹子類Python講解
Google開放最大目標檢測數據集,還要為它舉辦AI挑戰賽
深度模型訓練時間預估

TAG:機器學習 |