閱讀536 返回首頁    go 阿裏雲 go 技術社區[雲棲]


零基礎入門深度學習(六):遞歸神經網絡

遞歸神經網絡是啥  

 

因為神經網絡的輸入層單元個數是固定的,因此必須用循環或者遞歸的方式來處理長度可變的輸入。循環神經網絡實現了前者,通過將長度不定的輸入分割為等長度的小塊,然後再依次輸入到網絡中,從而實現了神經網絡對變長輸入的處理。

 

一個典型的例子是,當我們處理一句話時,我們可以把一句話看作是詞組成的序列,然後,每次向循環神經網絡輸入一個詞,如此循環直至整句話輸入完畢,循環神經網絡將產生對應的輸出。如此,我們就能處理任意長度的句子了。如下圖所示:

 

20170314095948384.jpg

 

然而,有時候把句子看做是詞的序列是不夠的,比如下麵這句話『兩個外語學院的學生』:

 

20170314095957707.jpg

 

上圖顯示了這句話的兩個不同的語法解析樹。可以看出來這句話有歧義,不同的語法解析樹則對應了不同的意思。一個是『兩個外語學院的/學生』,也就是學生可能有許多,但他們來自於兩所外語學校;另一個是『兩個/外語學院的學生』,也就是隻有兩個學生,他們是外語學院的。為了能夠讓模型區分出兩個不同的意思,我們的模型必須能夠按照樹結構去處理信息,而不是序列,這就是遞歸神經網絡的作用。當麵對按照樹/圖結構處理信息更有效的任務時,遞歸神經網絡通常都會獲得不錯的結果。

 

遞歸神經網絡可以把一個樹/圖結構信息編碼為一個向量,也就是把信息映射到一個語義向量空間中。這個語義向量空間滿足某類性質,比如語義相似的向量距離更近。也就是說,如果兩句話(盡管內容不同)它的意思是相似的,那麼把它們分別編碼後的兩個向量的距離也相近;反之,如果兩句話的意思截然不同,那麼編碼後向量的距離則很遠。如下圖所示:

 

20170314100005398.jpg

 

從上圖我們可以看到,遞歸神經網絡將所有的詞、句都映射到一個2維向量空間中。句子『the country of my birth』和句子『the place where I was born』的意思是非常接近的,所以表示它們的兩個向量在向量空間中的距離很近。另外兩個詞『Germany』和『France』因為表示的都是地點,它們的向量與上麵兩句話的向量的距離,就比另外兩個表示時間的詞『Monday』和『Tuesday』的向量的距離近得多。這樣,通過向量的距離,就得到了一種語義的表示。

 

上圖還顯示了自然語言可組合的性質:詞可以組成句、句可以組成段落、段落可以組成篇章,而更高層的語義取決於底層的語義以及它們的組合方式。遞歸神經網絡是一種表示學習,它可以將詞、句、段、篇按照他們的語義映射到同一個向量空間中,也就是把可組合(樹/圖結構)的信息表示為一個個有意義的向量。比如上麵這個例子,遞歸神經網絡把句子"the country of my birth"表示為二維向量[1,5]。有了這個『編碼器』之後,我們就可以以這些有意義的向量為基礎去完成更高級的任務(比如情感分析等)。如下圖所示,遞歸神經網絡在做情感分析時,可以比較好地處理否定句,這是勝過其它一些模型的:

 

20170314100020172.jpg

 

在上圖中,藍色表示正麵評價,紅色表示負麵評價。每個節點是一個向量,這個向量表達了以它為根的子樹的情感評價。比如"intelligent humor"是正麵評價,而"care about cleverness wit or any other kind of intelligent humor"是中性評價。我們可以看到,模型能夠正確的處理doesn't的含義,將正麵評價轉變為負麵評價。

 

盡管遞歸神經網絡具有更為強大的表示能力,但是在實際應用中並不太流行。其中一個主要原因是,遞歸神經網絡的輸入是樹/圖結構,而這種結構需要花費很多人工去標注。想象一下,如果我們用循環神經網絡處理句子,那麼我們可以直接把句子作為輸入。然而,如果我們用遞歸神經網絡處理句子,我們就必須把每個句子標注為語法解析樹的形式,這無疑要花費非常大的精力。很多時候,相對於遞歸神經網絡能夠帶來的性能提升,這個投入是不太劃算的。

 

我們已經基本了解了遞歸神經網絡是做什麼用的,接下來,我們將探討它的算法細節。

 

遞歸神經網絡的前向計算  

 

