機器學習原來如此有趣!全世界最簡單的機器學習入門指南

有一次,我和Vito(我的合夥人)聊起瞭當下熱門的幾種技術趨勢。當談及它們在未來可能的發展前景的時候,Vito說瞭下面的一段話:

人工智能是個信息革命到蒸汽機規模之間的機會,相比之下虛擬現實應該是移動互聯網級別的,而用戶個性化服務應該是伴生規模的。

如果人工智能技術帶來的變革確實能夠比擬工業革命的話,那麼它勢必會成就一代人,同時也淘汰掉一代人。而且,仔細想想,其實人工智能離我們並不遙遠,甚至可以說已經開始深入到我們的日常生活中瞭。從iPhone裡的Siri,到各大網站的內容推薦系統,再到圖像識別和人臉識別技術的廣泛應用,這些場景的背後都有這項技術在發揮作用。

作為程序員,以機器學習和深度學習為代表的人工智能技術,與我們的關系則更加緊密。現在凡是有些規模的互聯網公司,基本都有專門研究算法的團隊。在數據挖掘、Antispam、推薦系統和廣告系統,以及其它一些領域,我們都多多少少會涉及到一些機器學習的技術。即使我們不親自負責開發和維護這些技術,在工作中也難免會與之產生交集。

說瞭這麼多,我其實想強調的一點是:任何人都應該瞭解一點跟人工智能有關的技術,因為這是無法阻擋的大潮,是不可避免的未來趨勢。

而對於一名沒有涉及到任何這方面技術的工程師來說,這項技術本身的獨特性也絕對值得你花時間去瞭解。你一旦瞭解就會發現,這是一種全然不同的編程方式。

本文就是這樣的一篇科普文章,目的是向所有沒有接觸過人工智能技術的程序員(甚至非技術人員),介紹人工智能領域最前沿的神經網絡和深度學習方面的知識。也許,你看完之後,會像我第一次接觸它們的時候一樣,驚奇地感嘆:這種編程方式簡直是造物主留下的一個後門!竟然用如此簡單的算法就能實現出遠遠超越原本設計的智能!

好瞭,蓄勢完畢,相信現在你對於是否願意花時間讀完剩下的內容,已經做出自己的決定瞭。實際上,這項科普的工作並不輕松,因為這項技術涉及到不少數學知識。為瞭避免閱讀障礙,我會嘗試在描述的過程中盡量不引入復雜的數學公式,同時讓講解盡量有趣。


現在人工智能非常火爆,給大傢推薦一個非常適合小白入門的教程,點下面鏈接即可跳轉。

https://www.captainbed.net/suga


感知器

要想理解深度學習,我們就必須先理解人工神經網絡,因為神經網絡是深度學習的基礎。而要理解神經網絡,我們就必須先理解它的基本組成單元——神經元(neuron)。

感知器(perceptron)是一種早期的神經元結構,在上個世紀五六十年代就被提出來瞭[1]。現在它在神經網絡中已很少被使用,但理解它有助於理清其它類型神經元的基本結構和設計思路。

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

如上圖所示,一個感知器的定義元素包括:

  • 有多個輸入:x1, x2, x3, …, 它們隻能是0或1。
  • 有一個輸出:output. 隻能是0或1。
  • 每個輸入對應一個權重值:w1, w2, w3, …, 它們可以是任意實數。
  • 有一個閾值:threshold. 可以是任意實數。
  • 輸出output取決於各個輸入的加權求和與閾值threshold的大小,即:如果w1x1 + w2x2 + w3x3 + … > threshold,則輸出output=1,否則輸出output=0。

直觀上理解,感知器相當於一個決策模型。輸入表示進行決策時需要考慮的外在因素或條件,權重表示你對某個外在因素的重視程度,而閾值則表示你對於這個決策事件本身的喜好程度或接受程度。

舉一個例子:假設周末有一個同學聚會,現在你正在決策要不要去參加。你考慮的因素如下:

  • 如果那天天氣好,那麼你就更有意願去參加。用x1=1表示天氣好,x1=0表示天氣不好。你對於天氣這個因素的重視程度為w1=3。
  • 如果某個你討厭的人也去參加聚會,那麼你就興趣索然,不太樂意去瞭。用x2=1表示你討厭的那個人去參加聚會,x2=0表示那個人不參加聚會。對應權重w2=-5,負值表示這個因素的出現會降低你去參加聚會的意願。
  • 但如果你暗戀的一個女孩去參加聚會,那麼你無論如何也是想去的。用x3=1表示那個女孩去參加聚會,x3=0表示她不參加聚會。這個女孩對於你太重要瞭,所以有一個很大的權重:w3=10。

