具有一维时间序列的Keras LSTM


10

我正在学习如何使用Keras,并使用Chollet的Python深度学习中的示例在标记数据集上取得了合理的成功。数据集是〜1000个时间序列,长度为3125,具有3个潜在类别。

我想超越基本的Dense层,该层为我提供了约70%的预测率,并且本书继续讨论LSTM和RNN层。

所有示例似乎都为每个时间序列使用了具有多个功能的数据集,因此我正在努力研究如何实现数据。

例如,如果我有1000x3125时间序列,如何将其输入到SimpleRNN或LSTM层中?我是否缺少有关这些层功能的一些基本知识?

当前代码:

import pandas as pd
import numpy as np
import os
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM, Dropout, SimpleRNN, Embedding, Reshape
from keras.utils import to_categorical
from keras import regularizers
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

def readData():
    # Get labels from the labels.txt file
    labels = pd.read_csv('labels.txt', header = None)
    labels = labels.values
    labels = labels-1
    print('One Hot Encoding Data...')
    labels = to_categorical(labels)

    data = pd.read_csv('ts.txt', header = None)

    return data, labels

print('Reading data...')
data, labels = readData()

print('Splitting Data')
data_train, data_test, labels_train, labels_test = train_test_split(data, labels)

print('Building Model...')
#Create model
model = Sequential()
## LSTM / RNN goes here ##
model.add(Dense(3, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

print('Training NN...')
history = model.fit(data_train, labels_train, epochs=1000, batch_size=50,
    validation_split=0.25,verbose=2)

results = model.evaluate(data_test, labels_test)

predictions = model.predict(data_test)

print(predictions[0].shape)
print(np.sum(predictions[0]))
print(np.argmax(predictions[0]))

print(results)

acc = history.history['acc']
val_acc = history.history['val_acc']
epochs = range(1, len(acc) + 1)

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

Answers:


10

LSTM层需要不同形状的数据。

从您的描述中,我了解到起始数据集具有3125行和1000列,其中每一行都是一个时间步。然后,目标变量应具有3125行和1列,其中每个值可以是三个可能值之一。因此,听起来您正在执行分类问题。要在代码中检查这一点,我会做:

>>> X.shape
(3125, 1000)

>>> y.shape
(1000,)

LSTM类要求每个样本都包含一个“时间块”。假设您希望有一个100个时间步的块。这意味着X[0:100]是一个输入样本,它对应于的目标变量y[100]。这意味着您的窗口大小(又称时间步长或滞后数)等于100。如上所述,您有3125个样本,所以N = 3125。不幸的是,要形成第一个块,我们必须丢弃的前100个样本y,因为我们不能从可用数据中形成整个100个块(我们最终需要之前的数据点X[0])。

考虑到所有这些,LSTM要求您交付批次的形状(N - window_size, window_size, num_features),这会转化为(3125 - 100, 100, 1000)== (3025, 100, 1000)

创建这些时间段有点麻烦,但是一次创建一个好的函数,然后保存即可:)

还有就是更多的工作要做,也许是看多在我的解释深度上面的例子在这里 ......或有一个读LSTM文件,(或者更好的是,源代码!)。

这样,最终模型就足够简单了(根据您的代码):

#Create model
model = Sequential()
model.add(LSTM(units=32, activation='relu',
               input_shape=(100, 1000))    # the batch size is neglected!
model.add(Dense(3, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam',
              metrics=['accuracy'])

查看有关Sequential模型输入形状的文档。它基本上说我们不需要指定其中的批次数input_shape。例如batch_size=50,如果您要求将其设置为固定数字,则可以完成此操作。

我知道input_shape参数不在文档中LSTM,但类本身继承自RNN,而类又继承自Layer-从而可以使用您提供的信息。

最后一个技巧:如果您计划添加多个LSTM层(“堆叠”它们),那么您将需要向除最后一个之外的 所有其他层添加一个参数LSTM,即return_sequences=True


感谢您对Dexter(!)的全面答复。关于您对批处理大小的评论,与制作自己的自定义批处理相比,在model.fit参数中指定的batch_size是一个不同的超级参数吗?我设法通过使用data = np.reshape(data,(1000,1,3125))将数据从1000x3125矩阵重塑为3D矩阵来至少运行代码。这使我可以使用input_shape(1,3125)运行LSTM,但是同样,我不确定自己在做什么。再次感谢您的答复。我将看看您提供的链接,并进一步研究您的答案。
user1147964 '18

别客气!是的,您了解了这一点,如果batch_size在定义模型时遗漏了模型,则会从中使用相同的参数model.fit()。您应该重整以获得get (3025, 100, 1000),这意味着3025批,每100(行)个时间步和1000(列)变量。np.reshape遗憾的是,使用该功能将无法正常工作(您会得到一个错误),因为事实是您将重叠数据……最终形状的数据量大于输入的数据量。3025x100x1000> 3125x1000 - np.reshape不象是因为它是不明确的。我建议简单地循环遍历数据集,即1个循环= 1个样本。
n1k31t4 '18年

我觉得我有点困惑,这可能是因为我可能不经意地已经完成了批处理过程,在这里我将使用特定的值。我以6.25 kHz的采样率对3种不同的测量值进行了大约3分钟的采样,得出3个时间序列的长度为1093750。这将生成一个3x1093750的矩阵。然后,我将每个TS分成0.5秒的增量,从而得到1050x3125的矩阵。我可以从技术上将其重组为尺寸为3x350x3125的3D矩阵。这给了我350个0.5s长的“批次”。您的重塑似乎会产生更多的价值再次感谢您的答复。对不起
user1147964

只需添加一下,阅读您发布的第一个链接就可以使我认为我正在正确地重塑事物。抱歉,如果我缺少明显的内容,但此处以TS长度5000开头,并将其转换为尺寸为[1 25 200]的3D矩阵。
user1147964 '18年

与您链接中的方法相比,我的方法将创建更多示例。这是因为我正在使用一种“滚动”窗口。看一下这幅画。他们不使用滚动窗口。将3分钟分成350x0.5s的块是可以的(也许不需要-您预测的频率是多少?),每个块应为3x3125。“我可以将其重组为尺寸为3x350x3125的3D矩阵” -听起来更好,但是在进行拆分之后,我希望可以达到350x3x3125(350个3x3125块)。这些块中的每一个都可以按照我的描述进行处理。
n1k31t4 '18年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.