如何构建数据库系统为LSTM重新构建输入数据

注:本文主要是在http://colah.github.io/posts/2015-08-Understanding-LSTMs/ 这篇文章的基础上理解写成,姑且也可以称作 The understanding of understanding LSTM network. 感谢此篇作者的无私分享和通俗精确的讲解。
& & & & & 说到LSTM,无可避免的首先要提到最简单最原始的RNN。在这一部分,我的目标只是理解“循环神经网络”中的‘循环’二字,不打算扔出任何公式,顺便一提曾经困惑过我的keras中的输入数据格式。
& & & &我们经常可以看到有人说,LSTM适合时序序列,变长序列,尤其适合自然语言处理。那么是什么赋予它可以处理变长序列的能力呢? 其实,只要仔细研究上图,相信每个人都能有一个直观的答案。
& & & &从图片左边来看,RNN有两个输入,一个是当前t时刻的输入Xt, 另一个是一个看似“本身“的输入。
& & & &这样看还不甚明了,再看图片右边: 实际上右图是左图的一个在时间序列上的展开,上一个时刻输出是这一个时刻的输入。值得注意的是,实际上,右图上的所有神经元是同一个神经元,也就是左图,它们共享同样的权值,只不过在每一个时刻接受不同的输入,再把输出给下一个时刻作为输入。这就是存储的过去的信息。
& & & &理解到“循环”的含义即达到本章的目的了,公式和细节将在LSTM中详细叙述。
& & & &keras中文文档:&http://keras-cn.readthedocs.io/en/latest/layers/recurrent_layer/ &(中文文档真的做的很赞,除了翻译的内容,还加了额外的内容,例如tensor, batch size的概念帮助DL新手理解)
& & & &在所有的RNN中,包括simpleRNN, LSTM, GRU等等,输入输出数据格式如下:
& & & & &输入是一个三维向量。samples即为数据的条数。难以理解的是timesteps 和input_dim. Input_dim是数据的表示形式的维度,timestep则为总的时间步数。例如这样一个数据,总共100条句子,每个句子20个词,每个词都由一个80维的向量表示。在RNN中,每一个timestep的输入是一个词(当然这不一定,你也可以调成两个词或者其他),从第一张RNN的图来看,t0时刻是第一个时间步,x0则为代表一条句子中第一个词的80维向量,t1是第二个时间步,x1表示句子中第二个词的80维向量。。。所以,输入数据的大小应当是(100, 20, 80)&
& & & &注:实际中句子长度不会一模一样,但从RNN的工作流程来看,它可以处理变长序列。在kera中,可以首先将句子设为最大长度,不足这个长度的句子补足0,然后在RNN层前加embedding层或者Mask层过滤掉补足的字符。具体在我的博文中
http://www.cnblogs.com/leeshum/p/6089286.html
未完待续。。(搬砖去了)
阅读(...) 评论()tensorflow笔记:多层LSTM代码分析 - 吾知 - 博客园
tensorflow笔记系列:&(一)&tensorflow笔记:流程,概念和简单代码注释&(二)&tensorflow笔记:多层CNN代码分析&(三)&tensorflow笔记:多层LSTM代码分析&(四)&tensorflow笔记:常用函数说明&(五)&tensorflow笔记:模型的保存与训练过程可视化&(六)tensorflow笔记:使用tf来实现word2vec
之前讲过了tensorflow中CNN的示例代码,现在我们来看RNN的代码。不过好像官方只给了LSTM的代码。那么我们就来看LSTM吧。LSTM的具体原理就不讲了,可以参见,讲的非常清楚。
坦白说,这份写LSTM的代码有点难,倒不是说LSTM的原理有多难,而是这份代码中使用了大量tf提供的现成的操作函数。在精简了代码的同时,也增加了初学者阅读的难度。很多函数的用法我是去看源码,然后自己写示例代码才搞懂的。当然如果能把整份代码搞清楚的话,掌握这么多操作函数还是非常有用的。
这份代码并没有完整的出现在tf给出的示例中,而是只挑选了几个片段简略的介绍了一下。我当时看完之后简直是一头雾水。后来在github找到了这份代码的,发现这份文件只能在命令行里面运行,需要输入参数,例如
后来我改写了一下,使之可以直接运行。当然,运行之前需要先手动下载数据集,数据集的地址在
总的来看,这份代码主要由三步分组成。&第一部分,是PTBModel,也是最核心的部分,负责tf中模型的构建和各种操作(op)的定义。&第二部分,是run_epoch函数,负责将所有文本内容分批喂给模型(PTBModel)训练。&第三部分,就是main函数了,负责将第二部分的run_epoch运行多遍,也就是说,文本中的每个内容都会被重复多次的输入到模型中进行训练。随着训练的进行,会适当的进行一些参数的调整。&下面就按照这几部分来分开讲一下。我在后面提供了完整的代码,所以可以将完整代码和分段讲解对照着看。
在构建模型和训练之前,我们首先需要设置一些参数。tf中可以使用tf.flags来进行全局的参数设置
flags = tf.flags
logging = tf.logging
flags.DEFINE_string(
细心的人可能会注意到上面有行代码定义了model的值为small.这个是什么意思呢?其实在后面的完整代码部分可以看到,作者在其中定义了几个参数类,分别有small,medium,large和test这4种参数。如果model的值为small,则会调用SmallConfig,其他同样。在SmallConfig中,有如下几个参数:
init_scale = 0.1
其他的几个参数类中,参数类型都是一样的,只是参数的值各有所不同。
这个可以说是核心部分了。而具体来说,又可以分成几个小部分:多层LSTM结构的构建,输入预处理,LSTM的循环,损失函数计算,梯度计算和修剪
self.batch_size = batch_size = config.batch_size
self.num_steps = num_steps = config.num_steps
size = config.hidden_size
# 隐藏层规模
vocab_size = config.vocab_size
# 词典规模
self._input_data = tf.placeholder(tf.int32, [batch_size, num_steps])
self._targets = tf.placeholder(tf.int32, [batch_size, num_steps])
# 预期输出,两者都是index序列,长度为num_step
首先引进参数,然后定义2个占位符,分别表示输入和预期输出。注意此时不论是input还是target都是用词典id来表示单词的。
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(size, forget_bias=0.0, state_is_tuple=True)
首先使用tf.nn.rnn_cell.BasicLSTMCell定义单个基本的LSTM单元。这里的size其实就是hidden_size。&从源码中可以看到,在LSTM单元中,有2个状态值,分别是c和h,分别对应于下图中的c和h。其中h在作为当前时间段的输出的同时,也是下一时间段的输入的一部分。
那么当state_is_tuple=True的时候,state是元组形式,state=(c,h)。如果是False,那么state是一个由c和h拼接起来的张量,state=tf.concat(1,[c,h])。在运行时,则返回2值,一个是h,还有一个state。
DropoutWrapper
if is_training and config.keep_prob & 1: # 在外面包裹一层dropout
lstm_cell = tf.nn.rnn_cell.DropoutWrapper(
lstm_cell, output_keep_prob=config.keep_prob)
我们在这里使用了dropout方法。所谓dropout,就是指网络中每个单元在每次有数据流入时以一定的概率(keep prob)正常工作,否则输出0值。这是是一种有效的正则化方法,可以有效防止过拟合。在rnn中使用dropout的方法和cnn不同,推荐大家去把看一遍。&在rnn中进行dropout时,对于rnn的部分不进行dropout,也就是说从t-1时候的状态传递到t时刻进行计算时,这个中间不进行memory的dropout;仅在同一个t时刻中,多层cell之间传递信息的时候进行dropout,如下图所示
上图中,t-2时刻的输入xt-2首先传入第一层cell,这个过程有dropout,但是从t-2时刻的第一层cell传到t-1,t,t+1的第一层cell这个中间都不进行dropout。再从t+1时候的第一层cell向同一时刻内后续的cell传递时,这之间又有dropout了。
在使用tf.nn.rnn_cell.DropoutWrapper时,同样有一些参数,例如input_keep_prob,output_keep_prob等,分别控制输入和输出的dropout概率,很好理解。
多层LSTM结构和状态初始化
cell = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * config.num_layers, state_is_tuple=True)
# 参数初始化,rnn_cell.RNNCell.zero_stat
self._initial_state = cell.zero_state(batch_size, data_type())
在这个示例中,我们使用了2层的LSTM网络。也就是说,前一层的LSTM的输出作为后一层的输入。使用tf.nn.rnn_cell.MultiRNNCell可以实现这个功能。这个基本没什么好说的,state_is_tuple用法也跟之前的类似。构造完多层LSTM以后,使用zero_state即可对各种状态进行初始化。
输入预处理
with tf.device("/cpu:0"):
embedding = tf.get_variable(
# vocab size * hidden size, 将单词转成embedding描述
"embedding", [vocab_size, size], dtype=data_type())
# 将输入seq用embedding表示, shape=[batch, steps, hidden_size]
inputs = tf.nn.embedding_lookup(embedding, self._input_data)
if is_training and config.keep_prob & 1:
inputs = tf.nn.dropout(inputs, config.keep_prob)
之前有提到过,输入模型的input和target都是用词典id表示的。例如一个句子,“我/是/学生”,这三个词在词典中的序号分别是0,5,3,那么上面的句子就是[0,5,3]。显然这个是不能直接用的,我们要把词典id转化成向量,也就是embedding形式。可能有些人已经听到过这种描述了。实现的方法很简单。
第一步,构建一个矩阵,就叫embedding好了,尺寸为[vocab_size, embedding_size],分别表示词典中单词数目,以及要转化成的向量的维度。一般来说,向量维度越高,能够表现的信息也就越丰富。
第二步,使用tf.nn.embedding_lookup(embedding,input_ids) 假设input_ids的长度为len,那么返回的张量尺寸就为[len,embedding_size]。举个栗子
# 示例代码
import tensorflow as tf
import numpy as np
sess = tf.InteractiveSession()
embedding = tf.Variable(np.identity(5,dtype=np.int32))
input_ids = tf.placeholder(dtype=tf.int32,shape=[None])
input_embedding = tf.nn.embedding_lookup(embedding,input_ids)
sess.run(tf.initialize_all_variables())
print(sess.run(embedding))
#[[1 0 0 0 0]
# [0 1 0 0 0]
# [0 0 1 0 0]
# [0 0 0 1 0]
# [0 0 0 0 1]]
print(sess.run(input_embedding,feed_dict={input_ids:[1,2,3,0,3,2,1]}))
#[[0 1 0 0 0]
# [0 0 1 0 0]
# [0 0 0 1 0]
# [1 0 0 0 0]
# [0 0 0 1 0]
# [0 0 1 0 0]
# [0 1 0 0 0]]
第三步,如果keep_prob&1, 那么还需要对输入进行dropout。不过这边跟rnn的dropout又有所不同,这边使用tf.nn.dropout。
现在,多层lstm单元已经定义完毕,输入也已经经过预处理了。那么现在要做的就是将数据输入lstm进行训练了。其实很简单,只要按照文本顺序依次向cell输入数据就好了。lstm上一时间段的状态会自动参与到当前时间段的输出和状态的计算当中。
outputs = []
state = self._initial_state # state 表示 各个batch中的状态
with tf.variable_scope("RNN"):
for time_step in range(num_steps):
if time_step & 0: tf.get_variable_scope().reuse_variables()
# cell_out: [batch, hidden_size]
(cell_output, state) = cell(inputs[:, time_step, :], state) # 按照顺序向cell输入文本数据
outputs.append(cell_output)
# output: shape[num_steps][batch,hidden_size]
# 把之前的list展开,成[batch, hidden_size*num_steps],然后 reshape, 成[batch*numsteps, hidden_size]
output = tf.reshape(tf.concat(1, outputs), [-1, size])
这边要注意,tf.get_variable_scope().reuse_variables()这行代码不可少,不然会报错,应该是因为同一命名域(variable_scope)内不允许存在多个同一名字的变量的原因。
损失函数计算
# softmax_w , shape=[hidden_size, vocab_size], 用于将distributed表示的单词转化为one-hot表示
softmax_w = tf.get_variable(
"softmax_w", [size, vocab_size], dtype=data_type())
softmax_b = tf.get_variable("softmax_b", [vocab_size], dtype=data_type())
# [batch*numsteps, vocab_size] 从隐藏语义转化成完全表示
logits = tf.matmul(output, softmax_w) + softmax_b
# loss , shape=[batch*num_steps]
# 带权重的交叉熵计算
loss = tf.nn.seq2seq.sequence_loss_by_example(
# output [batch*numsteps, vocab_size]
[tf.reshape(self._targets, [-1])],
# target, [batch_size, num_steps] 然后展开成一维【列表】
[tf.ones([batch_size * num_steps], dtype=data_type())]) # weight
self._cost = cost = tf.reduce_sum(loss) / batch_size # 计算得到平均每批batch的误差
self._final_state = state
上面代码的上半部分主要用来将多层lstm单元的输出转化成one-hot表示的向量。关于one-hot presentation和distributed presentation的区别,可以参考
代码的下半部分,正式开始计算损失函数。这里使用了tf提供的现成的交叉熵计算函数,tf.nn.seq2seq.sequence_loss_by_example。不知道交叉熵是什么?见各个变量的具体shape我都在注释中标明了。注意其中的self._targets是词典id表示的。这个函数的具体实现方式不明。我曾经想自己手写一个交叉熵,不过好像tf不支持对张量中单个元素的操作。
之前已经计算得到了每批数据的平均误差。那么下一步,就是根据误差来进行参数修正了。当然,首先必须要求梯度
self._lr = tf.Variable(0.0, trainable=False)
通过tf.trainable_variables 可以得到整个模型中所有trainable=True的Variable。实际得到的tvars是一个列表,里面存有所有可以进行训练的变量。
grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars),
config.max_grad_norm)
这一行代码其实使用了两个函数,tf.gradients 和 tf.clip_by_global_norm。 我们一个一个来。
tf.gradients&用来计算导数。该函数的定义如下所示
def gradients(ys,
grad_ys=None,
name="gradients",
colocate_gradients_with_ops=False,
gate_gradients=False,
aggregation_method=None):
虽然可选参数很多,但是最常使用的还是ys和xs。根据说明得知,ys和xs都可以是一个tensor或者tensor列表。而计算完成以后,该函数会返回一个长为len(xs)的tensor列表,列表中的每个tensor是ys中每个值对xs[i]求导之和。如果用数学公式表示的话,那么&g = tf.gradients(y,x)可以表示成&
gi=∑j=0len(y)?yj?xig=[g0,g1,...,glen(x)]
tf.clip_by_global_norm&修正梯度值,用于控制梯度爆炸的问题。梯度爆炸和梯度弥散的原因一样,都是因为链式法则求导的关系,导致梯度的指数级衰减。为了避免梯度爆炸,需要对梯度进行修剪。&先来看这个函数的定义:
def clip_by_global_norm(t_list, clip_norm, use_norm=None, name=None):
输入参数中:t_list为待修剪的张量, clip_norm 表示修剪比例(clipping ratio).
函数返回2个参数: list_clipped,修剪后的张量,以及global_norm,一个中间计算量。当然如果你之前已经计算出了global_norm值,你可以在use_norm选项直接指定global_norm的值。
那么具体如何计算呢?根据源码中的说明,可以得到&list_clipped[i]=t_list[i] * clip_norm / max(global_norm, clip_norm),其中&global_norm = sqrt(sum([l2norm(t)**2 for t in t_list]))
如果你更熟悉数学公式,则可以写作&
Lic=Lit*Ncmax(Nc,Ng)Ng=∑i(Lit)2-------√
其中,&Lic和Lig代表t_list[i]和list_clipped[i],&Nc和Ng代表clip_norm 和 global_norm的值。&其实也可以看到其实Ng就是t_list的L2模。上式也可以进一步写作&
Lic={Lit,(Ng&=Nc)Lit*NcNg,(Ng&Nc)Ng=∑i(Lit)2-------√
也就是说,当t_list的L2模大于指定的Nc时,就会对t_list做等比例缩放
之前的代码已经求得了合适的梯度,现在需要使用这些梯度来更新参数的值了。
# 梯度下降优化,指定学习速率
optimizer = tf.train.GradientDescentOptimizer(self._lr)
# optimizer = tf.train.AdamOptimizer()
# optimizer = tf.train.GradientDescentOptimizer(0.5)
self._train_op = optimizer.apply_gradients(zip(grads, tvars))
# 将梯度应用于变量
# self._train_op = optimizer.minimize(grads)
这一部分就比较自由了,tf提供了很多种优化器,例如最常用的梯度下降优化(GradientDescentOptimizer)也可以使用AdamOptimizer。这里使用的是梯度优化。值得注意的是,这里使用了optimizer.apply_gradients来将求得的梯度用于参数修正,而不是之前简单的optimizer.minimize(cost)
还有一点,要留心一下self._train_op,只有该操作被模型执行,才能对参数进行优化。如果没有执行该操作,则参数就不会被优化。
这就是我之前讲的第二部分,主要功能是将所有文档分成多个批次交给模型去训练,同时记录模型返回的cost,state等记录,并阶段性的将结果输出。
def run_epoch(session, model, data, eval_op, verbose=False):
"""Runs the model on the given data."""
基本没什么其他的,就是要注意传入的eval_op。在训练阶段,会往其中传入train_op,这样模型就会自动进行优化;而在交叉检验和阶段,传入的是tf.no_op,此时模型就不会优化。
这里略去了数据读取和参数读取的代码,只贴了最关键的一部分。
with tf.Graph().as_default(), tf.Session() as session:
注意这里定义了3个模型,对于训练模型,is_trainable=T 而对于交叉检验和测试模型,is_trainable=False
summary_writer = tf.train.SummaryWriter('/tmp/lstm_logs',session.graph)
tf.initialize_all_variables().run()
注意上面train_perplexity操作中传入了m.train_op,表示要进行优化,而在valid_perplexity和test_perplexity中均传入了tf.no_op,表示不进行优化。
完整代码和注释&>&tensorflow 1.3 lstm训练和预测铁路客运数据
tensorflow 1.3 lstm训练和预测铁路客运数据
上传大小:3KB
使用LSTM预测铁路客运时间序列,代码在tensorflow 1.3上调试运行通过,解决了网络相关资源的一些坑(很多资源不是tensorflow的版本太旧就是数据与铁路客运数据不太匹配,难以直接运行测试),不需要建立train模型和test模型(被绕了半天,这种测试应该毫无必要),可对不同的超参数组合比较训练误差和学习误差!
综合评分:4(2位用户评分)
下载个数:
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有2条
need it right now, tks
编译出错了 UnicodeDecodeError: 'gbk' codec can't decode byte 0xbc in position 31: illegal multibyte sequence
tkyjqh回复oulin0091
应该不编译呀,是运行哪个语句出错了?
tkyjqh回复oulin0091
你参考一下,http://www.cnblogs.com/mengyu/p/6638975.html
综合评分:
积分/C币:13
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
tensorflow 1.3 lstm训练和预测铁路客运数据
会员到期时间:
剩余下载个数:
剩余积分:
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
(仅够下载10个资源)
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励5下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
tensorflow 1.3 lstm训练和预测铁路客运数据你的浏览器禁用了JavaScript, 请开启后刷新浏览器获得更好的体验!
最近想在实验上试试lstm,对于caffe的lstm来说貌似是针对语言模型,看过Jeff Donahue大神提供的简单语言模型的lstm_language_model.prototxt文件,文件中是先提供源数据然后搭建lstm,lstmde 输入blob格式是T*N*8801,另外引入了一个计数器cont:T*N.对于我来说,想要先用new_.reset(new Net())预设置网络框架,即先在prototxt文件中先设置输入Bolb个数、维度和网络的整体框架,并不带入数据,后面通过mutable_cpu_data()才带入数据,具体是在全连接层后加入lstm层。但是我在prototxt前面先预定义输入Blob的shape,想先预搭建好网络模型却一直失败,对比了语言模型输入Blob的格式(T*N*Vector)表示没错误,我也提供了cont的Blob(T*N),就是一直报错。望有使用LSTM层的大牛指点迷津,先行谢过!
... 没看明白你说的啥意思 复杂的模型建议你用python layer去构建 尤其是涉及到LSTM的时候;其实还有一个办法就是用python写的proto生成器生成一个超复杂的网络文件 对应的python文件很简单 但是生成的网络proto很复杂 说白了就是把递归全部展开了写到一个proto里
Jeff Donahue大神提供的简单语言模型的lstm_language_model.prototxt文件在哪,有网址吗兄弟,我也正在学习,能发一下吗,多谢!
要回复问题请先或
既然入了dl这个坑,就好好干~~
浏览: 2454
关注: 2 人如何为LSTM重新构建输入数据(Keras)
摘要:对于初入门的开发人员,如何为LSTM准备数据一直是一个问题。在为LSTM准备数据的过程中的确有很多需要注意的问题,阅读本文可能会帮助你解决更多的问题。
对于初入门的开发人员来说,这可能是非常困难的事情为LSTM模型准备序列数据。通常入门的开发者会在有关如何定义LSTM模型的输入层这件事情上感到困惑。还有关于如何将可能是1D或2D数字矩阵的序列数据转换可以输入到LSTM输入层所需的3D格式的困难。
在本文中,你将了解如何将输入层定义为LSTM模型,以及如何重新构建可以输入到LSTM模型的输入数据。
看完本文后,你将知道:
如何定义LSTM的输入层。
如何重塑LSTM模型的一维序列数据并定义输入层。
如何重塑LSTM模型的多并行系列数据并定义输入层。
教程概述本文分为4部分:
1.LSTM输入层。
2.具有单输入样本的LSTM示例。
3.具有多个输入特征的LSTM示例。
4.LSTM输入提示。
LSTM输入层
LSTM输入层是由神经网络第一个隐藏层上的“ input_shape ”参数指定的。这可能会让初学者感到困惑。例如,以下是具有一个隐藏的LSTM层和一个密集输出层组成的神经网络示例。
model =Sequential ()model.add (LSTM (32 ))model.add (Dense (1 ))
在这个例子中,我们可以看到LSTM()层必须指定输入的形状。而且每个LSTM层的输入必须是三维的。这输入的三个维度是:
样品。一个序列是一个样本。批次由一个或多个样本组成。
时间步。一个时间步代表样本中的一个观察点。
特征。一个特征是在一个时间步长的观察得到的。
这意味着输入层在拟合模型时以及在做出预测时,对数据的要求必须是3D数组,即使数组的特定维度仅包含单个值。
当定义LSTM网络的输入层时,网络假设你有一个或多个样本,并会给你指定时间步长和特征数量。你可以通过修改“ input_shape ”的参数修改时间步长和特征数量。例如,下面的模型定义了包含一个或多个样本,50个时间步长和2个特征的输入层。
model = Sequential()model.add(LSTM(32, input_shape=(50, 2)))model.add(Dense(1))
现在我们知道如何定义LSTM输入层,接下来我们来看一些我们如何为LSTM准备数据的例子。
具有单输入样本的LSTM示例
考虑到你可能会有多个时间步骤和一个特征序列的情况,所以我们先从这种情况讲起。例如,这是一个包含10个数字的序列:
0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0
我们可以将这个数字序列定义为NumPy数组。
from numpy importarraydata =array ([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 ])
然后,我们可以使用NumPy数组中的reshape()函数将这个一维数组重构为三维数组,每个时间步长为1个样本,那么我们需要10个时间步长和1个特征。
在数组上调用的reshape()函数需要一个参数,它是定义数组新形状的元组。我们不能干涉数据的重塑,重塑必须均匀地重组数组中的数据。
data = data.reshape((1, 10, 1))
一旦重塑,我们可以打印阵列的新形状。
print (data.shape )
完整的例子如下:
from numpy import arraydata = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])data = data.reshape((1, 10, 1))print(data.shape)
运行示例打印单个样本的新3D形状:
(1, 10, 1)
该数据现在可以为input_shape(10,1)的LSTM的输入(X)。
model = Sequential()model.add(LSTM(32, input_shape=(10, 1)))model.add(Dense(1)) 具有多个输入功能的LSTM示例
你的模型可能有多个并行数据作为输入的情况,接下来我们来看看这种情况。
例如,这可以是两个并行的10个值:
series 1: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0
series 2: 1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1
我们可以将这些数据定义为具有10行的2列的矩阵:
from numpy importarraydata =array ([[0.1, 1.0 ], [0.2, 0.9 ], [0.3, 0.8 ], [0.4, 0.7 ], [0.5, 0.6 ], [0.6, 0.5 ], [0.7, 0.4 ], [0.8, 0.3 ], [0.9, 0.2 ], [1.0, 0.1 ]])
该数据可以被设置为1个样本,具有10个时间步长和2个特征。
它可以重新整形为3D阵列,如下所示:
data = data.reshape(1, 10, 2)
完整的例子如下:
from numpy import arraydata = array([ [0.1, 1.0], [0.2, 0.9], [0.3, 0.8], [0.4, 0.7], [0.5, 0.6], [0.6, 0.5], [0.7, 0.4], [0.8, 0.3], [0.9, 0.2], [1.0, 0.1]])data = data.reshape(1, 10, 2)print(data.shape)
运行示例打印单个样本的新3D形状。
(1, 10, 2)
该数据现在可以为input_shape(10,2)作为LSTM的输入(X)使用。
model = Sequential()model.add(LSTM(32, input_shape=(10, 2)))model.add(Dense(1)) LSTM输入提示
接下来我列出了在为LSTM准备输入数据时可以帮助你的一些提示。
1.LSTM输入层必须是3D。
2.3个输入尺寸的含义是:样本,时间步长和特征。
3.LSTM输入层由第一个隐藏层上的input_shape参数定义。
4.所述input_shape参数是限定的时间的步骤和特征数量的两个值的元组。
5.样本数默认假定为大于1。
6.NumPy数组中的reshape()函数可用于将你的1D或2D数据重塑为3D。
7.reshape()函数会将一个元组作为新定义的形状的参数。
进一步阅读
如果你进一步了解,本部分将提供有关该主题的更多资源。
Recurrent Layers Keras API。
Numpy reshape()函数API。
如何将时间序列转换为Python中的监督学习问题。
时间序列预测作为监督学习。
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点

我要回帖

更多关于 ps4重新构建数据库 的文章

 

随机推荐