循環(huán)神經(jīng)網(wǎng)絡(luò)-第一周-吳恩達 Deep Learning Specialization 學(xué)習(xí)筆記

序列模型 sequence model

在前面已經(jīng)講到不同的神經(jīng)網(wǎng)絡(luò)架構(gòu)在處理不同類型的任務(wù)時具有不同的表現(xiàn),循環(huán)神經(jīng)網(wǎng)絡(luò) Recurrent neural network 在處理帶有前后序列性質(zhì)的數(shù)據(jù)如自然語言處理、機器翻譯、連續(xù)動作識別等應(yīng)用具有非常明顯的先天優(yōu)勢,RNN 之所以如此命名是因為我們會對序列中的每一個元素執(zhí)行同樣的操作,因此可以視作一種循環(huán)機制。

The RNN performs the same task for each element in the sequence.

在 RNN 中,記憶被定義為前序隱藏層的輸出。

Memory is defined as the output of hidden layer neurons, which will serve as additional input to the network during next training step.

符號約定

為了便于統(tǒng)一符號注解,在后續(xù)的課程中,對于一個輸入序列 x ,x<i> 表示其中的第 i 個元素,y<i> 表示對應(yīng)輸出序列的第 i 個元素,在很多論文中也用 h 來表示輸出。在時序數(shù)據(jù)中,由于引入了長度的概念,因此用 Tx 來表示一個輸入序列的長度,用 Ty 來表示一個輸出序列的長度。對于多個序列來說,x(i)<t> 表示第 i 個輸入中的第 t 個元素,相應(yīng)地,對于第 i 個輸入序列的長度用 Tx(i) 來表示,對于第 i 個輸出序列的長度用 Ty(i) 來表示,值得注意的是在實際應(yīng)用中 Tx(i) 與 Ty(i) 不一定相等。

在自然語言相關(guān)的時序數(shù)據(jù)處理中,為了便于統(tǒng)一的表示序列中的數(shù)據(jù),在處理具體的樣本前要先建立一個詞匯表 Vocabulary 或稱字典 Dictionary,再根據(jù)各個單詞在詞匯表中的索引位置來對輸入樣本中的詞匯進行 one-hot encoding,具體的操作過程在前面的 情感分析 的練習(xí)中已經(jīng)有過接觸和體會,這里就不再贅述。

另外需要注意的一點是如果最終在輸入中出現(xiàn)字典中沒有的輸入詞匯,則可以創(chuàng)建一個符號 Token 如 <UNK> 來標識這些未知詞匯,部分應(yīng)用中還會用 <EOS> 來代表句子的結(jié)束。

Word representation by one-hot encoding

循環(huán)神經(jīng)網(wǎng)絡(luò)模型建立

在前面的情感分析練習(xí)中已經(jīng)看到使用標準形式的多層神經(jīng)網(wǎng)絡(luò)在處理類似的語言類任務(wù)時表現(xiàn)并不突出,普通形式的神經(jīng)網(wǎng)絡(luò)在處理序列性質(zhì)的數(shù)據(jù)時面臨的主要問題有:

  1. 對于不同的輸入和輸出來說,樣本可能會有不同的長度

  2. 與在 CNN 中的情形類似,標準的多層神經(jīng)網(wǎng)絡(luò)不同單元之間無法共享在語句的不同位置學(xué)習(xí)到的特征

Why not Standard Neural Network

典型循環(huán)神經(jīng)網(wǎng)絡(luò)的工作機制

