利用LSTM预测2的多倍化序列中的下一个术语。

问题描述 投票:0回答:1

我正试图解决一个非常简单的问题(据说很简单,这让我做了个噩梦)。

我的数据是这样的

   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 = 300000

uni_train_mean = uni_data[:TRAIN_SPLIT].mean()
uni_train_std = uni_data[:TRAIN_SPLIT].std()


uni_data = (uni_data-uni_train_mean)/uni_train_std


univariate_past_history = 20
univariate_future_target = 0

x_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 = 256
BUFFER_SIZE = 10000

train_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 = 200
EPOCHS = 10

simple_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。他们都没有帮助。我相信我犯了非常简单的错误,任何指导将帮助很大。谢谢,并保持安全!!

python tensorflow machine-learning keras lstm
1个回答
0
投票

所以我终于想出了解决方法。

以上方法的问题是,我的训练数据和测试数据的均值和标准差很大。换句话说,我训练模型的数据范围是(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,ofc模型将预测2,因为模型只看到了输入的2,我们只需将其加到最后的实际值上就可以得到结果。

所以,模型的基本问题是训练数据和测试中未见值的标准差很高,解决的办法是反馈差值。

但另一个问题可能是我们如何做,如果我们想预测2**x的下一个元素,即2的指数,在这种情况下,模型可能会再次学习趋势,给定q类型的数据,但模型仍然不会很准确,因为在某些时候,它将再次有一个具有非常高的平均值和标准差的值。

最后,我在某个地方读到LSTM并不是用来从一个嵌入空间模型没有接触过的数据中推断数据的,有其他模型可以推断数据,但它不是LSTM。

© www.soinside.com 2019 - 2024. All rights reserved.