使用Keras中的复发层培训多个不同长度的时间序列

时间:2018-02-14 10:57:16

标签: python machine-learning keras lstm rnn

TL; DR - 我有几千个速度曲线(汽车速度已被采样的时间序列),我不确定如何配置我的模型以便我可以执行任意预测(即在给定样本t+n的情况下预测t个样本。)

我已经阅读了很多解释(12345),了解了Keras如何在其重复层中实现有状态,以及如何在迭代之间重置/不重置等。

但是,我无法获得我想要的模型形状(我认为)。

至于现在,我只使用我的个人资料的一部分(在下面的代码中表示为路线)。

Number of training routes: 90
Number of testing routes: 10

路线的长度不同,因此,我要做的第一件事是遍历所有路线并用0填充它们,所以它们的长度都相同。 (我假设这是必需的,如果我错了请告诉我。)在填充之后,我将路由转换为更适合监督学习任务的格式,如HERE所述。在这种情况下,我选择预测当前样本的后续5个步骤。

结果是张量,如:

Shape of trainig_data: (90, 3186, 6) == (nb_routes, nb_samples/route, nb_timesteps)

分为Xy,用于培训:

Shape of X: (90, 3186, 1)
Shape of y: (90, 3186, 5)

我的目标是让模型在当时占用一个route并对其进行训练。我创建了一个这样的模型:

# Create model 
model = Sequential()

# Add recurrent layer
model.add(SimpleRNN(nb_cells, batch_input_shape=(1, X.shape[1], X.shape[2]), stateful=True))

# Add dense layer at the end to acquire correct kind of forecast
model.add(Dense(y.shape[2]))

# Compile model
model.compile(loss="mean_squared_error", optimizer="adam", metrics = ["accuracy"])

# Fit model
for _ in range(nb_epochs):
    model.fit(X, y,
              validation_split=0.1,
              epochs=1,
              batch_size=1,
              verbose=1,
              shuffle=False)
    model.reset_states()                                                                                                                                   

这意味着我有一个带nb_cells层的模型,模型的输入是(number_of_samples,number_of_timesteps),即(3186,1),模型的输出是(number_of_timesteps_lagged),即(5)

但是,运行上述内容时出现以下错误:

ValueError: Error when checking target: expected dense_1 to have 2 dimensions, but got array with shape (90, 3186, 5)

我尝试过不同的方法解决上述问题,但我没有成功。

我还尝试过构建数据和模型的其他方法。例如合并我的路线,而不是(90,3186,6)我(286740,6)。我只是为每条路线获取数据并将其放在另一条路线之后。在摆弄我的模型后,我得到了这个,我得到了一个非常好的结果,但我真的想了解 这是如何工作的 - 我认为我上面尝试的解决方案是更好的(如果我可以让它工作)。

更新

注意: 我仍在寻找反馈意见。

我已经达成了解决方案"我觉得这很有用。

我放弃了填充,而是在方法时选择一个样本。原因是我试图通过向网络提供当时的一个样本来获取允许我predict的网络。我想给网络样本t并让它预测t+1, t+2, ...,t+n,所以我的理解是我必须在一个样本上训练网络。我还假设使用:

  • stateful将允许我保持批次之间未受污染的细胞的隐藏状态(这意味着我可以确定batch sizelen(route)
  • return_sequences将允许我获取我想要的输出向量

下面给出了更改后的代码。与原始问题不同,输入数据的形状现在为(90,)(即各种长度的90条路线),但每个训练路线每个样本仍然只有一个特征,每个标签路线每个特征有五个样本(滞后)时间)。

# Create model
model = Sequential()

# Add nn_type cells
model.add(SimpleRNN(nb_cells, return_sequences=True, stateful=True, batch_input_shape=(1, 1, nb_past_obs)))

# Add dense layer at the end to acquire correct kind of forecast
model.add(Dense(nb_future_obs))

# Compile model
model.compile(loss="mean_squared_error", optimizer="adam", metrics = ["accuracy"])

# Fit model
for e in range(nb_epochs):
    for r in range(len(training_data)):
        route = training_data[r]
        for s in range(len(route)):
            X = route[s, :nb_past_obs].reshape(1, 1, nb_past_obs)
            y = route[s, nb_past_obs:].reshape(1, 1, nb_future_obs)
            model.fit(X, y,
                      epochs=1,
                      batch_size=1,
                      verbose=0,
                      shuffle=False))
    model.reset_states()

return model

0 个答案:

没有答案