假設(shè)我們按照從左到右的方式處理一個語句,對于輸入語句的第一個單詞或稱元素 x<1>,網(wǎng)絡(luò)的第一步會計算相應(yīng)的預(yù)測 ?<1>,此后對于語句中的第二個輸入元素 x<2> 來說,網(wǎng)絡(luò)在預(yù)測 ?<2> 時會接收上一步的激活信息 a<1>,以此類推。由于網(wǎng)絡(luò)遵循從左到右的順序逐個對語句中的元素進行處理,因此不同單詞的處理之間存在一個時間步 time step 的概念,但對于同一層來說不同時間步之間的參數(shù)是相同的,也即圖中不同時間步中的 Wax 為同一套參數(shù)。由于對于下圖所示的循環(huán)神經(jīng)網(wǎng)絡(luò)來說,時間步在后的網(wǎng)絡(luò)只參考時間步在前的信息,因此這些參考信息的流動是單向的,對于雙向傳遞的循環(huán)神經(jīng)網(wǎng)絡(luò) Bidirectional Recurrent Neural Network,BRNN 后續(xù)會做介紹。

Typical architecture of RNN

循環(huán)神經(jīng)網(wǎng)絡(luò)的前向傳播

在實際的 RNN 實現(xiàn)中,每一個時間步的 RNN 都可以被看作是一個 2 層的全連接的神經(jīng)網(wǎng)絡(luò),在此基礎(chǔ)上除了可以橫向的多個時間步進行傳遞,還可以將輸出沿縱向傳遞給更深的層次,進而實現(xiàn) RNN 的堆疊。

A single time step of RNN in details

對于第一個單詞的前續(xù)輸入 a<0> 一般設(shè)置為元素全 0 的向量,此后對于輸入的第一個元素有:

  • a<1> = g(Waaa<0> + Waxx<1> + ba)
  • ?<1> = g'(Wyaa<1> + by)

更一般地,對于第 t 個時間步來說:

  • a<t> = g(Waaa<t-1> + Waxx<t> + ba)
  • ?<t> = g'(Wyaa<t> + by)

為了使得前向傳播的公式更加簡潔,上式可以改寫為:

  • a<t> = g(Wa [a<t-1>, x<t>] + ba)
  • ?<t> = g'(Wya<t> + by)

其中 Wa 為將 Waa 和 Wax 水平并列放置的結(jié)果,即 Wa = [Waa | Wax],而 [a<t-1>, x<t>] 為上下放置的結(jié)果,相應(yīng)的在 Numpy 中可以采用 hstack((Waa, Wax)) 和 vstack((a<t-1>, x<t>)) 來實現(xiàn)。

與在 CNN 中常用 ReLU 做激活函數(shù)不同的是在 RNN 中常用的激活函數(shù)是 tanh,對于預(yù)測部分的激活函數(shù)則可以根據(jù)實際應(yīng)用使用 Sigmoid 或 Softmax 等。

循環(huán)神經(jīng)網(wǎng)絡(luò)的反向傳播

在討論反向傳播之前需要針對任意一個時間步定義一個損失函數(shù),在這里仍然采用交叉熵函數(shù):

  • L<t>(?<t>, y<t>) = -y<t>log?<t> - (1 - y<t>)log(1 - ?<t>)

相應(yīng)地,對于整個輸入序列來說則可以定義成本函數(shù)如下:

  • L(?, y) = ΣL<t>(?<t>, y<t>), t = 1, 2, 3, ... , Tx

具體的計算過程類似前面講到的神經(jīng)網(wǎng)絡(luò)的反向傳播計算,先計算前向傳播(綠色箭頭),并計算各個節(jié)點的損失函數(shù),最終再通過計算圖計算反向傳播(紅色箭頭),通過梯度下降來完成參數(shù)的更新。由于在序列類型的輸入中引入了時間的概念,因此這個過程中的反向傳播稱為 Backpropagation through time。

Forward and backpropogation

不同類型的循環(huán)神經(jīng)網(wǎng)絡(luò)

上面討論的 RNN 中 Tx 與 Ty 是等長的,而現(xiàn)實中的情形不總是如此。對于下面的這些不同類型的序列數(shù)據(jù)來說,有些時候輸入僅是一維的,而對應(yīng)的輸出則是多維的,在另一些情形下輸入有些時候是多維的,而輸出則是一維的。

Examples of sequence data

