keras在構(gòu)建LSTM模型時對變長序列的處理操作
我就廢話不多說了,大家還是直接看代碼吧~
print(np.shape(X))#(1920, 45, 20) X=sequence.pad_sequences(X, maxlen=100, padding='post') print(np.shape(X))#(1920, 100, 20) model = Sequential() model.add(Masking(mask_value=0,input_shape=(100,20))) model.add(LSTM(128,dropout_W=0.5,dropout_U=0.5)) model.add(Dense(13,activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # 用于保存驗證集誤差最小的參數(shù),當驗證集誤差減少時,保存下來 checkpointer = ModelCheckpoint(filepath="keras_rnn.hdf5", verbose=1, save_best_only=True, ) history = LossHistory() result = model.fit(X, Y, batch_size=10, nb_epoch=500, verbose=1, validation_data=(testX, testY), callbacks=[checkpointer, history]) model.save('keras_rnn_epochend.hdf5')
補充知識:RNN(LSTM)數(shù)據(jù)形式及Padding操作處理變長時序序列dynamic_rnn
Summary
RNN
樣本一樣,計算的狀態(tài)值和輸出結(jié)構(gòu)一致,也即是說只要當前時刻的輸入值也前一狀態(tài)值一樣,那么其當前狀態(tài)值和當前輸出結(jié)果一致,因為在當前這一輪訓練中權(quán)重參數(shù)和偏置均未更新
RNN的最終狀態(tài)值與最后一個時刻的輸出值一致
輸入數(shù)據(jù)要求格式為,shape=(batch_size, step_time_size, input_size),那么,state的shape=(batch_size, state_size);output的shape=(batch_size, step_time_size, state_size),并且最后一個有效輸出(有效序列長度,不包括padding的部分)與狀態(tài)值會一樣
LSTM
LSTM與RNN基本一致,不同在于其狀態(tài)有兩個c_state和h_state,它們的shape一樣,輸出值output的最后一個有效輸出與h_state一致
用變長RNN訓練,要求其輸入格式仍然要求為shape=(batch_size, step_time_size, input_size),但可指定每一個批次中各個樣本的有效序列長度,這樣在有效長度內(nèi)其狀態(tài)值和輸出值原理不變,但超過有效長度的部分的狀態(tài)值將不會發(fā)生改變,而輸出值都將是shape=(state_size,)的零向量(注:RNN也是這個原理)
需要說明的是,不是因為無效序列長度部分全padding為0而引起輸出全為0,狀態(tài)不變,因為輸出值和狀態(tài)值得計算不僅依賴當前時刻的輸入值,也依賴于上一時刻的狀態(tài)值。其內(nèi)部原理是利用一個mask matrix矩陣標記有效部分和無效部分,這樣在無效部分就不用計算了,也就是說,這一部分不會造成反向傳播時對參數(shù)的更新。當然,如果padding不是零,那么padding的這部分輸出和狀態(tài)同樣與padding為零的結(jié)果是一樣的
''' #樣本數(shù)據(jù)為(batch_size,time_step_size, input_size[embedding_size])的形式,其中samples=4,timesteps=3,features=3,其中第二個、第四個樣本是只有一個時間步長和二個時間步長的,這里自動補零 ''' import pandas as pd import numpy as np import tensorflow as tf train_X = np.array([[[0, 1, 2], [9, 8, 7], [3,6,8]], [[3, 4, 5], [0, 10, 110], [0,0,0]], [[6, 7, 8], [6, 5, 4], [1,7,4]], [[9, 0, 1], [3, 7, 4], [0,0,0]], [[9, 0, 1], [3, 3, 4], [0,0,0]] ]) sequence_length = [3, 1, 3, 2, 2] train_X.shape, train_X[:,2:3,:].reshape(5, 3)
tf.reset_default_graph() x = tf.placeholder(tf.float32, shape=(None, 3, 3)) # 輸入數(shù)據(jù)只需能夠迭代并符合要求shape即可,list也行,shape不指定表示沒有shape約束,任意shape均可 rnn_cell = tf.nn.rnn_cell.BasicRNNCell(num_units=6) # state_size[hidden_size] lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units=6) # state_size[hidden_size] outputs1, state1 = tf.nn.dynamic_rnn(rnn_cell, x, dtype=tf.float32, sequence_length=sequence_length) outputs2, state2 = tf.nn.dynamic_rnn(lstm_cell, x, dtype=tf.float32, sequence_length=sequence_length) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 初始化rnn_cell中參數(shù)變量 outputs1, state1 = sess.run((outputs1, state1), feed_dict={x: train_X}) outputs2, state2 = sess.run([outputs2, state2], feed_dict={x: train_X}) print(outputs1.shape, state1.shape) # (4, 3, 5)->(batch_size, time_step_size, state_size), (4, 5)->(batch_size, state_size) print(outputs2.shape) # state2為LSTMStateTuple(c_state, h_state) print("---------output1<rnn>state1-----------") print(outputs1) # 可以看出output1的最后一個時刻的輸出即為state1, 即output1[:,-1,:]與state1相等 print(state1) print(np.all(outputs1[:,-1,:] == state1)) print("---------output2<lstm>state2-----------") print(outputs2) # 可以看出output2的最后一個時刻的輸出即為LSTMStateTuple中的h print(state2) print(np.all(outputs2[:,-1,:] == state2[1]))
再來懟懟dynamic_rnn中數(shù)據(jù)序列長度tricks
思路樣例代碼
from collections import Counter import numpy as np origin_data = np.array([[1, 2, 3], [3, 0, 2], [1, 1, 4], [2, 1, 2], [0, 1, 1], [2, 0, 3] ]) # 按照指定列索引進行分組(看作RNN中一個樣本序列),如下為按照第二列分組的結(jié)果 # [[[1, 2, 3], [0, 0, 0], [0, 0, 0]], # [[3, 0, 2], [2, 0, 3], [0, 0, 0]], # [[1, 1, 4], [2, 1, 2], [0, 1, 1]]] # 第一步,將原始數(shù)據(jù)按照某列序列化使之成為一個序列數(shù)據(jù) def groupby(a, col_index): # 未加入索引越界判斷 max_len = max(Counter(a[:, col_index]).values()) for i in set(a[:, col_index]): d[i] = [] for sample in a: d[sample[col_index]].append(list(sample)) # for key in d: # d[key].extend([[0]*a.shape[1] for _ in range(max_len-len(d[key]))]) return list(d.values()), [len(_) for _ in d.values()] samples, sizes = groupby(origin_data, 2) # 第二步,根據(jù)當前這一批次的中最大序列長度max(sizes)作為padding標準(不同批次的樣本序列長度可以不一樣,但同一批次要求一樣(包括padding的部分)),當然也可以一次性將所有樣本(不按照批量)按照最大序列長度padding也行,可能空間浪費 paddig_samples = np.zeros([len(samples), max(sizes), 3]) for seq_index, seq in enumerate(samples): paddig_samples[seq_index, :len(seq), :] = seq paddig_samples
以上這篇keras在構(gòu)建LSTM模型時對變長序列的處理操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python3 中把txt數(shù)據(jù)文件讀入到矩陣中的方法
下面小編就為大家分享一篇Python3 中把txt數(shù)據(jù)文件讀入到矩陣中的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04python GUI編程(Tkinter) 創(chuàng)建子窗口及在窗口上用圖片繪圖實例
這篇文章主要介紹了python GUI編程(Tkinter) 創(chuàng)建子窗口及在窗口上用圖片繪圖實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03python實現(xiàn)漢諾塔遞歸算法經(jīng)典案例
這篇文章主要大家分享了python實現(xiàn)漢諾塔遞歸算法經(jīng)典案例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-05-05Selenium中免登錄的實現(xiàn)方法option詳解
在selenium中有很多種可以實現(xiàn)網(wǎng)站的免登錄,option就是其中的一種做法,這篇文章主要介紹了Selenium中免登錄的實現(xiàn)方法option,需要的朋友可以參考下2022-12-12django獲取from表單multiple-select的value和id的方法
今天小編就為大家分享一篇django獲取from表單multiple-select的value和id的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
這篇文章主要介紹了OpenCV2.3.1+Python2.7.3+Numpy等的配置解析,具有一定借鑒價值,需要的朋友可以參考下2018-01-01