我正在尝试使用Keras使用LSTM进行一些香草模式识别来预测序列中的下一个元素.
我的数据如下所示:
其中训练序列的标签是列表中的最后一个元素:X_train['Sequence'][n][-1]
.
因为我的Sequence
列在序列中可以有可变数量的元素,所以我认为RNN是最好的模型.以下是我在Keras建立LSTM的尝试:
# Build the model
# A few arbitrary constants...
max_features = 20000
out_size = 128
# The max length should be the length of the longest sequence (minus one to account for the label)
max_length = X_train['Sequence'].apply(len).max() - 1
# Normal LSTM model construction with sigmoid activation
model = Sequential()
model.add(Embedding(max_features, out_size, input_length=max_length, dropout=0.2))
model.add(LSTM(128, dropout_W=0.2, dropout_U=0.2))
model.add(Dense(1))
model.add(Activation('sigmoid'))
# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
Run Code Online (Sandbox Code Playgroud)
以下是我尝试训练模型的方法: …
variable-length python-3.x lstm keras recurrent-neural-network
我知道Keras的LSTM需要一个带有形状(nb_samples, timesteps, input_dim)
作为输入的3D张量.但是,我不完全确定在我的情况下输入应该是什么样子,因为我只有一个T
观察样本用于每个输入,而不是多个样本,即(nb_samples=1, timesteps=T, input_dim=N)
.将每个输入分成长度样本是否更好T/M
?T
对我来说是几百万的观察,那么在这种情况下每个样本应该多长时间,即我将如何选择M
?
另外,我是正确的,因为这个张量应该看起来像:
[[[a_11, a_12, ..., a_1M], [a_21, a_22, ..., a_2M], ..., [a_N1, a_N2, ..., a_NM]],
[[b_11, b_12, ..., b_1M], [b_21, b_22, ..., b_2M], ..., [b_N1, b_N2, ..., b_NM]],
...,
[[x_11, x_12, ..., a_1M], [x_21, x_22, ..., x_2M], ..., [x_N1, x_N2, ..., x_NM]]]
Run Code Online (Sandbox Code Playgroud)
其中M和N如前所述定义,x对应于我将从上面讨论的分裂中获得的最后一个样本?
最后,给定一个pandas数据帧,T
每列中都有观察值,N
列,每个输入一个,如何创建这样的输入以馈送给Keras?
我有一个像下面的对话框.我想实现一个预测系统动作的LSTM模型.系统动作被描述为位向量.并且用户输入被计算为字嵌入,其也是位向量.
t1: user: "Do you know an apple?", system: "no"(action=2)
t2: user: "xxxxxx", system: "yyyy" (action=0)
t3: user: "aaaaaa", system: "bbbb" (action=5)
Run Code Online (Sandbox Code Playgroud)
所以我想要实现的是"多对多(2)"模型.当我的模型收到用户输入时,它必须输出系统操作.
但我无法理解LSTM后的
return_sequences
选项和TimeDistributed
图层.要实现"多对多(2)",需要return_sequences==True
添加TimeDistributed
LSTM后?如果你能更多地描述它们,我感激不尽.
return_sequences:布尔值.是返回输出序列中的最后一个输出,还是返回完整序列.
TimeDistributed:此包装器允许将图层应用于输入的每个时间片.
我想我能理解这个return_sequence
选项.但我还不确定TimeDistributed
.如果我添加一个TimeDistributed
LSTM之后,模型是否与下面的"我的多对多(2)"相同?所以我认为Dense图层适用于每个输出.
在Keras
高级深度学习库中,有多种类型的循环层; 这些包括LSTM
(长期短期记忆)和CuDNNLSTM
.根据Keras文档,a CuDNNLSTM
是:
由CuDNN支持的快速LSTM实现.只能在带有TensorFlow后端的GPU上运行.
据我所知,Keras会尽可能自动使用GPU.根据TensorFlow构建说明,要有一个工作的TensorFlow GPU后端,您将需要CuDNN:
必须在您的系统上安装以下NVIDIA软件:
- NVIDIA的Cuda Toolkit(> = 7.0).我们建议使用9.0版.有关详细信息,请参阅NVIDIA的文档.确保您的相关Cuda的路径名追加到PATH环境变量作为NVIDIA文档中的描述.
- 与NVIDIA的Cuda Toolkit相关的NVIDIA驱动程序.
- cuDNN(> = v3).我们建议使用6.0版.有关详细信息,请参阅NVIDIA的文档,特别是将适当的路径名附加到LD_LIBRARY_PATH环境变量的说明.
因此,使用TensorFlow GPU后端CuDNNLSTM
与正常情况LSTM
有何不同?当找到可用的TensorFlow GPU后端时,会CuDNNLSTM
自动选择并替换正常LSTM
吗?
我读了很多关于它的文章,似乎没有人回答这个非常基本的问题.它总是含糊不清:
在stateful = False
LSTM层中,keras会在以下情况后重置状态:
假设我的X_train形状为(1000,20,1),意味着单个值的20个步骤的1000个序列.如果我做:
model.fit(X_train, y_train, batch_size=200, nb_epoch=15)
Run Code Online (Sandbox Code Playgroud)
它会重置每个序列的状态(重置状态1000次)吗?
或者它会重置每个批次的状态(重置状态5次)?
import torch,ipdb
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
input = Variable(torch.randn(5, 3, 10))
h0 = Variable(torch.randn(2, 3, 20))
c0 = Variable(torch.randn(2, 3, 20))
output, hn = rnn(input, (h0, c0))
Run Code Online (Sandbox Code Playgroud)
这是文档中的LSTM示例.我不明白以下事项:
编辑:
import torch,ipdb
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
import torch.nn.functional as F
num_layers=3 …
Run Code Online (Sandbox Code Playgroud) 由于LSTM RNN使用先前的事件来预测当前序列,为什么我们将训练数据混洗?我们不会失去训练数据的时间顺序吗?在对改组后的训练数据进行训练后,如何进行预测仍然有效?
给定训练有素的LSTM模型,我想对单个时间步进行推理,即seq_length = 1
在下面的示例中.在每个时间步之后,需要记住内部LSTM(内存和隐藏)状态以用于下一个"批处理".在推理的最开始,init_c, init_h
给定输入计算内部LSTM状态.然后将它们存储在LSTMStateTuple
传递给LSTM 的对象中.在训练期间,每个时间步都更新此状态.然而,对于推理,我希望state
在批次之间保存,即初始状态只需要在开始时计算,然后在每个"批次"(n = 1)之后保存LSTM状态.
我发现这个相关的StackOverflow问题:Tensorflow,在RNN中保存状态的最佳方法?.但是,这仅在以下情况下有效state_is_tuple=False
,但TensorFlow很快就会弃用此行为(请参阅rnn_cell.py).Keras似乎有一个很好的包装器可以使有状态的 LSTM成为可能,但我不知道在TensorFlow中实现这一目标的最佳方法.TensorFlow GitHub上的这个问题也与我的问题有关:https://github.com/tensorflow/tensorflow/issues/2838
有关构建有状态LSTM模型的任何好建议吗?
inputs = tf.placeholder(tf.float32, shape=[None, seq_length, 84, 84], name="inputs")
targets = tf.placeholder(tf.float32, shape=[None, seq_length], name="targets")
num_lstm_layers = 2
with tf.variable_scope("LSTM") as scope:
lstm_cell = tf.nn.rnn_cell.LSTMCell(512, initializer=initializer, state_is_tuple=True)
self.lstm = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * num_lstm_layers, state_is_tuple=True)
init_c = # compute initial LSTM memory state using contents in placeholder 'inputs'
init_h = # compute initial LSTM …
Run Code Online (Sandbox Code Playgroud) 我的输入只是一个包含339732行和两列的csv文件:
我正在尝试在堆叠的LSTM模型上训练我的数据:
data_dim = 29
timesteps = 8
num_classes = 2
model = Sequential()
model.add(LSTM(30, return_sequences=True,
input_shape=(timesteps, data_dim))) # returns a sequence of vectors of dimension 30
model.add(LSTM(30, return_sequences=True)) # returns a sequence of vectors of dimension 30
model.add(LSTM(30)) # return a single vector of dimension 30
model.add(Dense(1, activation='softmax'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.summary()
model.fit(X_train, y_train, batch_size = 400, epochs = 20, verbose = 1)
Run Code Online (Sandbox Code Playgroud)
这会引发错误:
回溯(最近一次调用最后一次):文件"first_approach.py",第80行,在model.fit中(X_train,y_train,batch_size = 400,epochs = 20,verbose = 1)
ValueError:检查模型输入时出错:预期lstm_1_input有3个维度,但是有形状的数组(339732,29)
我尝试使用重塑我的输入,X_train.reshape((1,339732, 29))
但它没有显示错误:
ValueError:检查模型输入时出错:期望lstm_1_input具有形状(无,8,29)但是具有形状的数组(1,339732,29) …
前言
我目前正在研究机器学习问题,我们的任务是使用过去的产品销售数据来预测未来的销售量(以便商店可以更好地计划他们的库存).我们基本上有时间序列数据,对于每一个产品,我们知道在哪几天销售了多少单位.我们还提供有关天气如何,是否有公众假期,是否有任何产品销售等信息.
我们已经能够使用具有密集层的MLP取得一些成功,并且仅使用滑动窗口方法来包括周围几天的销售量.但是,我们相信,通过LSTM等时间序列方法,我们将能够获得更好的结果.
数据
我们的数据基本如下:
(编辑:为清楚起见,上图中的"时间"列不正确.我们每天输入一次,而不是每月一次.但结构是相同的!)
所以X数据的形状如下:
(numProducts, numTimesteps, numFeatures) = (50 products, 1096 days, 90 features)
Run Code Online (Sandbox Code Playgroud)
并且Y数据的形状如下:
(numProducts, numTimesteps, numTargets) = (50 products, 1096 days, 3 binary targets)
Run Code Online (Sandbox Code Playgroud)
因此,我们有三年的数据(2014年,2015年,2016年),并希望对此进行培训,以便对2017年进行预测.(当然,这不是100%正确,因为我们实际上有数据截至2017年10月,但我们只是现在忽略它)
问题
我想在Keras建立一个LSTM,允许我做出这些预测.有几个地方我被卡住了.所以我有六个具体问题(我知道应该尝试将Stackoverflow帖子限制为一个问题,但这些问题都是交织在一起的).
首先,我如何为批次切割数据?由于我有三年的时间,所以只需按顺序推进三批,每次大小一年是否合理?或者更小的批次(比如30天)以及使用滑动窗口更有意义吗?也就是说,不是36个批次,每个30天,我使用36*6批次,每个30天,每次滑动5天?或者这不是真的应该使用LSTM的方式吗?(请注意,数据中存在相当多的季节性,我需要捕捉这种长期趋势).
其次,在这里使用 return_sequences=True
是否有意义?换句话说,我保持我的Y数据是(50, 1096, 3)
这样的(据我所知),每个时间步都有一个预测,可以针对目标数据计算损失?或者我会更好return_sequences=False
,因此只有每批的最终价值用于评估损失(即如果使用年度批次,那么在2016年的产品1,我们评估2016年12月的价值(1,1,1)
).
第三,我该如何处理50种不同的产品?它们是不同的,但仍然强相关,我们已经看到其他方法(例如具有简单时间窗的MLP),当所有产品被考虑在同一模型中时,结果更好.目前摆在桌面上的一些想法是:
第四,我如何处理验证数据?通常我会随机选择一个随机选择的样本进行验证,但在这里我们需要保持时间排序.所以我想最好只是暂时搁置几个月?
第五,这是我可能最不清楚的部分 - 我如何使用实际结果来执行预测?假设我使用return_sequences=False
和训练了三年三次(每次都是11月),目标是训练模型以预测下一个值(2014年12月,2015年12月,2016年12月).如果我想在2017年使用这些结果,这实际上是如何工作的?如果我理解正确的话,我在这个例子中唯一可以做的就是为2017年1月到11月的所有数据点提供模型,它会给我回到2017年12月的预测.这是正确的吗?但是,如果我使用return_sequences=True
,然后对截至2016年12月的所有数据进行培训,那么我是否能够通过给出模型在2017年1月观察到的特征来获得2017年1月的预测?或者我需要在2017年1月之前的12个月内给它吗?那么2017年2月,我是否需要在2017年之前再提供11个月的价值?(如果听起来我很困惑,那是因为我!)
最后,根据我应该使用的结构,我如何在Keras中这样做?我现在想到的是以下几点:(虽然这只适用于一种产品,因此不能解决所有产品都在同一型号中):
Keras代码
trainX = …
Run Code Online (Sandbox Code Playgroud) lstm ×10
keras ×8
python ×3
tensorflow ×3
keras-layer ×1
pandas ×1
python-3.x ×1
pytorch ×1
rnn ×1
stateful ×1
valueerror ×1