如果將之前的循環(huán)神經(jīng)網(wǎng)絡(luò)稱為 many-to-many 的架構(gòu),那么對于類似電影情感分析類的多個輸入、單個輸出的 RNN 則可以稱為 many-to-one RNN:

Many-to-one architecture

反之對于音樂生成類單個輸入、多個輸出的架構(gòu)則可以稱為 one-to-many RNN:

One-to-many architecture

同時對于 many-to-many RNN 也存在輸入和輸出均為多個但又不相等的情形:

Many-to-many RNN with different input and output length

語言建模和序列生成

簡單說來語言建模的目的就是希望可以對于多個不同的語句組合給予一個概率評價,從而確定一個最高概率的語句組合。通過 RNN 進行語言模型的構(gòu)建過程如下:

  1. 首先需要獲取一個大型的語言信息訓(xùn)練集,這個集合在自然語言處理的語境中常被稱為語料庫 corpus

  2. 在此基礎(chǔ)上需要針對訓(xùn)練集中的詞匯通過 one-hot encoding 的形式將其符號化,以此作為網(wǎng)絡(luò)的輸入

  3. 通過對于網(wǎng)絡(luò)的訓(xùn)練確定不同語句及組合方式在尋常的表達中出現(xiàn)的概率,此時的輸出激活函數(shù)需要采用 softmax

使用循環(huán)神經(jīng)網(wǎng)絡(luò)進行語言模型訓(xùn)練時的一個具體的細節(jié)是會令 x<t> = y<t-1>,也即不斷的在后續(xù)的節(jié)點告知前面語句的正確輸入信息,在此基礎(chǔ)上計算在已知輸入為某個詞語的條件下語料庫中所有詞匯出現(xiàn)的概率,其本質(zhì)上是通過網(wǎng)絡(luò)計算一系列的條件概率。

RNN model is essentially a serials of conditional probability

抽樣獲取新序列

在訓(xùn)練完成后,可以通過采用 np.random.choice( ) 在詞匯表中隨機選取詞匯構(gòu)成新的序列組合來對模型進行測試,以直觀的了解模型學(xué)到了什么。

Random sampling and testing

這里需要注意的是在構(gòu)建語言模型的時候,可以構(gòu)建基于詞匯水平的模型,也可以構(gòu)建基于字母水平的模型。在構(gòu)建字母水平的模型時由于會對每一個字母進行分拆因此序列會變得非常的長,并且不如詞匯水平的模型對于句子不同位置的詞匯間的相關(guān)關(guān)系的捕捉能力。

RNN 中的梯度消失問題

由于有時在自然語言中前后詞匯之間的相關(guān)關(guān)系經(jīng)常要間隔較長的詞匯才會出現(xiàn),例如對于主語使用復(fù)數(shù)形式時,在一個從句當中其謂語可能會間隔了幾十個單詞才需要出現(xiàn),此時由于深層網(wǎng)絡(luò)存在的梯度消失問題,前面講到的標準形式的 RNN 就比較難將前面的信息傳遞到后面。

Gated RNN Unit, GRU

為了解決長間隔的序列信息傳遞問題,GRU 單元引入了一個記憶單元 memory cell,記做 C 來在處理信息的同時對重要的信息進行記憶,且在第 t 個時間步有 C<t> = a<t>,在網(wǎng)絡(luò)計算中用 ?<t> = tanh(Wc [C<t-1>, x<t>] + bc) 來做為 C<t> 的備選值,在決定是否采用 ?<t> 來對 C<t> 進行更新時,可以設(shè)置一個 Γu = σ(Wu [C<t-1>, x<t>] + bu) 來計算相應(yīng)的概率值,由于這個 Γ 的取值范圍是 (0, 1) ,并且在實際計算中取值基本為 0 或 1,因此對于是否對 C<t> 進行更新的判斷公式可以總結(jié)為 C<t> = Γu * ?<t> + (1 - Γu) * C<t-1>,最后這一步為基于元素的向量乘法 elementwise。