現在假設閾值threshold=2。我們根據前面的規則去計算output,這個計算過程就相當於決策過程。如果output算出來等於1,那麼你就去參加聚會,否則就不去。

決策結果無非是下面幾種:

  • 如果你暗戀的女孩去參加聚會,那麼不管其它因素,你肯定就去瞭。因為權重w3實在太大瞭,不管另外的輸入是多少,都會導致加權求和後超過threshold=2。
  • 你暗戀的那個女孩不去參加聚會,而你討厭的那個人去參加聚會。這時不管天氣如何,你都不會去瞭。
  • 你暗戀的那個女孩和你討厭的那個人都不去參加聚會。那麼你去不去最終取決於天氣怎麼樣。

對於一個給定的感知器來說,它的權重和閾值也是給定的,代表一種決策策略。因此,我們可以通過調整權重和閾值來改變這個策略。

關於閾值threshold,這裡需要指出的一點是,為瞭表達更方便,一般用它的相反數來表達:b=-threshold,這裡的b被稱為偏置(bias)。這樣,前面計算輸出的規則就修改為:如果w1x1 + w2x2 + w3x3 + … + b > 0,則輸出output=1,否則輸出output=0。

再看一下下面這個感知器。權重w1=w2=-2,而b=3。

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

很明顯,隻有當x1=x2=1的時候,output=0,因為(−2)*1+(−2)*1+3=−1,小於0。而其它輸入的情況下,都是output=1。這其實是一個“與非門”!

在計算機科學中,與非門是所有門部件中比較特殊的一個,它可以通過組合的方式表達任何其它的門部件。這被稱為與非門的普適性(Gate Universality)[2]。

既然感知器能夠通過設置恰當的權重和偏置參數,來表達一個與非門,那麼理論上它也就能表達任意其它的門部件。因此,隻要創建足夠多的感知器,那麼它們便能夠通過彼此連接從而組成一個計算機系統。但這似乎沒有什麼值得驚喜的,我們已經有現成的計算機瞭,這隻不過是讓事情復雜化瞭而已。

訓練和學習

單個感知器能做的事情很有限。要做復雜的決策,我們可能需要將多個感知器連接起來。就像下面這個一樣:

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

這個由感知器組成的網絡,包含5個輸入,8個感知器。權重參數的數量,我們可以算一下:5*3+3*4+4*1=31。再加上8個偏置參數,這個網絡總共有39個參數。

這個圖有一點需要說明的是:左邊第一層的每個感知器看起來似乎有4個輸出,而不是1個。但這是個錯覺。實際情況是每個感知器的那唯一的一個輸出分別連接到瞭下一層的各個感知器的輸入上瞭。這種表示法是為瞭方便。輸出端的多條連線隻是表示連接關系,而不表示輸出的個數。

這個感知器網絡還算是一個簡單的網絡,就已經有多達39個參數瞭。而實際中的網絡可能會有上萬個,甚至數十萬個參數。如果手工一個一個地去配置這些參數,恐怕這項任務永遠也完成不瞭瞭。

而神經網絡最有特色的地方就在於這裡。我們不是為網絡指定所有參數,而是提供訓練數據,讓網絡自己在訓練中去學習,在學習過程中為所有參數找到最恰當的值。

如何訓練呢?大體思路是這樣:我們告訴網絡當輸入是某個值的時候,我們期望的輸出是什麼。這樣的每一份訓練數據,稱為訓練樣本(training example)。這個過程相當於老師在教學生某個抽象的知識的時候,舉一個具體例子。一般來說,我們舉的例子越多,就越能表達那個抽象的知識。這在神經網絡的訓練中同樣成立。我們可以向網絡灌入成千上萬個訓練樣本,然後網絡就自動從這些樣本中總結出那份隱藏在背後的抽象的知識。這份知識的體現,就在於網絡的所有權重和偏置參數的取值。

假設各個參數有一個初始值。當我們輸入一個訓練樣本的時候,它會根據當前參數值計算出唯一的一個實際輸出值。這個值可能跟我們期望的輸出值不一樣。想象一下,這時候,我們可以試著調整某些參數的值,讓實際輸出值和期望輸出值盡量接近。當所有的訓練樣本輸入完畢之後,網絡參數也調整到瞭最佳值,這時每一次的實際輸出值和期望輸出值已經無限接近。這樣訓練過程就結束瞭。

