keras在构建LSTM模型时对变长序列的处理操作


Posted in Python onJune 29, 2020

我就废话不多说了,大家还是直接看代码吧~

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

keras在构建LSTM模型时对变长序列的处理操作

思路样例代码

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模型时对变长序列的处理操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python的Django框架中的数据库配置指南
Jul 17 Python
利用Python如何生成便签图片详解
Jul 09 Python
python中字符串内置函数的用法总结
Sep 13 Python
python3.6.3转化为win-exe文件发布的方法
Oct 31 Python
Face++ API实现手势识别系统设计
Nov 21 Python
python实现基于信息增益的决策树归纳
Dec 18 Python
Python列表常见操作详解(获取,增加,删除,修改,排序等)
Feb 18 Python
用Python调用win命令行提高工作效率的实例
Aug 14 Python
Python集合操作方法详解
Feb 09 Python
python实现快速文件格式批量转换的方法
Oct 16 Python
scrapy在python爬虫中搭建出错的解决方法
Nov 22 Python
python模拟点击在ios中实现的实例讲解
Nov 26 Python
Python爬虫爬取博客实现可视化过程解析
Jun 29 #Python
使用keras框架cnn+ctc_loss识别不定长字符图片操作
Jun 29 #Python
浅谈keras中的后端backend及其相关函数(K.prod,K.cast)
Jun 29 #Python
如何使用python记录室友的抖音在线时间
Jun 29 #Python
Python sublime安装及配置过程详解
Jun 29 #Python
keras K.function获取某层的输出操作
Jun 29 #Python
Python pytesseract验证码识别库用法解析
Jun 29 #Python
You might like
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
2017/12/26 PHP
js类中获取外部函数名的方法与代码
2007/09/12 Javascript
javaScript 判断字符串是否为数字的简单方法
2009/07/25 Javascript
点击弹出层效果&amp;弹出窗口后网页背景变暗效果的实现代码
2014/02/10 Javascript
jquery.fastLiveFilter.js实现输入自动过滤的方法
2015/08/11 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
浅谈js中用$(#ID)来作为选择器的问题(id重复的时候)
2017/02/14 Javascript
js中删除数组中的某一元素实例(无下标时)
2017/02/28 Javascript
javascript实现数据双向绑定的三种方式小结
2017/03/09 Javascript
微信小程序开发图片拖拽实例详解
2017/05/05 Javascript
关于Ajax的原理以及代码封装详解
2017/09/08 Javascript
vue中改变选中当前项的显示隐藏或者状态的实现方法
2018/02/08 Javascript
mint-ui在vue中的使用示例
2018/04/05 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
一次Webpack配置文件的分离实战记录
2018/11/30 Javascript
js实现随机抽奖
2020/03/19 Javascript
nestjs返回给前端数据格式的封装实现
2021/02/22 Javascript
python实现给字典添加条目的方法
2014/09/25 Python
Python 确定多项式拟合/回归的阶数实例
2018/12/29 Python
Python安装及Pycharm安装使用教程图解
2019/09/20 Python
Python面向对象之继承原理与用法案例分析
2019/12/31 Python
Python实现新型冠状病毒传播模型及预测代码实例
2020/02/05 Python
PyQt5实现仿QQ贴边隐藏功能的实例代码
2020/05/24 Python
python 如何把docker-compose.yaml导入到数据库相关条目里
2021/01/15 Python
python利用opencv实现颜色检测
2021/02/23 Python
购买200个世界上最好的内衣品牌:Bare Necessities
2017/02/11 全球购物
牦牛毛户外探险服装:Kora
2019/02/08 全球购物
学校司机岗位职责
2013/11/14 职场文书
公关关系专员的自我评价分享
2013/11/20 职场文书
幼儿园实习自我鉴定
2013/12/15 职场文书
便利店投资的创业计划书
2014/01/12 职场文书
五年级音乐教学反思
2014/02/06 职场文书
社会学专业求职信
2014/07/17 职场文书
支部书记四风问题对照检查材料
2014/10/04 职场文书
导游词之晋城蟒河
2019/12/12 职场文书