上述 GRU 單元實際上是一個簡化的版本,在實際實施中更為完整的版本如下:

  • ?<t> = tanh(Wc [ ΓrC<t-1>, x<t>] + bc)

  • Γr = σ(Wr [C<t-1>, x<t>] + br)

  • Γu = σ(Wu [C<t-1>, x<t>] + bu)

  • C<t> = Γu * ?<t> + (1 - Γu) * C<t-1>

公式中添加了 Γr 項以確定 c<t-1> 的重要性 relevance。

長短時記憶 LSTM

另一個專門針對間隔信息傳遞的架構(gòu)設(shè)計是長短時記憶 Long short-term memory,其與 GRU 在實現(xiàn)中最顯著的區(qū)別是 C<t> ≠ a<t>,其主要組成部分及判斷邏輯如下:

Forget Gate - 對應(yīng)下圖中最左側(cè)的邏輯門,其通過對前一個時間步傳遞過來的激活信息 a<t-1> 和當前時間步的輸入 x<t> 的組合信息進行一個邏輯激活來生成一個所有元素處于 0 - 1 之間的向量 Γf = σ(Wf [a<t-1>, x<t>] + bf),再通過這個向量來與從前一個時間步傳遞過來的長期記憶 C<t-1> 進行逐個元素的乘積來判斷 C<t-1> 中有哪些是需要忘記的 Γf * C<t-1>,以此完成對于長期記憶的部分更新

Use Gate - 對應(yīng)下圖中最中間部分的由一個 σ 激活判斷和一個 tanh 激活構(gòu)成的邏輯門,其結(jié)合前一個時間步傳遞過來的激活信息 a<t-1> 和當前時間步的輸入信息 x<t> 來判斷如何進一步更新從前一個時間步傳遞過來的長期記憶 C<t-1>,其實現(xiàn)原理為:

  • 根據(jù) ?<t> = tanh(Wc [ a<t-1>, x<t>] + bc) 來計算一個潛在的可以加入長期記憶的儲備信息

  • 再利用 Γu = σ(Wu [a<t-1>, x<t>] + bu) 進一步同 ?<t> 通過元素相乘判斷這個儲備信息中有多少可以被加入到長期記憶中

最后結(jié)合前兩個邏輯門的工作成果,最終此時間步的長期記憶為:C<t> = Γu * ?<t> + Γf * C<t-1>

Output Gate - 對應(yīng)下圖中最右側(cè)部分的由一個 σ 激活判斷和一個 tanh 激活構(gòu)成的邏輯門,其主要職責(zé)為根據(jù)前一個時間步傳遞過來的激活信息 a<t-1> 和當前時間步的輸入信息 x<t> 來判斷本時間步的長期記憶的激活信息 C<t> 有哪些是需要進行輸出的,相應(yīng)的計算公式為:

  • Γo = σ(Wo [a<t-1>, x<t>] + bo)

  • a<t> = Γo * tanh(C<t>)

LSTM module, from Colah's blog in the reference

在文獻中 C<t-1> 和 C<t> 常被稱為 cell state 或 long term memory,而上一個時間步的激活結(jié)果 a<t-1> 則被稱為 working memory。

在實際使用中由于 GRU 的實現(xiàn)更加簡潔,因此也更加適合規(guī)模化,但 LSTM 由于采用了 3 個邏輯門因而更加的靈活,并不能簡單的評價哪一個單元優(yōu)于另外一個,需要根據(jù)應(yīng)用具體選擇。

雙向 RNN

前面已經(jīng)講到在詞匯判斷時,單向 RNN 在某一個時間步只能利用其之前的時間步的信息,而這經(jīng)常是不夠的,雙向 RNN 就是為了解決這個問題而出現(xiàn)的。在雙向 RNN 中輸出預(yù)測結(jié)合了前向傳播和后向傳播的激活信息,二者共同參與輸出判斷。

Bi-directional RNN

但 BRNN 的一個重要缺陷就是模型需要整個序列的信息才能做出判斷,這在諸如實時語音識別類的應(yīng)用中就不太適用。

