【问题标题】:Python Keras LSTM " Error when checking input"Python Keras LSTM“检查输入时出错”
【发布时间】:2020-05-27 16:29:05
【问题描述】:

我正在尝试训练 LSTM RNN。这是我第一次尝试这个并使用 Keras。我使用指南来编写此代码。

以下是数据示例:

    lat         long        datetime                id  trip_id    mode_cat
0   39.979973   116.305745  2011-08-27 06:13:01     20  1          1
1   39.979957   116.305688  2011-08-27 06:13:02     20  1          1
2   39.979960   116.305693  2011-08-27 06:13:03     20  1          1
3   39.979970   116.305717  2011-08-27 06:13:04     20  1          1
4   39.979985   116.305732  2011-08-27 06:13:05     20  1          1

其中 lat、long、datetime、id、trip_id 是输入,mode_cat 是输出(输出为二进制)。

这是我创建和训练 RNN 的部分代码:

def evaluate_model(trainX, trainy, testX, testy):
    verbose, epochs, batch_size = 0, 15, 64
    n_timesteps, n_features, n_outputs = trainX.shape[0], trainX.shape[1], 1
    model = Sequential()
    print("adding LSTM")
    model.add(LSTM(1, input_shape=(n_timesteps,n_features), return_sequences=True))
    print("adding dropout")
    model.add(Dropout(0.5))
    print("adding dense")
    model.add(Dense(100, activation='relu'))
    print("adding dense")
    model.add(Dense(n_outputs, activation='softmax'))
    print("adding compile")
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    print(model.summary())
    # fit network
    model.fit(trainX, trainy, epochs=epochs, batch_size=batch_size, verbose=verbose)
    # evaluate model
    _, accuracy = model.evaluate(testX, testy, batch_size=batch_size, verbose=0)
    return accuracy

def run_experiment(repeats=10):
    # repeat experiment
    scores = list()
    for r in range(repeats):
        score = evaluate_model(train_x, train_y, test_x, test_y)
        score = score * 100.0
        print('>#%d: %.3f' % (r+1, score))
        scores.append(score)
    # summarize results
    summarize_results(scores)

run_experiment()

我得到以下结果:

adding LSTM
adding dropout
adding dense
adding dense
adding compile
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lstm_1 (LSTM)                (None, 455414, 1)         28        
_________________________________________________________________
dropout_1 (Dropout)          (None, 455414, 1)         0         
_________________________________________________________________
dense_1 (Dense)              (None, 455414, 100)       200       
_________________________________________________________________
dense_2 (Dense)              (None, 455414, 1)         101       
=================================================================
Total params: 329
Trainable params: 329
Non-trainable params: 0
_________________________________________________________________
None
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-5d4acc2b23d8> in <module>()
     31     summarize_results(scores)
     32 
---> 33 run_experiment()

<ipython-input-8-5d4acc2b23d8> in run_experiment(repeats)
     24     scores = list()
     25     for r in range(repeats):
---> 26         score = evaluate_model(train_x, train_y, test_x, test_y)
     27         score = score * 100.0
     28         print('>#%d: %.3f' % (r+1, score))

<ipython-input-8-5d4acc2b23d8> in evaluate_model(trainX, trainy, testX, testy)
     15     print(model.summary())
     16     # fit network
---> 17     model.fit(trainX, trainy, epochs=epochs, batch_size=batch_size, verbose=verbose)
     18     # evaluate model
     19     _, accuracy = model.evaluate(testX, testy, batch_size=batch_size, verbose=0)

~\Anaconda3\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
   1152             sample_weight=sample_weight,
   1153             class_weight=class_weight,
-> 1154             batch_size=batch_size)
   1155 
   1156         # Prepare validation data.

~\Anaconda3\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
    577             feed_input_shapes,
    578             check_batch_axis=False,  # Don't enforce the batch size.
--> 579             exception_prefix='input')
    580 
    581         if y is not None:

