利用雙向LSTM進行資料的預測
阿新 • • 發佈:2018-11-30
雙向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