我就废话不多说了,大家还是直接看代码吧~
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']) # 用于保存验证集误差最小的参数,当验证集误差减少时,保存下来 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)数据形式及Padding操作处理变长时序序列dynamic_rnn
Summary
RNN
样本一样,计算的状态值和输出结构一致,也即是说只要当前时刻的输入值也前一状态值一样,那么其当前状态值和当前输出结果一致,因为在当前这一轮训练中权重参数和偏置均未更新
RNN的最终状态值与最后一个时刻的输出值一致
输入数据要求格式为,shape=(batch_size, step_time_size, input_size),那么,state的shape=(batch_size, state_size);output的shape=(batch_size, step_time_size, state_size),并且最后一个有效输出(有效序列长度,不包括padding的部分)与状态值会一样
LSTM
LSTM与RNN基本一致,不同在于其状态有两个c_state和h_state,它们的shape一样,输出值output的最后一个有效输出与h_state一致
用变长RNN训练,要求其输入格式仍然要求为shape=(batch_size, step_time_size, input_size),但可指定每一个批次中各个样本的有效序列长度,这样在有效长度内其状态值和输出值原理不变,但超过有效长度的部分的状态值将不会发生改变,而输出值都将是shape=(state_size,)的零向量(注:RNN也是这个原理)
需要说明的是,不是因为无效序列长度部分全padding为0而引起输出全为0,状态不变,因为输出值和状态值得计算不仅依赖当前时刻的输入值,也依赖于上一时刻的状态值。其内部原理是利用一个mask matrix矩阵标记有效部分和无效部分,这样在无效部分就不用计算了,也就是说,这一部分不会造成反向传播时对参数的更新。当然,如果padding不是零,那么padding的这部分输出和状态同样与padding为零的结果是一样的
''' #样本数据为(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)) # 输入数据只需能够迭代并符合要求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中参数变量 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中数据序列长度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中一个样本序列),如下为按照第二列分组的结果 # [[[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]]] # 第一步,将原始数据按照某列序列化使之成为一个序列数据 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) # 第二步,根据当前这一批次的中最大序列长度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在构建LSTM模型时对变长序列的处理操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持小牛知识库。
我有一个顺序模型定义如下: 我想更改此模型,以获取可变形状的输入。具体来说,第一个维度需要可变。阅读关于指定输入形状的Keras文档,我发现可以在input\u shape元组中使用None条目,其中None表示可能需要任何正整数。 对于现有模型,如果我将input\u形状从(2,4)更改为(None,4),我将收到以下错误: 我不确定,但我不相信当模型包含一个flatte()层时,可以指定可变的
译者:ETCartman 之前我们已经学过了许多的前馈网络. 所谓前馈网络, 就是网络中不会保存状态. 然而有时 这并不是我们想要的效果. 在自然语言处理 (NLP, Natural Language Processing) 中, 序列模型是一个核心的概念. 所谓序列模型, 即输入依赖于时间信息的模型. 一个典型的序列模型是隐马尔科夫模型 (HMM, Hidden Markov Model). 另
问题内容: 我知道这是一个有很多问题的主题,但是我找不到解决问题的办法。 我正在使用遮罩层在可变长度输入上训练LSTM网络,但似乎没有任何效果。 输入形状(100、362、24),其中362为最大序列长度,特征为24,特征数为100,样本数为100(划分为75列/有效值为25)。 输出形状(100,362,1)随后转换为(100,362-N,1)。 这是我的网络的代码: 我的数据最后被填充。例:
本文向大家介绍pytorch对可变长度序列的处理方法详解,包括了pytorch对可变长度序列的处理方法详解的使用技巧和注意事项,需要的朋友参考一下 主要是用函数torch.nn.utils.rnn.PackedSequence()和torch.nn.utils.rnn.pack_padded_sequence()以及torch.nn.utils.rnn.pad_packed_sequence()来
我想创建一个Keras模型,包括一个嵌入层,然后是两个具有dropout 0.5的LSTM,最后是一个具有softmax激活的密集层。 第一个LSTM应该将顺序输出传播到第二层,而在第二层中,我只想在处理完整个序列后获得LSTM的隐藏状态。 我尝试了以下方法: 但是,我遇到以下错误: 显然,LSTM并没有返回我所期望的形状输出。如何修复此问题?
问题内容: 我试图使用RNN(特别是LSTM)进行序列预测。但是,我遇到了序列长度可变的问题。例如, 我正在尝试使用一个基于此基准的简单RNN预测当前单词之后的下一个单词,以构建PTB LSTM模型 。 但是,该参数(用于展开到先前的隐藏状态)在每个Tensorflow的时期应保持相同。基本上,批处理句子是不可能的,因为句子的长度会有所不同。 在这里,对于我来说,每个句子都需要更改。我已经尝试了几