引言
在之前我們學習的各種内容中(圖像識别啊,分類問題啊),我們的輸入在時間上沒有先後順序。然而在語音識别、自然語言處理當中,我們的各項輸入是有先後順序的。(例如句子當中詞的先後順序,聲音來源的先後順序)為了捕獲這種時間順序相關的特征,我們引入循環序列模型。
one hot 表示
在自然語言處理當中,如何對每一個單詞進行表示是一個重要問題。在這裡我們采用one-hot表示方法。
假如我們訓練的模型當中詞彙量為3個,那麼我們對三個單詞分别編碼為:
[1, 0, 0]
[0, 1 ,0]
[0, 0, 1]
可以看出,每個編碼都是一個長度為3的一維向量,并且向量中有且隻有一個位置是1,這就是one- hot
我們可能會想,為什麼不直接用0, 1, 2這樣進行編碼呢?還能省點空間。原因是因為這樣編碼會導緻本來本啥關系的詞突然出現了序關系,這會對模型産生影響。(蘋果沒有道理比鴨梨大,反之亦然)還有一個原因是,直接編碼會導緻元素之間的距離不再相同(蘋果=1, 鴨梨=2, 雞蛋 = 0, 雞蛋與蘋果之間的距離小于雞蛋和鴨梨之間的距離),這會給各個詞之間添加莫名其妙的關系。
RNN模型
引入RNN的意義就是要利用好上下文的資訊。為了簡單起見,我們先構造一個RNN模型,使得模型可以利用上文的資訊。
一個顯然的想法是,既然需要利用上文資訊,那麼每一個單詞X的輸出,既要受到自己X的影響,同時也應該收到上一個單詞産生的激活函數的影響。
前向傳播過程:
一個RNN基本單元如下所示:
可以看出,對于每一個時間片激活函數值a,它既受到目前X的影響,又受到上一時間片激活函數值的影響。
反向傳播
我們可以知道,每一個時間片的激活函數值,既對自己的輸出y有貢獻,同時也對後面所有的y都存在貢獻。
是以和以往不同,這次的反向傳播增加了時間次元的傳播。我們需要按照時間順序進行倒推,逐漸計算各個參數的偏導。
語言模型和序列生成
這裡面僅僅介紹了什麼是語言模型,以及如何利用語言模型生成序列。
語言模型的作用是算出一句話是人話的機率。(确定 我 吃 飯, 飯 吃 我哪個更像是人話)
訓練一個語言模型:
訓練集:我們需要一個大的語料庫(裡面有一堆句子)
每一個RNN單元:
輸入:單詞的one-hot
輸出:下一個單詞可能是誰的機率(可能是softmax)
訓練過程:
對于每一句話, 我們令每一個單詞為yi
- 第一步,設定初始x0 ,a0都是0向量,獲得y1_hat,這個輸出表示在什麼都沒有的情況下語言模型預測第一個單詞的機率
- 第二步,輸入y1,得到y2_hat,表示明确知道第一個單詞是y1的前提下獲得第二個單詞的機率
- 依次進行,直到yi走到最後
對于每一個y和y_hat, 利用交叉熵求出代價函數,對模型進行訓練。
利用語言模型生成序列采樣
- 第一步,設定初始x0 ,a0都是0向量,獲得第一個單詞的機率分布,利用這個機率分布随機挑選一個單詞y進行輸出。
- 第二步,将上一個輸出的y當作輸入,以預測下一個單詞。
- 依次進行,直到預測出終止單詞或達到最大輸出限制。
梯度消失和梯度爆炸
之前我們深層神經網絡的梯度問題主要出在層數過深上,而RNN的梯度問題出現在時間次元上。RNN的梯度消失可以這樣了解,第一個單詞的激活函數,很難對最後一個單詞造成影響,因為時間跨度過大,進而也導緻,最後一個單詞的偏導數很難反向傳遞到第一個單詞的各項參數。
對于梯度爆炸,我們可以通過設定梯度上限來解決。
然而對于梯度消失,我們就沒有太多操作空間了.
我們回想一下深層神經網絡是怎麼解決的:ResNets建立了可以跨越中間層的連接配接,變相起到了減少層數的作用(因為被跨越的層數可以比較容易地被忽略),那RNN是不是也可以利用這一點解決梯度消失呢?
答案是可以的,下面的GRU單元和LSTM單元在我看來也是這種思想。下面隻簡要介紹LSTM
LSTM
整體的網絡傳播邏輯和RNN一緻,隻不過更換了單元結構。
我們可以看到,每一次的c值和a值都與上一次的輸入相關。這個相關性的大小由各個gate來控制,通過合适的gate值,我們就可以讓前面某個單詞的c值和a值盡可能地儲存到後面,提升單元子產品的記憶能力。
雙向神經網絡
之前挖了個坑,每一個單詞的輸出可能與上文有關,還可能與下文有關,然而我們上面提到的模型都隻能利用上文的資訊。是以我們引入雙向神經網絡。
我們建構兩個網絡,正序跑一遍,逆序跑一邊,每一個單詞的輸出由兩個網絡的輸出共同決定,這樣一來就同時利用上下文的資訊。
深層循環神經網絡
我們上面介紹的網絡中,每個RNN單元隻有一層。實際應用中,RNN單元在空間次元上也可以疊加。
但是要注意的是,RNN本身由于時間軸因素已經足夠複雜,是以RNN的層數不應該過高。常見的作法是在輸出上面套用普通的神經網絡以增加層數,提升學習能力。