tensorflow學習筆記(六):LSTM 與 GRU

NO IMAGE

[10.26.2016 更新]
[新增內容:今天寫程式碼的時候,如果使用state_is_tuple=True, 那麼

initial_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
...
with tf.Session() as sess:
tf.initialize_all_variables().run()
state = initial_state.eval()   #state_is_tuple=True的話,這裡會報錯,不用eval也會報錯
sess.run([train_op, state],    #所以我使用了state_is_tuple=False,不知0.11.0會不會正常
feed_dict={
initial_state:state
})

]

LSTM & GRU

基本LSTM

tensorflow提供了LSTM實現的一個basic版本,不包含lstm的一些高階擴充套件,同時也提供了一個標準介面,其中包含了lstm的擴充套件。分別為:tf.nn.rnn_cell.BasicLSTMCell(), tf.nn.rnn_cell.LSTMCell()

LSTM的結構

盜用一下Understanding LSTM Networks上的圖
圖一

圖一
圖二
圖二
圖三
圖三
tensorflow中的BasicLSTMCell()是完全按照這個結構進行設計的

#tf.nn.rnn_cell.BasicLSTMCell(num_units, forget_bias, input_size, state_is_tupe=Flase, activation=tanh)
cell = tf.nn.rnn_cell.BasicLSTMCell(num_units, forget_bias=1.0, input_size=None, state_is_tupe=Flase, activation=tanh)
#num_units:圖一中ht的維數,如果num_units=10,那麼ht就是10維行向量
#forget_bias:遺忘門的初始化偏置
#input_size:[batch_size, max_time, size]。假設要輸入一句話,這句話的長度是不固定的,max_time就代表最長的那句話是多長,size表示你打算用多長的向量代表一個word,即embedding_size(embedding_size和size的值不一定要一樣)
#state_is_tuple:true的話,返回的狀態是一個tuple:(c=array([[]]), h=array([[]]):其中c代表Ct的最後時間的輸出,h代表Ht最後時間的輸出,h是等於最後一個時間的output的
#圖三向上指的ht稱為output
#此函式返回一個lstm_cell,即圖一中的一個A

如果你想要設計一個多層的LSTM網路,你就會用到tf.nn.rnn_cell.MultiRNNCell(cells, state_is_tuple=False),這裡多層的意思上向上堆疊,而不是按時間展開

lstm_cell = tf.nn.rnn_cell.MultiRNNCells(cells, state_is_tuple=False)
#cells:一個cell列表,將列表中的cell一個個堆疊起來,如果使用cells=[cell]*4的話,就是四曾,每層cell輸入輸出結構相同
#如果state_is_tuple:則返回的是 n-tuple,其中n=len(cells): tuple:(c=[batch_size, num_units], h=[batch_size,num_units])

這是,網路已經搭好了,tensorflow提供了一個非常方便的方法來生成初始化網路的state

initial_state = lstm_cell.zero_state(batch_size, dtype=)
#返回[batch_size, 2*len(cells)],或者[batch_size, s]
#這個函式只是用來生成初始化值的

現在進行時間展開,有兩種方法:
法一:
使用現成的介面:

tf.nn.dynamic_rnn(cell, inputs, sequence_length=None, initial_state=None,dtype=None,time_major=False)
#此函式會通過,inputs中的max_time將網路按時間展開
#cell:將上面的lstm_cell傳入就可以
#inputs:[batch_size, max_time, size]如果time_major=Flase. [max_time, batch_size, size]如果time_major=True
#sequence_length:是一個list,如果你要輸入三句話,且三句話的長度分別是5,10,25,那麼sequence_length=[5,10,25]
#返回:(outputs, states):output,[batch_size, max_time, num_units]如果time_major=False。 [max_time,batch_size,num_units]如果time_major=True。states:[batch_size, 2*len(cells)]或[batch_size,s]
#outputs輸出的是最上面一層的輸出,states儲存的是最後一個時間輸出的states

法二

outputs = []
states = initial_states
with tf.variable_scope("RNN"):
for time_step in range(max_time):
if time_step>0:tf.get_variable_scope().reuse_variables()#LSTM同一曾引數共享,
(cell_out, state) = lstm_cell(inputs[:,time_step,:], state)
outputs.append(cell_out)

已經得到輸出了,就可以計算loss了,根據你自己的訓練目的確定loss函式

GRU

GRU結構圖
來自Understanding LSTM Networks
圖四

圖四
tenforflow提供了tf.nn.rnn_cell.GRUCell()構建一個GRU單元

cell = tenforflow提供了tf.nn.rnn_cell.GRUCell(num_units, input_size=None, activation=tanh)
#參考lstm cell 使用