這節課中介紹了迴圈神經網路的第一部分,主要介紹了迴圈神經網路的基本概念,vanilla迴圈網路架構,RNN的一些應用,vanilla架構的問題,更先進的rnn架構比如GRU和LSTM
vanilla迴圈網路架構
在之前的討論中,我們往往以影像分類問題為基礎然後展開,訓練網路,輸入影像,然後我們可以得到相應的影像標籤,但在實際中,我們可能還會需要處理一些序列問題,比如說輸入一個影像,我們希望能得到一組單詞,表示影像的內容,或者說輸入一個影片也就是輸入一系列的影像,得到一個標籤,或者說輸入一組單詞,我們能夠將其翻譯為另一種語言的單詞:
迴圈網路的核心概念大致如上圖,簡單來說,我們依次使用不同的輸入向量和上一個狀態,經過一個權重矩陣,實現更新得到新的狀態,然會不斷重複上述過程直至輸入向量全部輸入,注意這裡我們採用的權重矩陣每一步迴圈都是相同的,我們以many to many計算圖為例:
我們可以看到首先初始化w與h0,然後x1,h0一起與fw作用得到h1之後,重複上述操作,一直得到h2,h3等等,同時每個隱藏層都會輸出一個y,用於表示對下一個x的預測結果,然後我們可以利用這個預測結果與實際的下一個輸入向量之間的差距,作為損失,反向傳播對權重矩陣進行更新。
最常用最簡單的迴圈神經網路就是vanilla RNN:
可以看到它給出了h與y的計算方式,其餘結構就和我們之前提到的一樣,下面是一個具體的例子,可以看到我們使用了“hello”這個單詞來訓練我們的迴圈神經網路。
應用與理解
我們實際上可以使用上述迴圈網路實現很多有意思的事情,比如說我們可以將莎士比亞的作品作為訓練集,然後讓ai來以莎士比亞的風格來自己創作:
我們可以看到經過不斷不斷的訓練,ai逐漸能輸出更加像樣的結果了,儘管從具體內容上來說還是狗屁不通
同樣,我們也可以讓神經網路去模仿寫數學證明或者一些程式碼,它也能模仿的有模有樣:
如果我們將隱藏層視覺化,並且選取其中可理解的一些結果觀察,我們可以發現一些有意思的一些事情:
實際上隱藏層特定地學習了我們輸入的文字序列中的某些資訊,比如句子的長度資訊,if語句資訊以及註釋資訊等等
我們可以將RNN與CNN結合起來,使用CNN來提取特徵向量,然後我們使用RNN來將特徵向量作為新的資訊加入,這樣能夠更好地訓練我們的網路,為特徵向量建立新的權重矩陣:
然後我們可以得到一些非常好的結果:
vanilla架構的問題
vanilla架構最大的問題就是反向傳播過程中,有的路徑太長,需要經過許多權重矩陣以及tanh(而我們知道tanh存在著殺死梯度的問題),如果矩陣的奇異值大於1,會導致在這個過程中梯度不斷增大,直到爆炸,如果奇異值小於1,則會出現梯度消失的現象,這兩種情況都會導致vanilla架構只有短期記憶,不能很好地學習,對於第一種,我們可以將梯度縮小,雖然這樣已經不是原本的梯度,但還是可以得到不錯的效果,對於第二種情況,我們則需要改變RNN網路的架構,這就有了LSTM架構:
LSTM
LSTM採取如下的架構:
把h層放大為4h,然後分成4個小h,每個h分別經過sigmoid,sigmoid,sigmoid以及tanh,分別得到輸入門,遺忘門,輸出門以及門門,其中輸入門表示我們是否向神經元中輸入資訊,是一個介於0-1之間的值,遺忘門表示是否要遺忘上一次輸入的資訊,也是一個0-1之間的值,門門表示我們要向神經元中輸入多少資訊,輸出門表述我們最終要輸出多少資訊
從\(c_{t}\)的推導式中我們也可以看出,首先f遺忘門與前一個c值哈達馬積(兩個矩陣對應位置元素相乘),表述我們要忘記多少上一層的資訊,然後再加上i與g的哈達馬積,表示我們要輸入多少資訊。
透過這樣的方法,我們實際上設計了一條新的反向傳播路徑,只需要先經過一個+號(我們知道反向傳播梯度與上游梯度相同),然後再經過一個對應元素相乘的反向傳播而不是和矩陣W相乘
實際上這種設計與殘差網路的設計有著相同的直覺,它們都提供了一條求解梯度的高速公路,來防止太長的反向傳播路徑
至於LSTM這種具體結構式怎麼想出來的,“it is called reasearch trial and error”hhh
最後介紹幾種不同的RNN結構的變體:
多層RNN架構(層數一般不會太深):
GRU(與LSTM思想大致相同,只是構建了不同的高速公路)
以及使用進化搜尋研究了10000種不同的RNN架構:
實踐證明我們使用LSTM架構一般就能得到較好的效果