循環神經網絡(LSTM和GRU)(1)

循環神經網絡的簡單實現:html

import tensorflow as tf x=[1,2] state=[0.0,0.0] w_cell_state=np.array([[0.1,0.2],[0.3,0.4]]) w_cell_input=np.array([0.5,0.6]) b_cell=np.array([0.1,-0.1]) w_output=np.array([1.0,2.0]) b_output=0.1
for i in range(len(x)): before_a=np.dot(state,w_cell_state)+x[i]*w_cell_input+b_cell #初始狀態state默認爲[0,0] state=np.tanh(before_a) #當前層的狀態state final_out=np.dot(state,w_output)+b_output #獲得輸出層結果 print(before_a) print('state:', state) print('final_out:', final_out) 

與單一tanh循環體結構不一樣,LSTM是一個擁有三個門結構的特殊網絡結構。git

LSTM靠一些門結構讓信息有選擇性的影響循環神經網絡中每一個時刻的狀態,所謂的門結構就是一個使用sigmoid神經網絡和一個按位作乘法的操做,這兩個操做合在一塊兒就是一個門結構。之因此該結構叫門是由於使用sigmoid做爲激活函數的全鏈接神經網絡層會數組

輸出一個0到1之間的數值,描述當前輸入有多少信息量能夠經過這個結構。該結構功能就相似於一扇門,當門打開時(sigmoid神經網絡輸出爲1時),所有信息均可以經過;當門關上時(sigmoid神經網絡輸出爲0時),任何信息都沒法經過。網絡

LSTM單元結構示意圖以下所示:dom

爲了使循環神經網絡更有效的保存長期記憶,遺忘門和輸入門是LSTM核心,遺忘門的做用是讓神經網絡忘記以前沒有用的信息,遺忘門會根據當前的輸入xt、上一時刻狀態ct-1和上一時刻輸出ht-1共同決定哪一部分記憶須要被遺忘。函數

在循環神經網絡忘記了部分以前的狀態後,它還須要從當前的輸入補充最新的記憶。這個過程就是輸入門完成的,輸入門會根據xt、ct-1和ht-1決定哪些部分進入當前時刻的狀態ct。好比當看到文章中提到環境被污染以後,模型須要將這個信息寫入優化

新的狀態,經過遺忘門和輸入門,LSTM能夠更有效的決定哪些信息應該被遺忘,哪些信息應該獲得保留。spa

LSTM結構在計算獲得新的狀態ct後須要產生當前時刻的輸出,該過程經過輸出門完成,輸出門會根據最新的狀態ct、上一時刻的輸出ht-1和當前的輸入xt來決定該時刻的輸出ht。以下代碼展現了tensorflow中實現LSTM結構的循環神經網絡的前向傳播過程:.net

#定義一個LSTM結構,經過一個簡單的命令實現一個完整的LSTM結構
lstm=tf.contrib.rnn.BasicRNNCell(lstm_hidden_size) #將LSTM中的狀態初始化爲全0數組,在優化循環神經網絡時,每次也會使用一個batch的訓練樣本。
state=lstm.zero_state(batch_size,tf.float32) loss=0.0
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爲克服沒法很好的處理遠距離依賴而提出3d

1、傳統的LSTM結構:

參考:https://blog.csdn.net/zhangxb35/article/details/70060295?locationNum=2&fps=1

參考:https://blog.csdn.net/u010751535/article/details/59536631

參考:https://www.cnblogs.com/taojake-ML/p/6272605.html

一、輸入門:

二、遺忘門:

三、輸出門:

四、當前狀態:

    當前狀態的計算過程和下面LSTM的變種的計算過程相同。

五、輸出結果:

             h()爲激活函數,將當前狀態經激活函數後和輸出門結果乘積,獲得最終結果

 

