深度學(xué)習(xí)入門與自然語言的理解
深度學(xué)習(xí)是機器學(xué)習(xí)領(lǐng)域的一個分支,也可以說是該領(lǐng)域近些年來的最大突破之一。
在了解深度學(xué)習(xí)之前,我們應(yīng)當(dāng)回顧一下歷史,同時也搞明白當(dāng)前最火爆的幾個概念到底有著什么樣的關(guān)系。
AI,ML,DL這些年來隨著科技的發(fā)展和國家政策的推進(jìn),人工智能、機器學(xué)習(xí)還有深度學(xué)習(xí)這幾個詞就不斷充斥于耳,但是這些概念卻常常被我們所混淆。
簡單的來講,我們可以認(rèn)為 AI 》 ML 》 DL,也就是說他們之間是包含關(guān)系:
人工智能(AI)是計算機科學(xué)的一個重要研究領(lǐng)域,擁有許多的分支,例如專家系統(tǒng)、進(jìn)化計算、計算機視覺等等。重點在于,如何使用計算機構(gòu)建復(fù)雜的、能夠擁有與人類智慧相同本質(zhì)的東西。
機器學(xué)習(xí)(ML)是實現(xiàn)人工智能的一種方法,或者說一種思路。ML之所以能夠在人工智能領(lǐng)域鶴立雞群,主要是因為它和普通的弱人工智能實現(xiàn)不同,可以使得機器擁有一定的“自適應(yīng)”能力。
機器學(xué)習(xí)的主要思路是,用算法來對大量的數(shù)據(jù)進(jìn)行解析、從中提取特征并學(xué)習(xí)(稱這個過程為“訓(xùn)練”),然后對真實的世界進(jìn)行預(yù)測和判斷。
目前機器學(xué)習(xí)方法的大分類主要有監(jiān)督學(xué)習(xí)、半監(jiān)督學(xué)習(xí)、無監(jiān)督學(xué)習(xí)、集成學(xué)習(xí)、強化學(xué)習(xí)和深度學(xué)習(xí)。傳統(tǒng)的算法包括決策樹、聚類、貝葉斯分類等等。
深度學(xué)習(xí)(DL)是一種實現(xiàn)機器學(xué)習(xí)的技術(shù)。近幾年該領(lǐng)域發(fā)展迅速,帶動機器學(xué)習(xí)領(lǐng)域向許多不同的新領(lǐng)域發(fā)展(無人車、圖像識別、自然語言理解等)。當(dāng)然這也并不意味著深度學(xué)習(xí)就比其他的學(xué)習(xí)方式優(yōu)秀,它只是在特定情況和特定領(lǐng)域下能展現(xiàn)出巨大的優(yōu)勢,并且實現(xiàn)了一定的通用性而已。
CNN看完了這些概念,我們就進(jìn)入深度學(xué)習(xí)領(lǐng)域一窺究竟。首先要說明的是,深度學(xué)習(xí)是基于人工神經(jīng)網(wǎng)絡(luò)的,這是一種由人腦結(jié)構(gòu)啟發(fā)而來的網(wǎng)絡(luò)結(jié)構(gòu),而今天要介紹的CNN(卷積神經(jīng)網(wǎng)絡(luò))正是其中應(yīng)用最為廣泛的一種,目前在計算機視覺、自然語言理解等領(lǐng)域都是首選的訓(xùn)練網(wǎng)絡(luò)。
首先先說一下什么是人工神經(jīng)網(wǎng)絡(luò),你可以類比人類的神經(jīng)元,就是許許多多的神經(jīng)元組成了我們復(fù)雜的神經(jīng)系統(tǒng)。神經(jīng)網(wǎng)絡(luò)也是一樣,它由許許多多的人工神經(jīng)元(簡單的說就是有一個輸入,一個輸出的單元)組成,上層的神經(jīng)元的輸出連接到下層神經(jīng)元的輸入,這樣多層的連接最終就形成了一個復(fù)雜的網(wǎng)絡(luò)。
你也可以把它抽象地想成一個非常非常復(fù)雜的函數(shù),擁有許多許多(數(shù)以萬計的)參數(shù),我們說訓(xùn)練網(wǎng)絡(luò),就是在調(diào)整這些參數(shù)(當(dāng)然,怎么調(diào)整的人類自己心里也沒數(shù),全靠機器自己學(xué)習(xí)),直到它的輸出盡可能地擬合我們想要的結(jié)果為之,這也是我們常把深度學(xué)習(xí)比喻成黑箱的原因之一。
好了,現(xiàn)在我們正式的開始講解CNN網(wǎng)絡(luò),看看神經(jīng)網(wǎng)絡(luò)究竟是如何工作的:
卷積既然是要講卷積神經(jīng)網(wǎng)絡(luò),我們就必須先知道什么是卷積。先想象一個矩陣,以其中的某一個元素為中心,然后和它相鄰的所有元素進(jìn)行某種運算(比如求和),然后移動(滑動)這個中心,直到把整個矩陣都覆蓋一遍,我們得到的最終結(jié)果的和就是一個卷積。
這么干說真是太抽象了,不如直接看這個圖來的實在:
這個矩陣很可能就代表了一個灰度圖像,每個元素就是一個像素,數(shù)字代表著這個像素的灰度值(一般在0~255)。這個滑動的窗口又被叫做內(nèi)核,篩或是特征檢測器,大小可以變化。當(dāng)窗口在整個矩陣?yán)锘瑒恿艘槐橹笏玫降乃薪Y(jié)果的和,就是我們對這個矩陣所求的卷積。
卷積的應(yīng)用計算每個像素和其相鄰像素的平均值可以模糊化一張圖片。
計算像素和其相鄰元素的差值可以進(jìn)行邊緣檢測。
因為邊緣往往是灰度(或者說RGB)變化最明顯的地方,所以相鄰元素間差值比較大的地方往往就是邊緣。如下圖
?。郏荩╤ttp://of1deuret.bkt.clouddn.com/18-1-11/12025490.jpg)
卷積神經(jīng)網(wǎng)絡(luò)卷積神經(jīng)網(wǎng)絡(luò)基本上就是幾層使用非線性激活函數(shù)(比如ReLU和tanh)的卷積來得到結(jié)果的神經(jīng)網(wǎng)絡(luò)。
在傳統(tǒng)的反饋型神經(jīng)網(wǎng)絡(luò)中,我們把每個神經(jīng)元的輸入分別連接到另外的神經(jīng)元的輸出上,這個被稱為全連接層。但在CNN中,我們把輸入層的卷積當(dāng)做輸出,這就意味著,我們是把許多個神經(jīng)元的輸出(一個矩陣的卷積)連接到了一個神經(jīng)元的輸入上。
每一層的篩都不同,往往他們把成百上千個元素結(jié)合計算得到一個結(jié)果,濃縮給下一層。
需要留意的是,CNN中,不同的卷積層之間并不是直接相連的,他們中間夾著一個稱為池化層(Pooling)的特殊的處理層,用于進(jìn)行結(jié)果的規(guī)范化(后面詳解)。
在訓(xùn)練的過程當(dāng)中,CNN會自動地根據(jù)你的目的來學(xué)習(xí)每一層篩的作用(計算方法)。舉個例子,在一個圖像識別的CNN中,第一層可能進(jìn)行邊緣檢測,然后在第二層用這些邊緣作為數(shù)據(jù)來推斷簡單的形狀,最后在更高的層里,用這些形狀來推斷更高級的特性(比如人臉檢測),最后一層則是使用這些高級特性來進(jìn)行分類的分類器。
下面是一個典型的CNN網(wǎng)絡(luò)的結(jié)構(gòu):
在計算過程中有兩點需要特別重視的:定位不變性和復(fù)合性。我們假設(shè)要檢測一張圖片里有沒有大象,因為你的窗口總是要滑動過整個圖像,所以并不必在意大象會出現(xiàn)在圖像的哪個位置,在實際訓(xùn)練中,池化層可以保持?jǐn)?shù)據(jù)的一致性,讓你不用擔(dān)心轉(zhuǎn)換、旋轉(zhuǎn)或是縮放這樣的操作影響數(shù)據(jù)本身。而每個篩都提供了一種使用本層數(shù)據(jù)表示高層數(shù)據(jù)的方法(映射),這就提供了復(fù)合性(多個數(shù)據(jù)復(fù)合成一個數(shù)據(jù))。這就是CNN在計算機視覺中表現(xiàn)優(yōu)異的原因:這和你本能認(rèn)知圖像的過程是一樣的,從點構(gòu)建輪廓,再從輪廓抽取形狀,最后從形狀中提取更多復(fù)雜的對象。
NLP與CNN我們說了很多CNN在計算機視覺方面的應(yīng)用(這也是它最擅長的領(lǐng)域),現(xiàn)在我們看看NLP又是如何與CNN掛鉤的。
在語言理解這個領(lǐng)域,矩陣的單元不再是圖像的像素,而是以矩陣形式表示的句子和文檔。矩陣的每一行相當(dāng)于一個符號(文法中的token),通常會是一個單詞,但也可以是一個字母。
這樣,每一行就是一個表示單詞的向量。一般這個向量可以用或者的方式轉(zhuǎn)換得到,當(dāng)然也可能是將單詞索引到詞匯表里的實數(shù)向量。一個有10個單詞的句子,我們使用一個100維的向量來表示每個詞的話,就會得到一個10*100的矩陣,這就是我們在NLP里的“圖像”了。
有關(guān)如何用向量表示單詞,可以參考此文章
在視覺處理中,我們的篩往往是在一張圖片上四處滑動,但是NLP中,我們用的篩一般和矩陣同寬,因此它只需要上下滑動,至于高度,通常為2-5個詞。綜合上述,一個用于NLP的CNN網(wǎng)絡(luò)可能像下面這樣:
跟視覺處理中很不一樣的是,你并不會在意單詞會在句子的什么地方出現(xiàn),而相鄰的單詞之間也不一定有語義的聯(lián)系(這跟圖片是不一樣的)。在很多語言中,一個短語的組合可以被拆分成很多新的詞,復(fù)合并不明顯。顯然,單詞是以某種方式組合的,比如一個形容詞修飾名詞,但這在更高的層次里到底“意味”著什么并不像在視覺處理上那么顯而易見。
根據(jù)上面分析的,看起來CNN并不能很好的去適應(yīng)NLP的任務(wù),相比之下遞歸神經(jīng)網(wǎng)絡(luò)(RNN)要更加直觀一點,它和我們處理語言的過程(至少是我們所認(rèn)為的)很相似:從左到右地讀取一個序列。不過這并不意味著CNN就沒有用了,有些模型還是能夠起到一定作用的。CNN適用于具有局部相關(guān)性的樣本,語言是滿足這一條件的。
使用CNN的一個很大的目的是因為它很快,在GPU的加速下,卷積的計算更加迅速。比起n元語法,CNN在表達(dá)上也更有效一些。當(dāng)詞匯量變的巨大時,計算超過三元的語法的代價就會變得昂貴起來。卷積能夠很好的自動學(xué)習(xí)表達(dá),而不用獲取整個詞匯表。