Deep RNNs

如同標準的神經(jīng)網(wǎng)絡(luò)一樣,我們可以把前面的標準 RNN 單元、GRU 單元、LSTM 單元和 BRNN 單元層疊在一起構(gòu)成深度更深的 DRNN 網(wǎng)絡(luò),但由于時間序列的存在,一般 3 層的 DRNN 就已經(jīng)算是比較復(fù)雜的架構(gòu)了。

這里Andrew 為了區(qū)分不同的層,在注釋中用 [ ] 添加了層數(shù),與標準 RNN 單元一致的是在同一層中的參數(shù)是相同的。

DRNN with 3 hidden layers

RNN in TensorFlow

在 TensorFlow 中,在構(gòu)建 RNN 時有兩個函數(shù):tf.nn.rnn 和 tf.nn.dynamic_rnn,這兩個函數(shù)的區(qū)別是 tf.nn.rnn 創(chuàng)建的是一個固定時間步的非展開狀態(tài)的 RNN 計算圖,因此其要求每一個批次的輸入必須具有相同的步長,而 tf.nn.dynamic_rnn 中不同批次的長度則可以不同,因此在可能的情況下盡量選擇后者。

RNN Cells & Wrappers & Layers

RNN 的基本構(gòu)成單元是一系列的 RNN,GRU 和 LSTM 單元,這一部分很多不同的參考來源對于 cell 和 unit 并沒有嚴格的定義。在 TensorFlow 中 cell 本身可以包含多個基本的 LSTM,GRU 或 RNN 單元,例如在 BasicLSTMCell 定義中有一個參數(shù) num_units 就是定義一個大的、處于同一層中的 LSTM cell 里可以包含多少個基本的 LSTM 單元,并列的多個(取決于時間步的多少) LSTM cell 構(gòu)成一個 LSTM 層,在此基礎(chǔ)上可以通過 MultiRNNCell 定義多個 LSTM 層。

  • BasicRNNCell – A vanilla RNN cell.
  • GRUCell – A Gated Recurrent Unit cell.
  • BasicLSTMCell – An LSTM cell based on Recurrent Neural Network Regularization. No peephole connection or cell clipping.
  • LSTMCell – A more complex LSTM cell that allows for optional peephole connections and cell clipping.
  • MultiRNNCell – A wrapper to combine multiple cells into a multi-layer cell.
  • DropoutWrapper – A wrapper to add dropout to input and/or output connections of a cell.
cell = tf.contrib.rnn.BasicLSTMCell(num_units=64, state_is_tuple=True) # 包含 64 個 LSTM 基本單元
cell = tf.contrib.rnn.DropoutWrapper(cell=cell, output_keep_prob=0.5)
cell = tf.contrib.rnn.MultiRNNCell(cells=[cell] * 4, state_is_tuple=True) # 4 個 LSTM 層

在完成基本單元構(gòu)造后,推薦使用 dynamic_rnn 來構(gòu)造計算圖,其性能要優(yōu)于 static_rnn:

outputs, state = tf.nn.dynamic_rnn(cell=cell, inputs=data, dtype=tf.float32) 
#根據(jù) inputs 中的時間步來展開構(gòu)造計算圖

在 dynamic_rnn 中還有一個參數(shù) sequence_length,其需要指定的是在同一批次的輸入中因為長度不同而采用 padding 時,每一個序列在未添加 padding 時的時間步長,這點在文檔中的解釋是含糊的。

參考閱讀

  1. The Unreasonable Effectiveness of Recurrent Neural Networks

  2. Understanding LSTM Networks

  3. A Beginner’s Guide to Recurrent Networks and LSTMs

  4. Exploring LSTMs

  5. Written Memories: Understanding, Deriving and Extending the LSTM

  6. Understanding LSTM in TensorFlow with MNIST

  7. RNNs in Tensorflow, a Practical Guide and Undocumented Features

  8. Understanding LSTM in Tensorflow(MNIST dataset)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內(nèi)容