循环神经网络基础介绍
在應用循環神經網絡的過程中,還是會有些地方疑惑,所以還是要回歸下問題的本質。
學而不思則惘,思而不學則怠。。
1. 循環神經網路簡介
首先循環神經網絡的主要用途是處理和預測序列數據。在之前的全鏈接神經網絡或卷積神經網絡模型中,網絡的結構都是從輸入層到隱藏層再到輸出層,層與層之間是全鏈接或者部分連接的,但每層之間的節點是無法連接的。而循環神經網絡的隱藏層之間的節點是有連接的,隱藏層的輸入不僅包括輸入層的輸出,還包括上一時刻隱藏層的輸出。
圖1.1 RNN-rolled
上圖是一個典型的循環神經網絡。對于循環神經網絡,一個非常重要的概念就是時刻。循環神經網絡會對于每一個時刻的輸入結合當前模型的狀態給出一個輸出。從圖中可以看到,循環神經網絡的主體結構A的輸入除了來自輸入層Xt,還有一個循環的邊來提供當前時刻的狀態。在每一個時刻,循環神經網絡的模塊A會讀取t時刻的輸入Xt,并輸出一個值Ht。同時A的狀態會從當前步傳遞到下一步。
因此,循環神經網絡理論上可以被看作是同一神經網絡結構被無限復制的結果。但出于優化的考慮,目前循環神經網絡無法做到真正的無限循環,所以,現實中一般會將循環體展開,于是可以得到下圖所示的展示結構。
圖1.2 按時間展開后的RNN結構
在上圖中可以更加清楚的看到循環神經網絡在每一個時刻會有一個輸入XtX_tXt?,然后根據循環神經網絡當前的狀態AtA_tAt?,提供一個輸出hth_tht?。而循環神經網絡的當前狀態AtA_tAt?是根據上一時刻的的狀態At?1A_{t-1}At?1?和當前的輸入XtX_tXt?共同決定的。從循環神經網絡的結構特征可以很容易得出它最擅長解決的問題是與時間序列相關的。循環神經網絡也是處理這類問題時最自然的神經網絡結構。對于一個序列數據,可以將這個序列上不同時刻的數據依次傳入循環神經網絡的輸入層,而輸出可以是對序列中下一個時刻的預測,也可以是對當前時刻信息的處理結果(比如語音識別結果)。循環神經網絡要求每一個時刻都有一個輸入,但是不一定每一個時刻都需要有輸出。
下面是RNN的應用場景:
RNN相對于傳統的神經網絡,它允許我們對向量序列進行操作:輸入序列、輸出序列、或大部分的輸入輸出序列。如下圖所示,每一個矩形是一個向量,箭頭則表示函數(比如矩陣相乘)。輸入向量用紅色標出,輸出向量用藍色標出,綠色的矩形是RNN的狀態。
圖1.3 RNN的模式分類
從左到右:
(1)沒有使用RNN的Vanilla模型,從固定大小的輸入得到固定大小輸出(比如圖像分類)
(2)序列輸出(比如圖片字幕,輸入一張圖片輸出一段文字序列)
(3)序列輸入(比如情感分析,輸入一段文字然后將它分類成積極或者消極情感)
(4)序列輸入和序列輸出(比如機器翻譯:一個RNN讀取一條英文語句然后將它以法語形式輸出)
(5)同步序列輸入輸出(比如視頻分類,對視頻中每一幀打標簽)。我們注意到在每一個案例中,都沒有對序列長度進行預先特定約束,因為遞歸變換(綠色部分)是固定的,而且我們可以多次使用。
舉例子:
圖1.4 循環神經網絡實現序列預測
以機器翻譯為例來簡單介紹循環神經網絡是如何使用的,循環神經網絡的每一個時刻的輸入為需要翻譯的句子中的單詞,如上所示,需要翻譯的句子為ABCD,那么循環神經網絡的第一段中的每一時刻的輸入數據分別是A、B、C、和D。然后用“_”作為翻譯的結束符號。在第一個階段中,循環神經網絡中沒有輸出(句子還沒有讀完,不能進行翻譯),只有每一個時刻的輸入,而從結束符號開始有輸出,也就是進入了翻譯階段。在翻譯階段每一個時刻的輸入是上一個時刻的輸出,而最終的的輸出XYZ就是ABCD的翻譯結果,而Q是代表翻譯結束的標志。
在上述實現的過程中可以看作同一個循環體在時間序列上被復制多次的結果,而這個循環體的設計網絡結構的是問題的關鍵。和卷積神經網絡結構中過濾器的參數共享類似,在循環神經網絡中的循環體的參數在不同時刻也是共享的。
2. 簡單的單層全連接神經網絡作為循環體的例子
圖2.1 使用單層全連接神經網絡作為循環體的循環神經網絡結構圖
上圖展示了一個使用最簡單的循環體結構的循環神經網絡,在這個循環體中只使用了一個類似全連接層的神經網絡結構。下面將通過上圖中所展示的神經網絡來介紹循環神經網絡前向傳播的完整流程。
循環神經網絡中的狀態是通過一個向量來表示的,這個向量的維度也稱為神經網絡隱藏層的大小,假設其為h。
從上圖種可以看出,循環體中的神經網絡的輸入有兩部分,一部分為上一時刻的狀態,另一部分為當前時刻的輸入樣本。對于時間序列數據來說,每一時刻的輸入樣例可以是當前時刻的數據;對于語言模型來說,輸入樣例可以是當前單詞對應的單詞向量(word embedding)。
假設輸入向量的維度為x,那么上圖中循環體的全連接層神經網絡的輸入大小為h+x。也就是將上一時刻的狀態與當前時刻的輸入拼接成一個大的向量作為循環體中神經網絡的輸入。因為該神經網絡的輸出為當前時刻的狀態,于是輸出層的節點個數也為h(節點個數就是向量的維度,或者是隱藏層的大小),循環體中的參數個數為(h+x)?h+h(h+x)*h+h(h+x)?h+h個(這里可以理解為輸入層有h+x個神經元,輸出層有h個神經元,從而形成一個全連接的前饋神經網絡,有(h+x)*h個權值,有h個偏置)。
同時循環體的神經網絡輸出不但提供給下一個時刻作為狀態,同時還提供給當前的時刻作為輸出。為了將當前時刻的狀態轉化為最終的輸出,循環體還需要另外一個全連接神經網絡來完成這個過程。這和卷積神經網絡中最后的全連接層的意義是一樣的。類似的,不同時刻用于輸出的全連接神經網絡中的參數也是共享的(參數一致)。
下面是一個具體的例子,當然了數值都是假設的,意在理解原理:
圖2.2 RNN的前向傳播的計算過程
如圖2所示,假設節點狀態的維度為2,節點的輸入和輸出維度為1,那么在循環體的全連接層神經網絡的輸入維度為3,也就是將上一時刻的狀態與當前時刻的輸入拼接成一維向量作為循環體的全連接層神經網絡的輸入,在這里t0時刻的節點狀態初始化為[0.0, 0.0],t0時刻的節點輸入為[1.0],拼接之后循環體的全連接層神經網絡的輸入為[0.0, 0.0, 1.0],循環體中的全連接層的權重表示為二維矩陣[[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]],偏置項為[0.1, -0.1],我們可以看到權重矩陣和偏置項在t0和t1時刻的循環體中是一樣的,這也說明了RNN結構中的參數在不同時刻中也是共享的。經過循環體中的全連接層神經網絡后節點的狀態改變為tanh([0.6, 0.5]) = [0.537, 0.462],當前節點狀態的輸出作為下一個節點狀態的輸入。
為了將當前時刻的狀態轉變為節點的最終輸出,RNN中還有另外一個全連接神經網絡來計算節點輸出,在圖2中被表示為[0.537, 0.462] * [1.0, 2.0] + [0.1] = [1.56],用于輸出的全連接層權重為[1.0, 2.0],偏置項為[0.1],1.56表示為t0時刻節點的最終輸出。
得到RNN的前向傳播結果之后,和其他神經網絡類似,定義損失函數,使用反向傳播算法和梯度下降算法訓練模型,但RNN唯一的區別在于:由于它每個時刻的節點都有一個輸出,所以RNN的總損失為所有時刻(或部分時刻)上的損失和。
下面是自己假設數據的代碼實現:
import numpy as np""" 定義RNN的參數 """X = [1,2] # 輸入序列 state = [0.0, 0.0] # 初始狀態下的狀態 # 狀態層的權重和輸入層的權重分開定義,方便操作 w_cell_state = np.asarray([[0.1, 0.2], [0.3, 0.4]]) # 定義狀態層權重 w_cell_input = np.asarray([0.5, 0.6]) # 定義輸入層的權重 b_cell = np.asarray([0.1, -0.1]) # 狀態層的偏置 w_output = np.asarray([[1.0], [2.0]]) # 輸出層的權重 b_output = 0.1 # 輸出層的偏置""" 執行前向傳播過程 """for i in range(len(X)):before_activation = np.dot(state, w_cell_state) + X[i] * w_cell_input + b_cellstate = np.tanh(before_activation)final_output = np.dot(state, w_output) + b_outputprint ("before activation: ", before_activation)print ("state: ", state)print ("output: ", final_output)運行結果:
before activation: [0.6 0.5] state: [0.53704957 0.46211716] output: [1.56128388] before activation: [1.2923401 1.39225678] state: [0.85973818 0.88366641] output: [2.72707101]3. 長短時記憶網絡(LSTM)結構
循環神經網絡工作的關鍵點就是使用歷史的信息來幫助當前的決策。例如使用之前出現的單詞來加強對當前文字的理解。循環神經網絡可以更好地利用傳統神經網絡結構所不能建模的信息,但同時,這也帶來了更大的技術挑戰——長期依賴(long-term dependencies)問題。
因此,當前預測位置和相關信息之間的文本間隔就有可能變得很大。當這個間隔不斷增大時,類似圖2.1中給出的簡單循環神經網絡有可能喪失學習到距離如此遠的信息的能力。或者在復雜語言場景中,有用信息的間隔有大有小、長短不一,循環神經網絡的性能也會受到限制。
3.1 LSTM簡介
長短記憶網絡(long short term memory, LSTM)的設計正是為了解決上述RNN的依賴問題,即為了解決RNN有時依賴的間隔短,有時依賴的間隔長的問題。其中循環神經網絡被成功應用的關鍵就是LSTM。
圖3.1 LSTM單元結構圖
它是一種特殊的循環體結構,與單一的tanh循環體結構不同,LSTM是一種擁有三個“門”結構的特殊網絡結構。
所謂的“門”結構就是使用了sigmoid激活函數的全連接神經網絡和一個按位做乘法的操作,sigmoid激活函數會輸出一個0~1之間的數值,這個數值描述的是當前有多少信息能通過“門”,0表示任何信息都無法通過,1表示全部信息都可以通過。其中,“遺忘門”和“輸入門”是LSTM單元結構的核心。下面我們來詳細分析下三種“門”結構。
遺忘門:用來讓RNN“忘記”之前沒有用的信息。比如“十年前,北京的天空是藍色的”,但當看到“空氣污染開始變得越來越嚴重”后,RNN應該忘記“北京的天空是藍色的”這個信息。遺忘門會根據當前時刻節點的輸入Xt、上一時刻節點的狀態C(t-1)和上一時刻節點的輸出h(t-1)來決定哪些信息將被遺忘。
輸入門:用來讓RNN決定當前輸入數據中哪些信息將被留下來。在RNN使用遺忘門“忘記”部分之前的信息后,還需要從當前的輸入補充最新的記憶。輸入門會根據當前時刻節點的輸入Xt、上一時刻節點的狀態C(t-1)和上一時刻節點的輸出h(t-1)來決定哪些信息將進入當前時刻節點的狀態Ct,比如看到“空氣污染開始變得越來越嚴重”后,模型需要記憶這個最新的信息。
輸出門:LSTM在得到最新節點狀態Ct后,結合上一時刻節點的輸出h(t-1)和當前時刻節點的輸入Xt來決定當前時刻節點的輸出。比如當前時刻節點狀態為被污染,那么“天空的顏色”后面的單詞應該是“灰色”。
在TensorFlow中可以使用lstm = rnn_cell.BasicLSTMCell(lstm_hidden_size)來聲明一個LSTM結構。
3.2 LSTM詳解
具體的LSTM每個門的公式如下:
圖3.2 LSTM單元詳細結構
所有循環神經網絡都有一個重復結構的模型形式,在標準的RNN中,重復的結構是一個簡單的循環體,如圖3.2所示的A循環體。然而LSTM的循環體是一個擁有四個相互關聯的全連接前饋神經網絡的復制結構。
符號介紹:
圖3.3 符號說明
- Neural NetWork Layer:該圖表示一個神經網絡層(自己可以定義大小)
- Pointwise Operation:該圖表示一種操作,如加號表示矩陣或向量的求和、乘號表示向量的乘法操作;
- Vector Tansfer:每一條線表示一個向量,從一個節點輸出到另一個節點;
- Concatenate:該圖表示兩個向量的合并,即由兩個向量合并為一個向量,如有X1和X2兩向量合并后為[X1,X2]向量;
- Copy:該圖表示一個向量復制了兩個向量,其中兩個向量值相同。
門設計:
遺忘門:LSTM的第一步是決定要從上一個時刻的狀態中丟棄什么信息,其是由一個sigmoid全連接的前饋神經網絡的輸出管理,將這種操作稱為遺忘門(forget get layer)。如圖3.4所示。這個全連接的前饋神經網絡的輸入是ht?1h_{t-1}ht?1?和XtX_tXt?組成的向量,輸出是ftf_tft?向量。ftf_tft?向量是由1和0組成,1表示能夠通過,0表示不能通過。
圖3.4 遺忘門
輸入門:第二步決定哪些輸入信息要保存到神經元的狀態中。這由兩個前饋神經網絡,如圖3.5所示。首先是一個sigmoid層的全連接前饋神經網絡,稱為輸入門(input gate layer),其決定了哪些值將被更新;然后是一個tanh層的全連接前饋神經網絡,其輸出是一個向量Ct~\tilde{C_t}Ct?~?,Ct~\tilde{C_t}Ct?~?向量可以被添加到當前時刻的神經元狀態中;最后根據兩個神經網絡的結果創建一個新的神經元狀態。
圖3.5 輸入門
狀態控制:第三步就可以更新上一時刻的狀態Ct?1C_{t-1}Ct?1?為當前時刻的狀態CtC_tCt?了。上述的第一步的遺忘門計算了一個控制向量,此時可通過這個向量過濾了一部分Ct?1C_{t-1}Ct?1?狀態,如圖3.6所示的乘法操作;上述第二步的輸入門根據輸入向量計算了新狀態,此時可以通過這個新狀態和Ct?1狀態根據一個新的狀態C_{t-1}狀態根據一個新的狀態Ct?1?狀態根據一個新的狀態C_t$。
圖3.6 狀態控制
輸出門:最后一步就是決定神經元的輸出向量hth_tht?是什么,此時的輸出是根據上述第三步的CtC_tCt?狀態進行計算的,即根據一個sigmoid層的全連接前饋神經網絡過濾到一部分CtC_tCt?狀態作為當前時刻神經元的輸出,如圖3.7所示。這個計算過程是:首先通過sigmoid層生成一個過濾向量;然后通過一個tanh函數計算當前時刻的CtC_tCt?狀態向量(即將向量每個值的范圍變換到[-1,1]之間);接著通過sigmoid層的輸出向量過濾tanh函數結果,即為當前時刻神經元的輸出。
圖3.7 輸出門
LSTM有很多種變體:
Peephole connections:一種流行的LSTM變體是由Gers&Schmidhuber(2000)提出的網絡結構,如圖 29所示。通過將上一時刻的狀態Ct-1合并到各個門上,從而更詳細控制各個門的管理。
Coupled forget and input gates:另一種變體是使用耦合的遺忘門和輸入門
Gated Recurrent Unit:另一種變體是Gated Recurrrent Unit
3.3 循環神經網絡的變體
雙向循環神經網絡(BRNN):RNN和LSTM都只能依據之前時刻的時序信息來預測下一時刻的輸出,但在有些問題中,當前時刻的輸出不僅和之前的狀態有關,還可能和未來的狀態有關系。比如預測一句話中缺失的單詞不僅需要根據前文來判斷,還需要考慮它后面的內容,真正做到基于上下文判斷。BRNN(bidirectional
RNN)有兩個RNN上下疊加在一起組成的,輸出由這兩個RNN的狀態共同決定。BRNN結構圖如圖3.8所示:
圖3.8 BRNN結構圖
從上圖可以看出,雙向循環神經網絡就是兩個單向循環神經網絡的結合。在每一個時刻t,輸入會同時提供給這兩個方向相反的循環神經網絡,而輸出則是由這兩個單向循環神經網路共同決定的。
深層循環神經網絡(DRNN:DRNN可以增強模型的表達能力,相比圖3.2介紹的循環神經網絡,深層循環神經網絡主要是將每個時刻上的循環體重復多次,每一層循環體中參數是共享的,但不同層之間的參數可以不同。DRNN結構如圖3.9所示:
圖3.9 DRNN結構圖
TensorFlow中可以通過rnn_cell.MultiRNNCell([lstm] * number_of_layer)來構建DRNN,其中number_of_layer表示了有多少層。
3.4 循環神經網絡的fropout
在構建實際的任務模型時,往往會設置dropout來讓構建的網絡模型更加健壯,類似在卷積神經網絡只在最后全連接層使用dropout,DRNN一般只在不同層循環體結構中使用dropout,而不在同一層的循環體結構中使用。即從時刻t-1傳遞到t時刻時,RNN不進行狀態的dropout,但在同一時刻t中,不同層循環體之間會使用dropout,圖3.10展示了DRNN中使用dropout,其中實線箭頭表示不使用dropout,虛線箭頭表示使用dropout。
圖3.10 DRNN中使用dropout
TensorFlow中可以使用tf.nn.rnn_cell.DropoutWrapper類來實現dropout功能。
在實際編程中,可以通過TensorFlow的高層封裝工具TFLearn來自定義模型,TFLearn封裝了一些常用的神經網絡模型,這里不再介紹。
參考:https://www.cnblogs.com/huliangwen/p/7464813.html
總結
以上是生活随笔為你收集整理的循环神经网络基础介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022怎么装修最省钱实用8个装修省钱大
- 下一篇: 循环神经网络应用案例