2、LSTM的變體公式以下(比傳統的LSTM計算多了上一層的狀態ct-1

(參考:https://www.cnblogs.com/taojake-ML/p/6272605.html)

(參考:https://blog.csdn.net/zhangxb35/article/details/70060295?locationNum=2&fps=1)

(參考:https://zybuluo.com/hanbingtao/note/581764     好文

一、輸入門:

        輸入門根據xt,ht-1,st-1來決定哪些部分進入當前時刻的狀態

上一時刻的輸出、上一時刻的狀態、當前時刻的輸入進行加權求和,再經激活函數獲得輸出結果(傳統的LSTM的狀態c在這裏改爲s)

其中表示當前時刻的輸入ht-1表示上一時刻的輸出st-1表示上一時刻的狀態(也即上一時刻的通過激活函數處理的門輸出結果),c下標表示cell,f()表示激活函數。

I表示輸入層的神經元個數,K是輸出層的神經元個數,H是隱藏層H的個數。wi1和wi2分別表示輸入門、遺忘門的權重。

二、遺忘門:

        遺忘門根據xt,ht-1,st-1來決定哪些部分進入當前時刻的狀態

一樣是上一時刻的輸出、上一時刻的狀態、當前時刻的輸入進行加權求和,再經激活函數獲得輸出結果

三、當前狀態:

       

計算上一時刻的輸出、當前時刻的輸入進行加權求和,將遺忘門和輸入門的結果做爲權重,計算上一時刻狀態和當前經激活函數處理的acell的加權和          

四、輸出門:

       

計算當前輸入、上一時刻的輸出、當前狀態的加權和,並經激活函數獲得輸出結果        

五、結果輸出:

 

遺忘門和輸入門經激活函數處理後返回結果在[0,1]區間,在計算當前狀態的過程當中,倘若遺忘門結果取0,那麼上一層的狀態將不會對當前狀態產生影響,也就表現爲上一層的狀態會被遺忘(這也就是門結構的由來而後則只關注這個時刻的輸入,輸入門決定了是否接受如今時刻的輸入。

最後經過輸出門的結果來決定是否輸出當前狀態。

變體LSTM圖形以下:

(資料來源:引自 Alex Graves 的論文 Supervised Sequence Labelling with Recurrent Neural Networks 中對 LSTM 的描述)

一個以LSTM爲模型的實現的例子以下所示:

import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data mnist=input_data.read_data_sets('MNIST_data',one_hot=True) lr=0.001 training_iters=100000 batch_size=128 n_inputs=28     #mnist data input (img shape:28*28)
n_steps=28 n_hidden_units=128   #neurons in hidden layer
n_classes=10     #mnist classes
 x=tf.placeholder(tf.float32,[None,n_steps,n_inputs]) y=tf.placeholder(tf.float32,[None,n_classes]) weight={ 'in':tf.Variable(tf.random_normal([n_inputs,n_hidden_units])) , 'out':tf.Variable(tf.random_normal([n_hidden_units,n_classes])) } biases={ 'in':tf.Variable(tf.constant(0,1,shape=[n_hidden_units,])), 'out':tf.Variable(tf.constant(0.1,shape=[n_classes,])) } def RNN(X,weight,biases): X=tf.reshape(X,[-1,n_inputs]) X_in=tf.matmul(X,weight['in'])+biases['in']     #shape=[n_steps,n_hidden_units] biases_shape=[n_hidden_units]
    X_in=tf.reshape(X_in,[-1,n_steps,n_hidden_units]) lstm_cell=tf.contrib.rnn.BasicLSTMCell(n_hidden_units,forget_bias=1.0,state_is_tuple=True) init_state=lstm_cell.zero_state(batch_size,dtype=tf.float32) outputs,final_state=tf.nn.dynamic_rnn(lstm_cell,X_in,initial_state=init_state,time_major=False) results=tf.matmul(final_state[1],weight['out'])+biases['out'] return results pred=RNN(x,weight,biases) cost=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=y)) train_op=tf.train.AdamOptimizer(lr).minimize(cost) correct_pred=tf.equal(tf.argmax(pred,1),tf.argmax(y,1)) accuracy=tf.reduce_mean(tf.cast(correct_pred,tf.float32)) init=tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) step=0 while step*batch_size<training_iters: batch_xs,batch_ys=mnist.train.next_batch(batch_size) batch_xs=batch_xs.reshape([batch_size,n_steps,n_inputs]) sess.run([train_op],feed_dict={x:batch_xs,y:batch_ys}) if step%20==0: print(sess.run(accuracy,feed_dict={x:batch_xs,y:batch_ys})) step+=1

 3、GRU模型

參考:https://www.cnblogs.com/taojake-ML/p/6272605.html

相較於LSTM的三個門計算實現:遺忘門、輸入門、輸出門

GRU則只剩下兩個門,分別爲更新門和重置門。也就是zt和rt更新門用於控制前一時刻的狀態信息被帶入當前狀態的程度,更新門越大說明前一時刻被帶入的信息越多。重置門用於控制忽略前一時刻狀態信息的程度,重置門值越小說明忽略的信息越多。

 其中GRU的圖形以下所示:

計算公式以下所示:

其中zt是更新門(update gate),用於更新activation時的邏輯門(表如今計算ht的時候,是否更新)。相較於LSTM,這裏將遺忘門和輸入門合成了一個更新門

rt是重置門(reset gate),用於決定candidate activation時,是否放棄之前的activation ht-1,在計算中,當rt趨向於0時,則表現爲遺忘上一時刻的ht-1

是candidate activation(所謂的候選即不直接將計算結果拿來用,而是用於進一步的計算),接收[xt,ht-1]

ht是activation,是GRU的隱層,接收

相關文章
相關標籤/搜索