使用LSTM预测2的乘积序列的下一项

我试图解决一个非常简单的问题(虽然简单,但它让我头疼)。

我的数据是这样的

   0.64900194,  2.32144675,  4.36117903,  6.8795263 ,  8.70335759,   10.52469321, 12.50494439, 14.92118469, 16.31657096, 18.69954666,   20.653336  , 22.08447934, 24.29878371, 26.01567801, 28.3626067 ,   30.75065028, 32.81166691, 34.52029737, 36.90956918, 38.55743122

上述数据序列对应的目标值为40.24253

如您所见,这是一个简单的LSTM序列预测问题,输入数据是过去20个2的乘积序列值,目标是序列中的下一个数字加上某个随机的均匀数(为了增加一些噪声)。

样本输入和目标的大小分别为:(batch_size, 20, 1) 和 (batch_size, )

这是我用于预测的代码:

def univariate_data(dataset, start_index, end_index, history_size, target_size):    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)        # Reshape data from (history_size,) to (history_size, 1)        data.append(np.reshape(dataset[indices], (history_size, 1)))        labels.append(dataset[i+target_size])    return np.array(data), np.array(labels)uni_data = np.array([(i*2)+random.random() for i in range(0,400000)])TRAIN_SPLIT = 300000uni_train_mean = uni_data[:TRAIN_SPLIT].mean()uni_train_std = uni_data[:TRAIN_SPLIT].std()uni_data = (uni_data-uni_train_mean)/uni_train_stdunivariate_past_history = 20univariate_future_target = 0x_train_uni, y_train_uni = univariate_data(uni_data, 0, TRAIN_SPLIT,                                           univariate_past_history,                                           univariate_future_target)x_val_uni, y_val_uni = univariate_data(uni_data, TRAIN_SPLIT, None,                                       univariate_past_history,                                       univariate_future_target)print ('Single window of past history')print (x_train_uni.shape)print ('\n Target temperature to predict')print (y_train_uni.shape)BATCH_SIZE = 256BUFFER_SIZE = 10000train_univariate = tf.data.Dataset.from_tensor_slices((x_train_uni, y_train_uni))train_univariate = train_univariate.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()val_univariate = tf.data.Dataset.from_tensor_slices((x_val_uni, y_val_uni))val_univariate = val_univariate.batch(BATCH_SIZE).repeat()simple_lstm_model = tf.keras.models.Sequential([    tf.keras.layers.LSTM(8, input_shape=x_train_uni.shape[-2:]),    tf.keras.layers.Dense(1)])simple_lstm_model.compile(optimizer='adam', loss='mae')for x, y in val_univariate.take(1):    print(simple_lstm_model.predict(x).shape)EVALUATION_INTERVAL = 200EPOCHS = 10simple_lstm_model.fit(train_univariate, epochs=EPOCHS,                      steps_per_epoch=EVALUATION_INTERVAL,                      validation_data=val_univariate, validation_steps=50)

对于任何给定的序列,预测值与实际值相差甚远,任何建议都会有所帮助。

之前的一些搜索建议了归一化和标准化,我都尝试过了。我还尝试了不同层的LSTM,并尝试了SimpleRNN和GRU。尝试了不同的激活函数,如’tanh’和’relu’。还尝试了使用过去的10、30和50个值,而不是过去的20个值。这些都没有帮助。我认为我犯了一个非常简单的错误,任何指导都会非常有帮助。谢谢,保重!!


回答:

所以我终于找到了解决方案。

上述方法的问题在于我的训练数据和测试数据的均值和标准差非常不同。换句话说,我用范围(0,400000)的数据训练模型,而我的测试集是范围(400000, 500000)的数据。现在,从训练数据中获得的均值和标准差与测试数据大不相同,而且在上述情况下,标准差(训练数据的)大约是173,250。任何模型在训练数据具有如此高标准差的情况下预测准确度都非常困难。

解决方案是,不要直接将数据输入模型,而是输入连续元素的差异。例如,不要输入数据p = [0, 1, 2, 3, 4, 5, 6],而是输入数据q = [2, 2, 2, 2, 2, 2, 2],其中q是通过q[i] = p[i] - p[i-1]获得的。所以现在如果我们用数据q喂养模型,模型当然会预测出2,因为模型只看到输入值为2,我们只需将这个值加到最后一个实际值上即可得出结果。

因此,模型的基本问题是训练数据的高标准差和测试中未见过的值,而解决方案是输入值的差异。

但另一个问题是,如果我们想预测2的幂,即2的指数,在这种情况下,模型可能会从类型q的数据中学习趋势,但模型仍然不会非常准确,因为在某个点上,它又会遇到具有非常高均值和标准差的值。

最后,我在某处读到LSTM并不适合从模型未接触过的嵌入空间中外推数据,有其他模型用于外推数据,但LSTM不是其中之一。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注