1. 程式人生 > >利用雙向LSTM進行資料的預測

利用雙向LSTM進行資料的預測

雙向LSTM

我們為什麼要用雙向LSTM?

雙向卷積神經網路的隱藏層要儲存兩個值, A 參與正向計算, A’ 參與反向計算。最終的輸出值 y 取決於 A 和 A’:

在這裡插入圖片描述

即正向計算時,隱藏層的 s_t 與 s_t-1 有關;反向計算時,隱藏層的 s_t 與 s_t+1 有關

在這裡插入圖片描述

現在們利用tensorflow提供雙向LSTM函式來進行手寫識別的分類案例,時間序列資料資料的預測也可以通過修改資料集來實現
載入資料
mnist=input_data.read_data_sets("MNIST/",one_hot=True)
定義一個引數的配置類
class Config():
    """
    配置檔案的類
    """
    def __init__(self,input,timestep,batchsize,hidden_unit,hidden_unit1,learning_rate,epoch,num_class):

        self.TimeStep=timestep
        self.input=input
        self.batchsize=batchsize
        self.hidden_unit=hidden_unit
        self.hidden_unit1=hidden_unit1
        self.learning_rate=learning_rate
        self.epoch=epoch
        self.num_class=num_class
        self.weight ={
            'in':tf.Variable(tf.random_normal([2 * self.hidden_unit1, self.hidden_unit])),
            'out':tf.Variable(tf.random_normal([2*self.hidden_unit,self.num_class]))
        }
        self.bias = {
            'in':tf.Variable(tf.random_normal([self.hidden_unit])),
            'out':tf.Variable(tf.random_normal([self.num_class]))
        }
        self.max_samples=400000
定義雙向LSTM模型
def BiLSTM_Model(x,config):
    """
    雙向LSTM模型來對影象進行分類
    :return:
    """
    '''
    LSTM在進行對序列資料進行處理的時候,需要先將其轉化為滿足網路的格式[batch,timestep,features]
    '''
    x=tf.transpose(x,[1,0,2])
    x=tf.reshape(x,[-1,config.input])
    x=tf.split(x,config.TimeStep,0)

    #進行的多層雙向神經網路
    fw_lstm_cell_1=tf.nn.rnn_cell.BasicLSTMCell(num_units=config.hidden_unit1)
    bw_lstm_cell_1=tf.nn.rnn_cell.BasicLSTMCell(num_units=config.hidden_unit1)

    fw_lstm_cell_2=tf.nn.rnn_cell.BasicLSTMCell(num_units=config.hidden_unit)
    bw_lstm_cell_2=tf.nn.rnn_cell.BasicLSTMCell(num_units=config.hidden_unit)

    stack_lstm_fw=tf.nn.rnn_cell.MultiRNNCell(cells=[fw_lstm_cell_1,fw_lstm_cell_2])
    stack_lstm_bw=tf.nn.rnn_cell.MultiRNNCell(cells=[bw_lstm_cell_1,bw_lstm_cell_2])

    outputs,_,_=tf.nn.static_bidirectional_rnn(cell_fw=stack_lstm_fw,cell_bw=stack_lstm_bw,inputs=x,dtype=tf.float32)

    return tf.add(tf.matmul(outputs[-1],config.weight['out']),config.bias['out'])  #全連線層進行輸出
主函式執行
if __name__=="__main__":

   #定義一個配置類的物件
   config=Config(learning_rate=0.01,batchsize=128,input=28,timestep=28,hidden_unit1=256,num_class=10,epoch=None,hidden_unit=128)

   #定義變數和佔位符
   #None 表示不確定一次輸入多少條資料
   X=tf.placeholder(dtype=tf.float32,shape=[None,config.TimeStep,config.input])
   Y=tf.placeholder(dtype=tf.float32,shape=[None,config.num_class])

   #預測結果的輸出
   pred=BiLSTM_Model(X,config)
   pre_=tf.nn.softmax(pred)
   '''取到了前5個概率較大的值以及對應的索引'''
   top_k_values,top_k_index=tf.nn.top_k(pre_,5) #獲取索引也就表示找到了預測的這個值,然後再進行計算
   '''在資料集的one-hot編碼索引上進行預測模型的計算,然後統計發生的數量'''
   prediction_indices=tf.gather(Y,top_k_index)
   count_predictions=tf.reduce_sum(prediction_indices,reduction_indices=1)  #這個表示有多少個預測是準確的
   prediction=tf.argmax(count_predictions,dimension=1)

   #計算交叉熵損失,如果是計算交叉熵,則需要使用tf.reduce_sum()
   cost=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y,logits=pred))
   optimizer=tf.train.AdamOptimizer(learning_rate=config.learning_rate).minimize(cost)

   #計算預測的準確性
   correct_pred=tf.equal(tf.argmax(pred,1),tf.argmax(Y,1))
   accuracy=tf.reduce_sum(tf.cast(correct_pred,tf.float32))

   #接下來開始對變數進行初始化
   init=tf.global_variables_initializer()
   pred_result=[]
   with tf.Session() as sess:
       sess.run(init)
       step = 1
       while step * config.batchsize <config.max_samples:
           batch_x, batch_y = mnist.train.next_batch(config.batchsize)
           batch_x = batch_x.reshape((config.batchsize, config.TimeStep, config.input))
           sess.run(optimizer, feed_dict={X: batch_x, Y: batch_y})
           if step%20==0:
               acc,loss,pred_,pre_soft,ab,predict= sess.run([accuracy/config.batchsize,cost,tf.shape(pred),pre_,top_k_index,prediction], feed_dict={X: batch_x, Y: batch_y})
               # pred_result.append(sess.run(tf.argmax(pred_,1)))  #將預測的結果
               print("pre_soft:{},a:{},predict:{}".format(np.shape(pre_soft),ab,len(predict)))
               # print("acc={:.5f},loss={:.9f}".format(acc, loss)
           step+=1
       print("Optimizer Finished!!d!")

       test_len=10000
       test_data=mnist.test.images[:test_len].reshape((-1,config.TimeStep,config.input))
       test_label=mnist.test.labels[:test_len]
       print("Testing Accuracy:{:.5f}".format(sess.run(accuracy/test_len,feed_dict={X:test_data,Y:test_label})))
結果:acc:0.984

參考資料:

https://www.jianshu.com/p/471bdbd0170d
https://maxwell.ict.griffith.edu.au/spl/publications/papers/ieeesp97_schuster.pdf