基本介紹
- 中文名:長短期記憶網路
- 外文名:Long-Short Term Memory
- 縮寫:LSTM
簡介,結構,訓練方法,搭建實例,
簡介
LSTM的表現通常比時間遞歸神經網路及隱馬爾科夫模型(HMM)更好,比如用在不分段連續手寫識別上。2009年,用LSTM構建的人工神經網路模型贏得過ICDAR手寫識別比賽冠軍。LSTM還普遍用於自主語音識別,2013年運用TIMIT自然演講資料庫達成17.7%錯誤率的紀錄。作為非線性模型,LSTM可作為複雜的非線性單元用於構造更大型深度神經網路。
結構
LSTM是一種含有LSTM區塊(blocks)或其他的一種類神經網路,文獻或其他資料中LSTM區塊可能被描述成智慧型網路單元,因為它可以記憶不定時間長度的數值,區塊中有一個gate能夠決定input是否重要到能被記住及能不能被輸出output。
右圖底下是四個S函式單元,最左邊函式依情況可能成為區塊的input,右邊三個會經過gate決定input是否能傳入區塊,左邊第二個為input gate,如果這裡產出近似於零,將把這裡的值擋住,不會進到下一層。左邊第三個是forget gate,當這產生值近似於零,將把區塊里記住的值忘掉。第四個也就是最右邊的input為output gate,他可以決定在區塊記憶中的input是否能輸出 。
LSTM有很多個版本,其中一個重要的版本是GRU(Gated Recurrent Unit),根據谷歌的測試表明,LSTM中最重要的是Forget gate,其次是Input gate,最次是Output gate。
LSTM模型
![LSTM模型 LSTM模型](/img/d/fb7/AZ0cjYjVzNjFmM1MDM1UTZ3UTOkJGN2UDMwYjY5MTNkNDZ2MTZjRTMvMWaw9SbvNmLz9mYlNmYu4GZj5yZtl2ai9yL6MHc0RHa.jpg)
訓練方法
為了最小化訓練誤差,梯度下降法(Gradient descent)如:套用時序性倒傳遞算法,可用來依據錯誤修改每次的權重。梯度下降法在遞迴神經網路(RNN)中主要的問題初次在1991年發現,就是誤差梯度隨著事件間的時間長度成指數般的消失。當設定了LSTM 區塊時,誤差也隨著倒回計算,從output影響回input階段的每一個gate,直到這個數值被過濾掉。因此正常的倒傳遞類神經是一個有效訓練LSTM區塊記住長時間數值的方法。
搭建實例
以下代碼展示了在tensorflow中實現使用LSTM結構的循環神經網路的前向傳播過程。
# 定義一個LSTM結構,LSTM中使用的變數也會在該函式中自動被聲明lstm=rnn_cell.BasicLSTMCell(lstm_hidden_size) # 將LSTM中的狀態初始化為全0數組,BasicLSTMCell提供了zero_state函式來生成全零的初始狀態state=lstm.zero_state(batch_size,tf.float32) # 定義損失函式loss=0.0# 理論上循環神經網路可以處理任意長度的序列,但是在訓練時為了避免梯度消散的問題,會規定一個最大的序列長度# 下面代碼使用參數num_steps來表示這個長度for i in range(num_steps): # 在第一個時刻聲明LSTM結構中使用的變數,在之後的時刻都需要復用之前定義好的變數 if i>0: tf.get_variable_scope().reuse_variables() # 每一步處理時間序列中的一個時刻。將當前輸入(current_input)和前一時刻狀態(state)傳入定義的LSTM結構可以得到 # 當前LSTM結構的輸出lstm_output和更新後的狀態state lstm_output,state=lstm(current_input,state) # 將當前時刻LSTM結構的輸出傳入一個全連線層得到最後的輸出 final_output=fully_connected(lstm_output) # 計算當前時刻輸出的損失 loss+=calc_loss(final_output,expected_output)
LSTM網路的變體:雙向循環神經網路和深層循環神經網路
雙向循環神經網路的主體結構是由兩個單向循環神經網路組成的。在每一個時刻t,輸入會同時提供給這兩個方向相反的循環神經網路,而輸出則是由這兩個單向循環神經網路共同決定。其結構如下圖一所示:
![圖一 圖一](/img/3/e4c/wMxUmYzQmNzU2Y1ETYlVzY1YTZiR2MwYjY5QzM0MDOyEmM0QGZyQjMvMWaw9SbvNmLz9mYlNmYu4GZj5yZtl2ai9yL6MHc0RHa.jpg)
六個權值分別對應:輸入到向前和向後隱含層(w1, w3),隱含層到隱含層自己(w2, w5),向前和向後隱含層到輸出層(w4, w6)。值得注意的是:向前和向後隱含層之間沒有信息流,這保證了展開圖是非循環的。
深層循環神經網路:為了增強模型的表達能力,該網路在每一個時刻上將循環體結構複製多次,每一層的循環體中參數是一致的,而不同層中的參數可以不同。其結構如下圖二所示:
![圖二 圖二](/img/7/a68/gYyQTO4MTOiVmMmJTMkF2M3MTMiJjZ2YWZwgjYmNTMyEDM5MTOlBDMvMWaw9SbvNmLz9mYlNmYu4GZj5yZtl2ai9yL6MHc0RHa.jpg)
tensorflow中提供了MultiRNNCell類來實現深層循環神經網路的前向傳播過程。代碼如下:
# 定義一個基本的LSTM結構作為循環體的基礎結構。深層循環神經網路也支持使用其他的循環體結構lstm=rnn_cell.BasicLSTMCell(lstm_size) # 通過MultiRNNCell類實現深層循環神經網路中每一個時刻的前向傳播過程。其中number_of_layers表示有多少層。stacked_lstm=rnn_cell.MultiRNNCell([lstm]*number_of_layers) # 通過zero_state函式來獲取初始狀態state=stacked_lstm.zero_state(batch_size,tf.float32) # 定義損失函式loss=0.0for i in range(num_steps): if i>0: tf.get_variable_scope().reuse_variables() stacked_lstm_output,state=stacked_lstm(current_input,state) # 將當前時刻LSTM結構的輸出傳入一個全連線層得到最後的輸出 final_output=fully_connected(stacked_lstm_output) # 計算當前時刻輸出的損失 loss+=calc_loss(final_output,expected_output)