這篇文章主要摘自李宏毅老師機器學習課程的內容, 推薦大家去看原視頻。我主要是做CV的,對NLP不算特別熟,如有理解錯誤的地方歡迎大家指正。

單詞的表示法:1-of-N encoding

首先對一個句子,我們將每個辭彙用一個vector來表示。怎麼表示呢,我們假設有一個很大的詞典,比如說有n個單詞,那麼每個單詞的表示就是一個n+1維的向量,多的一個維度用於存放那些詞典裡面沒有的辭彙。每個向量都只有一個維度是1,其餘是0

RNN基礎結構

好了單詞的表示我們知道了,那麼怎麼去理解一個句子呢?如果按照傳統的DNN方法,我們把一個單詞扔進一個DNN,那麼出來的時候能夠得到一個它的分數,那麼也許我們能夠知道它的語義。比如說有一個句子「arrive Taipei on Novermber」,我們把每一個單詞扔進一個DNN,那可能出來的時候就能知道Taipei屬於目的地,Novermber屬於出發時間。

但是事情顯然沒有這麼簡單。如下圖,兩個句子裡面都有臺北,但是明顯語義不一樣,一個是到達,一個是離開。

所以我們要解決上下文的,也就是說,我們要讓NN擁有記憶力——這種NN就叫做Recurrent Nural Network, 也就是RNN。其實它的原理很簡單。在輸入一個句子(我們稱之為一個序列)的時候,我們將序列中的前一個元素的hidden layer的neural都會存起來,我們稱之為memory。下一次有input的時候,它會去考慮前一次輸入的memory。在下圖中,我們設 a_1,a_2 為memory

假設我們的input是一系列sequence,[1,1],[1,1][2,2]...這裡只是說為了示例這麼表示哈,如果說我們用前面說的1-of-N embedding來表示這個序列的話,一個m個單詞的句子應該是由m個n+1長的one-hot向量來表示的。

我們在初次輸入前,需要將memory初始化,也就是a1,a2初始值,我們這裡為了方便假設是0。NN我們先用一個只有一層的神經網路來表示。

我們輸入 x_1 , 也就是序列的第一個元素,這裡是[1,1],那麼hidden layer(也就是綠色神經元)會同時接收initialize 的memory [0,0]和input [1, 1], 那麼output是[4,4]

我們把第一個元素hidden-layer的output 2存到memory a_1,a_2 中,接下來輸入序列的第二個元素[1,1],此時memory為[2,2],那麼hidden layer output是[6,6],output是[12,12]

我們可以發現雖然input是一樣的,但是output可能不一樣,因為memory是不一樣的。此時我們把之前Hidden layer的值[6,6]更新到memory,所以輸入[2,2]的output是[32,32]。所以可以發現,在RNN裡面,如果調換順序,那麼output會不一樣的(因為Memory不一樣),所以它切實考慮到了句子順序的問題。

因此我們來看之前我們示例的句子,首先我們輸入arrive,得到 a_1 ,這個就是下一個單詞Taipei輸入時的memory, 後面的也是類似的。

這麼看起來有人也許會覺得這是不是有多個NN啊?其實不是的同一個network在不同的時間點使用了,而不是說有多個network。實際上每個元素經過的hidden layer的參數是一樣的。而由於memory的不同,最後得到的output是不一樣的。那麼開頭我們示例的leave taipei和arrive taipei,因為存在memeory裡面的值不一樣(leave和arrive的含義不一樣),所以最後taipei的詞性的output會不一樣。

我們把一層的NN拓展到DNN,也是一個原理。有多個層的時候,每一層hidden layer都會存儲前一個詞的Memory

上面的我們一直在講得Memory為hidden layer的output的這種叫Elman Network,另外一種基礎RNN結構叫Jordan Network,讀的是output的值作為memory,而不是hidden layer的output,據說Jordan Network的效果是更好一些的。

Bidirectional RNN

這個就是說train一個正序句子的RNN,又訓練一個逆向的RNN,把兩個不同的方向output結合起來產生 y_t 。這種的好處是看的範圍會更加廣一些。

以上就是RNN中最簡單的基礎知識介紹啦。


推薦閱讀:
相關文章