接下來,我們詳細介紹一下遞歸神經網絡是如何處理樹/圖結構的信息的。在這裏,我們以處理樹型信息為例進行介紹。

 

遞歸神經網絡的輸入是兩個子節點(也可以是多個),輸出就是將這兩個子節點編碼後產生的父節點,父節點的維度和每個子節點是相同的。如下圖所示:

 

20170314100031862.jpg

 

C1和C2分別是表示兩個子節點的向量,P是表示父節點的向量。子節點和父節點組成一個全連接神經網絡,也就是子節點的每個神經元都和父節點的每個神經元兩兩相連。我們用矩陣表示這些連接上的權重,它的維度將是d X 2d,其中,d表示每個節點的維度。父節點的計算公式可以寫成:

 

20170314100037933.jpg

 

在上式中,tanh是激活函數(當然也可以用其它的激活函數),b是偏置項,它也是一個維度為d的向量。如果讀過前麵的文章,相信大家已經非常熟悉這些計算了,在此不做過多的解釋了。

 

然後,我們把產生的父節點的向量和其他子節點的向量再次作為網絡的輸入,再次產生它們的父節點。如此遞歸下去,直至整棵樹處理完畢。最終,我們將得到根節點的向量,我們可以認為它是對整棵樹的表示,這樣我們就實現了把樹映射為一個向量。在下圖中,我們使用遞歸神經網絡處理一棵樹,最終得到的向量P3,就是對整棵樹的表示:

 

20170314100044674.jpg

 

舉個例子,我們使用遞歸神將網絡將『兩個外語學校的學生』映射為一個向量,如下圖所示:

 

20170314100052551.jpg

 

最後得到的向量P3就是對整個句子『兩個外語學校的學生』的表示。由於整個結構是遞歸的,不僅僅是根節點,事實上每個節點都是以其為根的子樹的表示。比如,在左邊的這棵樹中,向量P2是短語『外語學院的學生』的表示,而向量P1是短語『外語學院的』的表示。

 

式1就是遞歸神經網絡的前向計算算法。它和全連接神經網絡的計算沒有什麼區別,隻是在輸入的過程中需要根據輸入的樹結構依次輸入每個子節點。

 

需要特別注意的是,遞歸神經網絡的權重W和偏置項b在所有的節點都是共享的。

 

遞歸神經網絡的訓練  

 

20170314100059372.jpg

 

誤差項的傳遞

 

 

首先,我們先推導將誤差從父節點傳遞到子節點的公式,如下圖:

 

20170314100107783.jpg

 

20170314100114591.jpg

 

有了上式,我們就可以把它表示為矩陣形式,從而得到一個向量化表達:

 

20170314100120484.jpg

 

20170314100128515.jpg

 

20170314100136911.jpg

 

20170314100145989.jpg

 

權重梯度的計算

 

 

根據加權輸入的計算公式:

 

20170314100154563.jpg

 

那麼,我們可以求得誤差函數在第l層對權重的梯度為:

 

20170314100202196.jpg

 

20170314100210794.jpg

 

式3就是第l層權重項的梯度計算公式。我們知道,由於權重是在所有層共享的,所以和循環神經網絡一樣,遞歸神經網絡的最終權重梯度是各個層權重梯度之和。即:

 

20170314100221496.jpg

 

因為循環神經網絡的證明過程已經在《零基礎入門深度學習(三) :卷積神經網絡》一文中給出,因此,遞歸神經網絡『為什麼最終梯度是各層梯度之和』的證明就留給讀者自行完成啦。

 

20170314100229816.jpg

 

式5是第l層偏置項的梯度,那麼最終的偏置項梯度是各個層偏置項梯度之和,即:

 

20170314100237933.jpg

 

權重更新

 

 

如果使用梯度下降優化算法,那麼權重更新公式為:

 

20170314100246243.jpg

 

把式6帶入到上式,即可完成偏置項的更新。

 

這就是遞歸神經網絡的訓練算法BPTS。由於我們有了前麵幾篇文章的基礎,相信讀者們理解BPTS算法也會比較容易。

 

遞歸神經網絡的實現  

 

現在,我們實現一個處理樹型結構的遞歸神經網絡。

 

在文件的開頭,加入如下代碼:

 

20170314100255203.jpg

 

上述四行代碼非常簡單,沒有什麼需要解釋的。IdentityActivator激活函數是在我們介紹卷積神經網絡時寫的,現在引用一下它。

 

我們首先定義一個樹節點結構,這樣,我們就可以用它保存卷積神經網絡生成的整棵樹:

 

20170314100306767.jpg

 