~\Anaconda3\lib\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
    133                         ': expected ' + names[i] + ' to have ' +
    134                         str(len(shape)) + ' dimensions, but got array '
--> 135                         'with shape ' + str(data_shape))
    136                 if not check_batch_axis:
    137                     data_shape = data_shape[1:]

ValueError: Error when checking input: expected lstm_1_input to have 3 dimensions, but got array with shape (455414, 5)

请指教!

【问题讨论】:

    标签: python tensorflow keras time-series lstm


    【解决方案1】:

    馈入 RNN 与其他网络有点不同,因为它使用序列。

    代码中的问题是数据集格式。 RNN 的输入应该是一个 3D 张量,形状为[batch, timesteps, feature]1

    由于您有时间序列数据集,因此您应该使用移动窗口方案对输入数据进行预处理

    您应该查看this tutorial 关于时间序列预测的信息,他们在其中实施了这样的窗口方案:

    def multivariate_data(dataset, target, start_index, end_index, history_size,
                          target_size, step, single_step=False):
      data = []
      labels = []
    
      start_index = start_index + history_size
      if end_index is None:
        end_index = len(dataset) - target_size
    
      for i in range(start_index, end_index):
        indices = range(i-history_size, i, step)
        data.append(dataset[indices])
    
        if single_step:
          labels.append(target[i+target_size])
        else:
          labels.append(target[i:i+target_size])
    
      return np.array(data), np.array(labels)
    
    past_history = 720
    future_target = 72
    STEP = 6
    
    x_train_single, y_train_single = multivariate_data(dataset, dataset[:, 1], 0,
                                                       TRAIN_SPLIT, past_history,
                                                       future_target, STEP,
                                                       single_step=True)
    x_val_single, y_val_single = multivariate_data(dataset, dataset[:, 1],
                                                   TRAIN_SPLIT, None, past_history,
                                                   future_target, STEP,
                                                   single_step=True)
    

    这里是移动窗口过程的示意图(取自paper

    您的问题不完全是时间序列预测,因此您应该根据您的问题调整该教程中的代码。 应该是这样的:

    def moving_window(dataset, past_history):
        data, labels = [], []
        for i in range(past_history, len(dataset)):
            indices = range(i-past_history, i)
            data.append(dataset[['lat', 'long', 'id', 'trip_id']].values[indices])
            label.append(dataset['mode_cat'][i])
        return np.array(data), np.array(labels)
    
    PAST_HISTORY = 60
    X, y = moving_window(dataset, PAST_HISTORY)
    

    PAST_HISTORY 是一个应该调整的超参数。

    希望对您有所帮助! :)

    【讨论】:

    • 首先,非常感谢您的帮助!我花了一整天的时间阅读该教程并阅读它。你定义的moving_window函数,我假设是替换文章中列出的multivariate_data函数?文章中该函数之后的所有内容都应该保持不变吗?
    • 考虑到该教程处理不同类型的时间序列预测,与您的更相似的是“预测多变量时间序列 > 单步”。因此,如果您使用moving_window 函数而不是教程中的multivariate_data 来准备数据集,您应该能够使用教程解释的相同模型。注意:当然,您还应该将数据集分成训练/验证。此外,您还应该标准化数据集。这些步骤在教程中有很好的解释。
    • 在我的情况下,我应该将日期时间和 id(用户 id)设置为索引吗?因为对于日期时间和用户 ID 的每个唯一组合,它应该有自己的纬度、经度、trip_id 行?我问是因为在教程中他们将日期时间设置为索引。
    • 不建议将 DateTime 添加为功能。当您为模型提供时间序列([batch, timesteps, feature])时,网络将随着时间的推移自行提取关系。但是,您可以使用 DateTime 创建新功能以添加到训练数据集中。例如,您可以创建一个特征来表示是否是周末,或者是星期几,或者是早上、下午、晚上等。
    猜你喜欢
    • 2019-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多