LSTM 模型的精度低于预期

LSTM model has lower than expected accuracy

您好,我正在解决一个与时间序列有关的问题。

我正在用 10000 个值绘制 y = sin (x)

然后,对于每个值 (y),我关联一个根据下一个值(0 到 1 之间)计算的索引

然后我尝试使用 tensorflow/keras 建立一个 LSTM 网络,以便根据最后 150 个值预测该指数,这对于正弦函数来说应该是微不足道的。

这是代码和解释:

  1. 我制作了一个包含 10000 个 sin(x) 值的数组
import numpy as np
import math
from matplotlib import pyplot as plt

n = 10000

array = np.array([math.sin(i*0.02) for i in range(1, n)])
fig, ax = plt.subplots()
ax.plot([(i*0.02) for i in range(1, n)], array, linewidth=0.75)
plt.show()
  1. 计算关联指数,这里SELL_INDEX
SELL_INDEX = np.zeros((len(array), 1))

for index, row in enumerate(array):
    
    if index > len(array) - 150:
        continue

    max_price = np.amax(array[index:index + 150])
    min_price = np.amin(array[index:index + 150])
    
    current_sell_index = (row - min_price) / (max_price - min_price)
    
    SELL_INDEX[index][0] = current_sell_index

data_with_sell_index = np.hstack((array.reshape(-1,1), SELL_INDEX))
data_final =  np.hstack( (data_with_sell_index,  np.arange(len(data_with_sell_index)).reshape(-1, 1)) )
fig, ax = plt.subplots()
ax.scatter(data_final[:,2], data_final[:,0] , c = data_final[:,1], s = .5)
plt.show()

这是情节 (sin(x), SELL_INDEX : 1 是黄色,0 是紫色)

  1. 下面是模型的创建
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler
from tensorflow.python.keras import models, Input, Model
from tensorflow.python.keras.layers import LSTM, Dense, Dropout
# from neural_intelligence.batches_generator import generate_smart_lstm_batch, get_smart_lstm_data

class LearningRateReducerCb(tf.keras.callbacks.Callback):

    def on_epoch_end(self, epoch, logs={}):
        old_lr = self.model.optimizer.lr.read_value()
        new_lr = old_lr * 0.99
        print("\nEpoch: {}. Reducing Learning Rate from {} to {}".format(epoch, old_lr, new_lr))
        self.model.optimizer.lr.assign(new_lr)


# Model creation

input_layer = Input(shape=(150, 1))
layer_1_lstm = LSTM(100, return_sequences=True)(input_layer)
dropout_1 = Dropout(0.0)(layer_1_lstm)
layer_2_lstm = LSTM(200, return_sequences=True)(dropout_1)
dropout_2 = Dropout(0.0)(layer_2_lstm)
layer_3_lstm = LSTM(100)(dropout_2)

output_sell_index_proba = Dense(1, activation='sigmoid')(layer_3_lstm)

model = Model(inputs=input_layer, outputs=output_sell_index_proba)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()


  1. 训练模型
def generate_batch(dataset_x, dataset_y, sequence_length):
    x_data, y_data = [], []
    for i in range(len(list(zip(dataset_x, dataset_y))) - sequence_length - 1):
        x_data.append(dataset_x[i:i + sequence_length])
        y_data.append(dataset_y[i + sequence_length])
    return np.array(x_data), np.array(y_data)

x, y = generate_batch(data_final[:,0], data_final[:,1], sequence_length=150)
x = x.reshape(x.shape[0], x.shape[1], 1)
y = y.reshape(x.shape[0], 1, 1)

print(x.shape, y.shape)

model.fit(x, y, callbacks=[LearningRateReducerCb()], epochs=2,
                   validation_split=0.1, batch_size=64, verbose=1)

这是我的问题,准确度从未超过 0.52,我不明白为什么,对我来说似乎一切正常。

对于LSTM这么强大的工具,这应该很简单,但它可以算出索引可以是什么。

如果你能以任何方式帮助我,不客气,谢谢

编辑:要绘制结果,请使用

data = np.array(data_final[:,0])
results = np.array([])
for i in range (150, 1000):
    result = model.predict(data[i - 150 : i].reshape(1, 150, 1))
    results = np.append(result, results)
        
data = data[150:1000]

fig, ax = plt.subplots()
ax.scatter([range(len(data))], data.flatten() , c = results.flatten(), s= 1)
plt.show()

它似乎有效,问题是:为什么在训练时准确率永远不会上升?

这促使我调查问题所在,而不是尝试预测

这可能过于简单,但在我看来,您只能准确预测一半的曲线。

  • 这是您的拟合图表中蓝线和黄线重叠的地方。除非您另有说明,否则将计算所有行的准确性度量。
  • 这直观地解释了为什么你的准确率是 c。 50%。您应该能够通过将数据分成这两部分并计算每个部分的准确性来确认这一点

我建议尝试一下您的特征和变换,以了解哪种类型的形状可以更准确地预测您的正弦曲线(并在线条之间提供更完整的重叠)。