假設在訓練過程中,網絡已經對數萬個樣本能夠給出正確(或接近正確)的反應瞭,那麼再給它輸入一個它沒見過的數據,它也應該有很大概率給出我們預期的決策。這就是一個神經網絡工作的原理。

但這裡還有一個問題。在訓練過程中,當實際輸出值和期望輸出值產生差異的時候,我們如何去調整各個參數呢?當然,在思考怎麼做之前,我們應該先弄清楚:通過調整參數的方式獲得期望的輸出,這個方法可行嗎?

實際上,對於感知器網絡來說,這個方法基本不可行。比如在上圖有39個參數的感知器網絡中,如果維持輸入不變,我們改變某個參數的值,那麼最終的輸出基本完全不可預測。它或者從0變到1(或從1變到0),當然也可能維持不變。這個問題的關鍵在於:輸入和輸出都是二進制的,隻能是0或者1。如果把整個網絡看成一個函數(有輸入,有輸出),那麼這個函數不是連續的。

因此,為瞭讓訓練成為可能,我們需要一個輸入和輸出能夠在實數上保持連續的神經網絡。於是,這就出現瞭sigmoid神經元。

sigmoid神經元

sigmoid神經元(sigmoid neuron)是現代神經網絡經常使用的基本結構(當然不是唯一的結構)。它與感知器的結構類似,但有兩個重要的區別。

第一,它的輸入不再限制為0和1,而可以是任意0~1之間的實數。

第二,它的輸出也不再限制為0和1,而是將各個輸入的加權求和再加上偏置參數,經過一個稱為sigmoid函數的計算作為輸出。

具體來說,假設z=w1x1+w2x2+w3x3+…+b,那麼輸出output=σ(z),其中:

σ(z) = 1/(1+e-z)

σ(z)的函數曲線如下:

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

可見,σ(z)是一個平滑、連續的函數。而且,它的輸出也是0~1之間的實數,這個輸出值可以直接作為下一層神經元的輸入,保持在0~1之間。

可以想象,在采用sigmoid神經元組裝神經網絡之後,網絡的輸入和輸出都變為連續的瞭。也就是說,當我們對某個參數的值進行微小的改變的時候,它的輸出也隻是產生微小的改變。這樣就使得逐步調整參數值的訓練成為可能。這個思想如下圖所示:

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

一個經典的應用案例

為瞭說明神經網絡如何具體應用。這裡我們引入一個經典的案例。這個例子來自Michael Nielsen的書《Neural Networks and Deep Learning》[3],是利用神經網絡對於手寫體數字進行識別。當然,這個例子在歷史上,很多研究人員也都做過嘗試。

這裡順便說一句,Michael Nielsen 的這本書真的很贊,沒見過哪一份資料能把神經網絡和深度學習講解得這麼透徹。這本書簡直稱得上是神經網絡的科普聖經,感興趣的初學者一定要讀一讀。

這個問題就是對類似下面這樣的手寫體數字進行識別,區分出它們具體是0到9哪一個數字:

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

這份手寫體數據其實來源於一個公開的數據集,稱為MNIST[4]。其中每個數字,是一張28像素×28像素的黑白圖片,每個像素用一個灰度值表示。

Michael Nielsen采用的神經網絡結構如下:

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

左側第一列圓圈表示網絡的784個輸入(註意圖中沒有畫出全部),對應一張圖片的28×28=784個像素點。每個像素的灰度值,在經過歸一化處理之後,可以表達為0~1之間的數值,作為這裡的輸入。註意:這一列圓圈並不是神經元(雖然看起來像),隻是輸入而已。

中間一列稱為隱藏層(hidden layer),圖中畫出的是15個神經元節點。隱藏層上的每一個節點都與每個輸入連接,也就是說輸入層和隱藏層之間是全連接。

這個神經網絡隻有一層隱藏層,屬於淺層的神經網絡(shallow neural networks)。而真正的深度神經網絡(deep nerual networks),則會有多層隱藏層。

