keras在构建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'])

# 用于保存验证集误差最小的参数,当验证集误差减少时,保存下来
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模型时对变长序列的处理操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Python中利用LSTM模型进行时间序列预测分析的实现

    时间序列模型 时间序列预测分析就是利用过去一段时间内某事件时间的特征来预测未来一段时间内该事件的特征.这是一类相对比较复杂的预测建模问题,和回归分析模型的预测不同,时间序列模型是依赖于事件发生的先后顺序的,同样大小的值改变顺序后输入模型产生的结果是不同的. 举个栗子:根据过去两年某股票的每天的股价数据推测之后一周的股价变化:根据过去2年某店铺每周想消费人数预测下周来店消费的人数等等 RNN 和 LSTM 模型 时间序列模型最常用最强大的的工具就是递归神经网络(recurrent neural n

  • 浅谈keras的深度模型训练过程及结果记录方式

    记录训练过程 history=model.fit(X_train, Y_train, epochs=epochs,batch_size=batch_size,validation_split=0.1) 将训练过程记录在history中 利用时间记录模型 import time model_id = np.int64(time.strftime('%Y%m%d%H%M', time.localtime(time.time()))) model.save('./VGG16'+str(model_id

  • keras 解决加载lstm+crf模型出错的问题

    错误展示 new_model = load_model("model.h5") 报错: 1.keras load_model valueError: Unknown Layer :CRF 2.keras load_model valueError: Unknown loss function:crf_loss 错误修改 1.load_model修改源码:custom_objects = None 改为 def load_model(filepath, custom_objects, c

  • 基于Keras 循环训练模型跑数据时内存泄漏的解决方式

    在使用完模型之后,添加这两行代码即可清空之前model占用的内存: import tensorflow as tf from keras import backend as K K.clear_session() tf.reset_default_graph() 补充知识:keras 多个模型测试阶段速度越来越慢问题的解决方法 问题描述 在实际应用或比赛中,经常会用到交叉验证(10倍或5倍)来提高泛化能力,这样在预测时需要加载多个模型.常用的方法为 mods = [] from keras.ut

  • keras在构建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=

  • tensorflow 变长序列存储实例

    问题 问题是这样的,要把一个数组存到tfrecord中,然后读取 a = np.array([[0, 54, 91, 153, 177,1], [0, 50, 89, 147, 196], [0, 38, 79, 157], [0, 49, 89, 147, 177], [0, 32, 73, 145]]) 图片我都存储了,这个不还是小意思,一顿操作 import tensorflow as tf import numpy as np def _int64_feature(value): if

  • 解决pytorch rnn 变长输入序列的问题

    pytorch实现变长输入的rnn分类 输入数据是长度不固定的序列数据,主要讲解两个部分 1.Data.DataLoader的collate_fn用法,以及按batch进行padding数据 2.pack_padded_sequence和pad_packed_sequence来处理变长序列 collate_fn Dataloader的collate_fn参数,定义数据处理和合并成batch的方式. 由于pack_padded_sequence用到的tensor必须按照长度从大到小排过序的,所以在

  • 变长双向rnn的正确使用姿势教学

    如何使用双向RNN 在<深度学习之TensorFlow入门.原理与进阶实战>一书的9.4.2中的第4小节中,介绍过变长动态RNN的实现. 这里在来延伸的讲解一下双向动态rnn在处理变长序列时的应用.其实双向RNN的使用中,有一个隐含的注意事项,非常容易犯错. 本文就在介绍下双向RNN的常用函数.用法及注意事项. 动态双向rnn有两个函数: stack_bidirectional_dynamic_rnn bidirectional_dynamic_rnn 二者的实现上大同小异,放置的位置也不一样

  • keras的三种模型实现与区别说明

    前言 一.keras提供了三种定义模型的方式 1. 序列式(Sequential) API 序贯(sequential)API允许你为大多数问题逐层堆叠创建模型.虽然说对很多的应用来说,这样的一个手法很简单也解决了很多深度学习网络结构的构建,但是它也有限制-它不允许你创建模型有共享层或有多个输入或输出的网络. 2. 函数式(Functional) API Keras函数式(functional)API为构建网络模型提供了更为灵活的方式. 它允许你定义多个输入或输出模型以及共享图层的模型.除此之外

  • 使用Keras实现简单线性回归模型操作

    神经网络可以用来模拟回归问题 (regression),实质上是单输入单输出神经网络模型,例如给下面一组数据,用一条线来对数据进行拟合,并可以预测新输入 x 的输出值. 一.详细解读 我们通过这个简单的例子来熟悉Keras构建神经网络的步骤: 1.导入模块并生成数据 首先导入本例子需要的模块,numpy.Matplotlib.和keras.models.keras.layers模块.Sequential是多个网络层的线性堆叠,可以通过向Sequential模型传递一个layer的list来构造该

  • keras自定义损失函数并且模型加载的写法介绍

    keras自定义函数时候,正常在模型里自己写好自定义的函数,然后在模型编译的那行代码里写上接口即可.如下所示,focal_loss和fbeta_score是我们自己定义的两个函数,在model.compile加入它们,metrics里'accuracy'是keras自带的度量函数. def focal_loss(): ... return xx def fbeta_score(): ... return yy model.compile(optimizer=Adam(lr=0.0001), lo

  • 使用keras内置的模型进行图片预测实例

    keras 模块里面为我们提供了一个预训练好的模型,也就是开箱即可使用的图像识别模型 趁着国庆假期有时间我们就来看看这个预训练模型如何使用吧 可用的模型有哪些? 根据官方文档目前可用的模型大概有如下几个 1.VGG16 2.VGG19 3.ResNet50 4.InceptionResNetV2 5.InceptionV3 它们都被集成到了keras.applications 中 模型文件从哪来 当我们使用了这几个模型时,keras就会去自动下载这些已经训练好的模型保存到我们本机上面 模型文件会

随机推荐