为Keras LSTM准备时间序列数据 - 损失极高的网络列车

时间:2017-02-21 14:57:03

标签: python numpy neural-network keras recurrent-neural-network

我遇到了准备我的数据以便在Keras的LSTM层中使用的问题。该数据是1,600,000项时间序列csv,由日期和三​​个特征组成:

Date F1 F2 F3 2016-03-01 .252 .316 .690 2016-03-02 .276 .305 .691 2016-03-03 .284 .278 .687 ...  我的目标是预测未来F1 prediction_period 时间步长的值。了解Keras的LSTM层以格式(样本,时间步长,维度)获取导入数据我编写了以下函数,将我的数据转换为此格式的3D numpy数组(以2016-03-03为例):

[[[。[284,.278,.687],[。276,.305,.691],[。252,。316,。690]],......其他样本...]

此功能通过堆叠数据副本来创建数组,每个副本都会向后移动一步。回顾是堆栈中“层”的数量,而trainpercent是列车/测试拆分:

def loaddata(path):
    df = pd.read_csv(path)
    df.drop(['Date'], axis=1, inplace=True)
    df['label'] = df.F1.shift(periods=-prediction_period)
    df.dropna(inplace=True)

    df_train, df_test = df.iloc[:int(trainpercent * len(df))], df.iloc[int(trainpercent * len(df)):]
    train_X, train_Y = df_train.drop('label', axis=1).copy(), df_train[['label']].copy()
    test_X, test_Y = df_test.drop('label', axis=1).copy(), df_test[['label']].copy()
    train_X, train_Y, test_X, test_Y = train_X.as_matrix(), train_Y.as_matrix(), test_X.as_matrix(), test_Y.as_matrix()
    train_X, train_Y, test_X, test_Y = train_X.astype('float32'), train_Y.astype('float32'), test_X.astype('float32'), test_Y.astype('float32')

    train_X, test_X = stackit(train_X), stackit(test_X)
    train_X, test_X = train_X[:, lookback:, :], test_X[:, lookback:, :]
    train_Y, test_Y = train_Y[lookback:, :], test_Y[lookback:, :]

    train_X = np.reshape(train_X, (train_X.shape[1], train_X.shape[0], train_X.shape[2]))
    test_X = np.reshape(test_X, (test_X.shape[1], test_X.shape[0], test_X.shape[2]))
    train_Y, test_Y = np.reshape(train_Y, (train_Y.shape[0])),  np.reshape(test_Y, (test_Y.shape[0]))
    return train_X, train_Y, test_X, test_Y

def stackit(thearray):
    thelist = []
    for i in range(lookback):
        thelist.append(np.roll(thearray, shift=i, axis=0))
    thelist = tuple(thelist)
    thestack = np.stack(thelist)
    return thestack

虽然网络接受了数据并进行了训练,但损失值非常高,考虑到数据具有明确的周期性趋势,这是非常令人惊讶的。为了尝试找出问题,我用这个例子中的sin-wave数据集和结构替换了我的数据集和网络结构: http://www.jakob-aungiers.com/articles/a/LSTM-Neural-Network-for-Time-Series-Prediction

即使使用sin波数据集,损失仍然高于示例函数产生的数量级。我使用一列顺序数据集逐个浏览函数,并将期望值与实际值进行比较。我没有发现任何错误。

我是否错误地为Keras的LSTM层构建输入数据?如果是这样,这样做的正确方法是什么?如果没有,你会期望在我的职能或其他方面造成这些症状(极高的损失,不会随着时间的推移而减少,即使有40多个时代)。

提前感谢您提供的任何建议!

2 个答案:

答案 0 :(得分:0)

A"高损失"是一个非常主观的事情。如果没有看到你的模型,我们无法对此进行评估。

这可能有多种原因:

  • 训练损失可能受到正规化技术的影响。例如,L2正则化的整个要点是在损失中添加模型的权重。
  • 损失由目标函数定义,因此取决于您使用的目标。
  • 您可能无法调整用于该目标函数的optmizer。一些优化者不保证损失的收敛。
  • 你的时间系列可能无法预测(但显然这不是你的情况)。
  • 您的模型可能不适合您要完成的任务。
  • 您的训练数据未正确准备(但您已经对此进行了调查)

你看到有很多可能性。高损失本身并不意味着任何事情。你可以有一个非常小的损失,只需要做到1000,并且在问题解决后你的损失会很高

答案 1 :(得分:0)

您可以采取以下措施来改善预测:

  1. 首先确保输入数据居中,即应用一些 标准化或标准化。你可以使用 来自sklearn库或工具的MinMaxScaler或StandardScaler 根据您的数据进行一些自定义缩放。

  2. 确保您的网络(LSTM / GRU / RNN)足够大以捕获 数据的复杂性。

  3. 使用Keras中的tensorboard回调来监控您的体重 矩阵和损失函数。

  4. 使用自适应优化器而不是设置自定义学习 参数。也许'亚当'或者' adagrad'

  5. 使用这些至少可以确保您的网络正在接受培训。随着时间的推移,您应该看到损失逐渐减少。在您解决了这个问题之后,您可以自由地尝试初始的超参数并实现不同的正则化技术

    祝你好运!