最右側一列是輸出層(output layer),有10個神經元節點,分別代表識別結果是0,1,2,…,9。當然,受sigmoid函數σ(z)的限制,每個輸出也肯定是0~1之間的數。那我們得到一組輸出值之後,我們到底認為識別結果是哪個數字呢?我們可以根據哪個輸出的值最大,我們就認為識別結果就取那個數字。而在訓練的時候,我們期望的輸出形式是:正確的那個數字輸出為1,其它輸出為0。隱藏層和輸出層之間也是全連接。

我們可以算一下這個神經網絡共有多少個參數。權重參數有784*15+15*10=11910個,偏置參數有15+10=25個,總共參數個數為:11910+25=11935個。

對於這個神經網絡的訓練過程,就是要確定這11935個參數。訓練的目標可以粗略概括為:對於每一個訓練樣本,我們期望的那個正確數字,對應的輸出無限接近於1,而其它輸出無限接近於0。

先不說具體的學習方法(下一節會介紹),我們先說一下神經網絡這種編程方式在這一具體問題上取得的結果。根據Michael Nielsen給出的實驗結果,以上述網絡結構為基礎,在未經過調優的情況下,可以輕松達到95%的正確識別率。而核心代碼隻有74行!

在采用瞭深度學習的思路和卷積網絡(convolutional networks)之後,最終達到瞭99.67%的正確識別率。而針對MNIST數據集達到的歷史最佳成績是99.79%的識別率,是由Li Wan, Matthew Zeiler, Sixin Zhang, Yann LeCun, 和 Rob Fergus在2013年做出的。

考慮到這個數據集裡還有一些類似如下這樣難以辨認的數字,這個結果是相當驚人的!它已經超越瞭真正人眼的識別瞭。

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

在本文前面一節,我們已經對神經網絡的訓練過程進行瞭描述,但其中關鍵的一步還沒有介紹,就是如何在這個過程中一步步調整權重和偏置參數的值呢?要講清楚這個問題,我們就必須引入梯度下降算法(gradient descent)。

隨機梯度下降

在訓練的過程中,我們的神經網絡需要有一個實際可行的學習算法,來逐步調整參數。要設計這樣一個學習算法,我們首先要明確訓練的目標。

我們訓練的最終目的,是讓網絡的實際輸出與期望輸出能夠盡量接近。我們需要找到一個表達式來對這種接近程度進行表征。這個表達式被稱為代價函數(cost function)。

一個比較常見的cost function如下所示:

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

這是本文出現的最復雜的一個公式瞭。但不用恐懼,我們對它分析一下,隻要能理解它的主旨就好:

  • x表示一個訓練樣本,即網絡的輸入。其實一個x代表784個輸入。
  • y(x)表示當輸入為x的時候,期望的輸出值;而a表示當輸入為x的時候,實際的輸出值。y(x)和a都分別代表10個輸出值(以數學上的向量來表示)。而它們的差的平方,就表征瞭實際輸出值和期望輸出值的接近程度。越接近,這個差值就越小。
  • n是訓練樣本的數量。假設有5萬個訓練樣本,那麼n就是5萬。因為是多次訓練,所以要除以n對所有訓練樣本求平均值。
  • C(w,b)的表示法,是把cost function看成是網絡中所有權重w和偏置b的函數。為什麼這樣看呢?進行訓練的時候,輸入x是固定的(訓練樣本),不會變。在認為輸入不變的情況下,這個式子就可以看成是w和b的函數。那麼,式子右邊的w和b在哪呢?實際上,在a裡面。y(x)也是固定值,但a是w和b的函數。

總結來說,C(w,b)表征瞭網絡的實際輸出值和期望輸出值的接近程度。越接近,C(w,b)的值就越小。因此,學習的過程就是想辦法降低C(w,b)的過程。而不管C(w,b)的表達形式如何,它是w和b的函數,這就變成瞭一個求函數最小值的最優化問題。

由於C(w,b)的形式比較復雜,參數也非常多,所以直接進行數學上的求解,非常困難。為瞭利用計算機算法解決這一問題,計算機科學傢們提出瞭梯度下降算法(gradient descent)。這個算法本質上是在多維空間中沿著各個維度的切線貢獻的方向,每次向下邁出微小的一步,從而最終抵達最小值。

由於多維空間在視覺上無法體現,所以人們通常會退到三維空間進行類比。當C(w,b)隻有兩個參數的時候,它的函數圖像可以在三維空間裡呈現。如下所示:

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

就好像一個小球在山谷的斜坡上向下不停地滾動,最終就有可能到達谷底。這個理解重新推廣到多維空間內也基本成立。