接下來,我們把遞歸神經網絡的實現代碼都放在RecursiveLayer類中,下麵是這個類的構造函數:

 

20170314100317314.jpg

 

下麵是前向計算的實現:

 

   20170314100328408.jpg

 

forward函數接收一係列的樹節點對象作為輸入,然後,遞歸神經網絡將這些樹節點作為子節點,並計算它們的父節點。最後,將計算的父節點保存在self.root變量中。

 

上麵用到的concatenate函數,是將各個子節點中的數據拚接成一個長向量,其代碼如下:

 

   20170314100337725.jpg

 

下麵是反向傳播算法BPTS的實現:

 

20170314100347329.jpg

20170314100400291.jpg

 

在上述算法中,calc_delta函數和calc_gradient函數分別計算各個節點的20170314100725733.jpg以及最終的梯度。它們都采用遞歸算法,先序遍曆整個樹,並逐一完成每個節點的計算。

 

下麵是梯度下降算法的實現(沒有weight decay),這個非常簡單:

 

20170314100410455.jpg

 

以上就是遞歸神經網絡的實現,總共100行左右,和上一篇文章的LSTM相比簡單多了。

 

最後,我們用梯度檢查來驗證程序的正確性:

 

20170314100420354.jpg

 

下麵是梯度檢查的結果,完全正確,OH YEAH!

 

20170314100440145.jpg

 

遞歸神經網絡的應用  

 

自然語言和自然場景解析

 

 

在自然語言處理任務中,如果我們能夠實現一個解析器,將自然語言解析為語法樹,那麼毫無疑問,這將大大提升我們對自然語言的處理能力。解析器如下所示:

 

20170314100455501.jpg

 

可以看出,遞歸神經網絡能夠完成句子的語法分析,並產生一個語法解析樹。

除了自然語言之外,自然場景也具有可組合的性質。因此,我們可以用類似的模型完成自然場景的解析,如下圖所示:

 

20170314100505639.jpg

 

兩種不同的場景,可以用相同的遞歸神經網絡模型來實現。我們以第一個場景,自然語言解析為例。

 

我們希望將一句話逐字輸入到神經網絡中,然後,神經網絡返回一個解析好的樹。為了做到這一點,我們需要給神經網絡再加上一層,負責打分。分數越高,說明兩個子節點結合更加緊密,分數越低,說明兩個子節點結合更鬆散。如下圖所示:

 

20170314100513493.jpg

 

一旦這個打分函數訓練好了(也就是矩陣U的各項值變為合適的值),我們就可以利用貪心算法來實現句子的解析。第一步,我們先將詞按照順序兩兩輸入神經網絡,得到第一組打分:

 

20170314100521459.jpg

 

我們發現,現在分數最高的是第一組,The cat,說明它們的結合是最緊密的。這樣,我們可以先將它們組合為一個節點。然後,再次兩兩計算相鄰子節點的打分:

 

20170314100530924.jpg

 

現在,分數最高的是最後一組,the mat。於是,我們將它們組合為一個節點,再兩兩計算相鄰節點的打分:

 

20170314100539854.jpg

 

這時,我們發現最高的分數是on the mat,把它們組合為一個節點,繼續兩兩計算相鄰節點的打分......最終,我們就能夠得到整個解析樹:

 

20170314100550584.jpg

 

現在,我們困惑這樣牛逼的打分函數score是怎樣訓練出來的呢?我們需要定義一個目標函數。這裏,我們使用Max-Margin目標函數。它的定義如下:

 

20170314100600441.jpg

 

20170314100611915.jpg

 

具體細節,讀者可以查閱『參考資料3』的論文。

 

小結  

 

我們在係列文章中已經介紹的全連接神經網絡、卷積神經網絡、循環神經網絡和遞歸神經網絡,在訓練時都使用了監督學習(Supervised Learning)作為訓練方法。在監督學習中,每個訓練樣本既包括輸入特征X,也包括標記Y,即樣本20170314100622191.jpg

 

然而,很多情況下,我們無法獲得形如20170314100629857.jpg的樣本,這時,我們就不能采用監督學習的方法。在接下來的幾篇文章中,我們重點介紹另外一種學習方法:增強學習(Reinforcement Learning)。在了解增強學習的主要算法之後,我們還將介紹著名的圍棋軟件AlphaGo,它是一個把監督學習和增強學習進行完美結合的案例。

 原文發布時間為:2017-03-14

本文來自雲棲社區合作夥伴DBAplus

最後更新:2017-05-16 10:32:07

  上一篇:go  (七)相親
  下一篇:go  (六)柳暗花明