而由於訓練樣本的數量很大(上萬,幾十萬,甚至更多),直接根據前面的C(w,b)進行計算,計算量會很大,導致學習過程很慢。於是就出現瞭隨機梯度下降(stochastic gradient descent)算法,是對於梯度下降的一個近似。在這個算法中,每次學習不再針對所有的訓練集,而是從訓練集中隨機選擇一部分來計算C(w,b),下一次學習再從剩下的訓練集中隨機選擇一部分來計算,直到把整個訓練集用光。然後再不斷重復這一過程。

深度學習

深度神經網絡(具有多個hidden layer)比淺層神經網絡有更多結構上的優勢,它有能力從多個層次上進行抽象。

機器學習原來如此有趣!全世界最簡單的機器學習入門指南

上圖表達瞭在一個基於深度學習的圖像識別過程中,逐層抽象的過程:

  • 最下面的視覺輸入層,接受圖片的各個像素。
  • 第一層hidden layer,通過比較相鄰元素的不同亮度,識別出圖像的邊界。
  • 第二層hidden layer,將邊界組合,識別出圖像的角和輪廓。
  • 第三層hidden layer,進一步抽象,將角和輪廓進行組合,識別出物體的組成部分。
  • 最終,輸出層識別出具體的物體(是汽車、人,還是動物)。

從上個世紀八九十年代開始,研究人員們不斷嘗試將隨機梯度下降算法應用於深度神經網絡的訓練,但卻碰到瞭梯度消失(vanishing gradient)或梯度爆發(exploding gradient)的問題,導致學習過程異常緩慢,深度神經網絡基本不可用。

然而,從2006年開始,人們開始使用一些新的技術來訓練深度網絡,不斷取得瞭突破。這些技術包括但不限於:

  • 采用卷積網絡(convolutional networks);
  • Regularization (dropout);
  • Rectified linear units;
  • 利用GPU獲得更強的計算能力;
  • 使用更好的cost function;
  • ……

限於篇幅原因,我們有機會下次再討論這些技術細節。

深度學習的優缺點

根據本文前面的介紹,深度學習的優點顯而易見:這是一種全新的編程方式,它不需要我們直接為要解決的問題設計算法和編程,而是針對訓練過程編程。網絡在訓練過程中就能自己學習到解決問題的正確方法,這使得我們可以用簡單的算法來解決復雜的問題,而且在很多領域勝過瞭傳統方法。而訓練數據在這個過程發揮瞭更重要的作用:簡單的算法加上復雜的數據,可能遠勝於復雜的算法加上簡單的數據。

但這項技術的一些缺點我們也不得不警惕:

  • 深度網絡往往包含大量的參數,這從哲學原則上不符合奧卡姆剃刀原則。通常人們要在調整這些參數上面花費巨大的精力;
  • 訓練深度網絡需要大量的計算力和計算時間;
  • 過擬合(Overfitting)問題始終伴隨著神經網絡的訓練過程,學習過慢的問題始終困擾著人們;
  • 我們很難理解神經網絡的工作方式,這容易讓人們產生一種失控的恐懼,同時也對這項技術在一些重要場合的進一步應用制造瞭障礙。

記得前一段時間在朋友圈流傳甚廣BetaCat的故事,講的就是一個人工智能程序,通過自我學習,最終逐漸統治世界的故事。

那麼,現在的人工智能技術的發展,會導致這種情況發生嗎?會導致強人工智能的出現嗎?

恐怕還不太可能。個人感覺,大概有兩個重要因素:

  • 第一,現在的人工智能,它的自我學習還是限定在人們指定的方式,隻能學習解決特定的問題,仍然不是通用的智能。
  • 第二,現在對於人工智能的訓練過程,需要人們為其輸入規整化的訓練數據,系統的輸入輸出仍然對於數據的格式要求很嚴格。這也意味著,即使把人工智能程序連到網上,它也不能像BetaCat那樣對於互聯網上海量的非結構化數據進行學習。

但是,本著實用的角度,這仍然是一種非常吸引人,而且很有前景的技術。

前段時間,朋友圈裡流傳著另外一個故事:一個日本小夥(一位工程師)利用深度學習技術,嘗試為他母親的農場設計瞭分選黃瓜的機器,大大減輕瞭他母親在農忙時節的工作量。

那麼,同樣作為工程師的你,是否也想利用平生所學,為媽媽做一點事呢?

Published in News by Awesome.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *