Прогноз модели LSTM почти постоянен.

Вопрос или проблема

Я новичок в RNN и LSTM и сейчас экспериментирую с различными настройками.

При попытке смоделировать данные временных рядов в абсолютных величинах (предсказанная цена закрытия) я столкнулся со следующими проблемами:

  1. Потеря на валидации падает, в то время как потеря на обучении растет
  2. Предсказание на тестовом наборе почти постоянно

Есть идеи, почему так происходит?

#df - это выборка с признаками и целевыми значениями (close+1)

# СОЗДАНИЕ БОЛЬШОЙ ВЫБОРКИ ДЛЯ ТЕСТИРОВАНИЯ
df_train = df[:40000]
df_val = df[40000:50000]
df_test = df[50000:]
df_train.reset_index(drop=True,inplace=True)
df_val.reset_index(drop=True,inplace=True)
df_test.reset_index(drop=True,inplace=True)

# Создание наборов x_train, x_val путем исключения целевой переменной
x_train = df_train.drop(['close+1'], axis=1)
x_val = df_val.drop(['close+1'], axis=1)

# Масштабирование обучающих данных сначала, затем применение трансформации к тестовому набору
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_val)

# Создание y_train, y_test, просто целевая переменная для регрессии
y_train = df_train['close+1']
y_test = df_val['close+1']

# Определение окна для входных данных LSTM
sliding_window = 30

# Преобразование x_train, x_test, y_train, y_test в 3D массив (образцы, временные шаги, признаки) для ввода LSTM
dataXtrain = []
for i in range(len(x_train)-sliding_window-1):
        a = x_train[i:(i+sliding_window), 0:(x_train.shape[1])]
        dataXtrain.append(a)

dataXtest = []
for i in range(len(x_test)-sliding_window-1):
        a = x_test[i:(i+sliding_window), 0:(x_test.shape[1])]
        dataXtest.append(a)

dataYtrain = []
for i in range(len(y_train)-sliding_window-1):
        dataYtrain.append(y_train[i + sliding_window])

dataYtest = []
for i in range(len(y_test)-sliding_window-1):
        dataYtest.append(y_test[i + sliding_window])


# Убедитесь, что данные делятся на целые числа при обучении
dataXtrain = np.array(dataXtrain[:39680])
dataYtrain = np.array(dataYtrain[:39680])
dataXtest = np.array(dataXtest[:9728])
dataYtest = np.array(dataYtest[:9728])

# Проверка размеров входных данных
print('Размер dataXtrain: {}'.format((dataXtrain).shape))
print('Размер dataXtest: {}'.format((dataXtest).shape))
print('Размер dataYtrain: {}'.format((dataYtrain).shape))
print('Размер dataYtest: {}'.format((dataYtest).shape))


### ФАКТИЧЕСКАЯ МОДЕЛЬ LSTM

batch_size = 256
timesteps = dataXtrain.shape[1]
features = dataXtrain.shape[2]

# Настройка модели, 4 уровня состояний LSTM
model = Sequential()
model.add(LSTM(512, return_sequences=True, stateful=True,
               batch_input_shape=(batch_size, timesteps, features)))
model.add(LSTM(256,stateful=True, return_sequences=True))
model.add(LSTM(256,stateful=True, return_sequences=True))
model.add(LSTM(128,stateful=True))
model.add(Dense(1, activation='linear'))

model.summary()

reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor="val_loss", factor=0.9, patience=5, min_lr=0.000001, verbose=1)

def coeff_determination(y_true, y_pred):
    from keras import backend as K
    SS_res =  K.sum(K.square( y_true-y_pred ))
    SS_tot = K.sum(K.square( y_true - K.mean(y_true) ) )
    return ( 1 - SS_res/(SS_tot + K.epsilon()) )

model.compile(loss="mse",
              optimizer="nadam",
              metrics=[coeff_determination,'mse','mae','mape'])

history = model.fit(dataXtrain, dataYtrain,validation_data=(dataXtest, dataYtest),
          epochs=100,batch_size=batch_size, shuffle=False, verbose=1, callbacks=[reduce_lr])

predictions = model.predict(dataXtest, batch_size=batch_size)
print(predictions)

plt.plot(history.history["loss"][5:])
plt.plot(history.history["val_loss"][5:])
plt.title("потеря модели")
plt.ylabel("потеря")
plt.xlabel("эпоха")
plt.legend(["обучение", "валидация"], loc="best")
plt.show()

plt.figure(figsize=(20,8))
plt.plot(dataYtest)
plt.plot(predictions)
plt.title("Предсказание")
plt.ylabel("Цена")
plt.xlabel("Время")
plt.legend(["Истина", "Предсказание"], loc="best")
plt.show()

Фактические значения против предсказания

вставьте описание изображения здесь

Это могут быть ряд различных причин, но когда у меня возникала эта проблема в прошлом, это обычно было связано с слишком высоким темпом обучения или оптимизатором. Я бы рекомендовал либо уменьшить начальный темп обучения, либо использовать обычный SGD. Иногда я замечал проблемы с Adam, особенно если у вас нет разогрева. Вам также стоит попробовать более общие техники поиска гиперпараметров и поэкспериментировать с такими параметрами, как размер пакета, длина прогноза и lr и т. д.

Ответ или решение

Почему предсказания модели LSTM почти постоянны?

Модели LSTM (долгосрочная память с кратковременной памятью) стали популярными для работы с временными рядами, особенно в области финансов, таких как прогнозирование цен акций. Однако, как вы отметили, ваша модель демонстрирует проблемы, включая постоянные предсказания и расхождение между обучающей и валидационной потерями. Рассмотрим возможные причины и пути их решения.

1. Уровень обучения и выбор оптимизатора

Первоначально, высокий уровень обучения может быть одной из основных причин, по которой ваша модель не обучается должным образом. Крайне важно установить уровень обучения, который позволит модели постепенно корректировать свои веса. Если уровень обучения слишком высок, сеть может делать слишком большие шаги, что приводит к пропуску оптимальной точки. Рекомендуется снизить начальный уровень обучения или попробовать использовать более стабильные оптимизаторы, такие как SGD (стохастический градиентный спуск).

2. Структура модели

Вы используете многослойную LSTM с несколькими слоями. Это увеличивает сложность модели и может привести к переобучению, особенно если количество обучающих данных ограничено. Попробуйте сократить количество слоев или уменьшить количество нейронов в каждом слое. Это может помочь модели лучше обобщать данные, избегая заучивания.

3. Обработка данных

Проблемы с почти постоянными предсказаниями также могут возникнуть из-за неправильной обработки данных. Убедитесь, что данные были правильно нормализованы и что нет утечек информации из тестового набора в обучающий. Кроме того, стоит проверить, нет ли выбросов или шумов в данных, которые могут искажать обучение.

4. Гиперпараметры

Поиск подходящих гиперпараметров (размер батча, длина предсказания и т.д.) является важным этапом. Используйте методику настройки гиперпараметров, чтобы определить, какие значения работают лучше для вашей задачи. Иногда даже небольшие изменения в размере батча или длине временного окна могут существенно повлиять на результаты.

5. Подходит ли LSTM для вашей задачи?

Также стоит отметить, что не каждая задача подходит для архитектуры LSTM. Возможно, стоит экспериментировать с другими архитектурами, например, с GRU (гейтеризированные рекуррентные блоки) или даже с CNN (сверточные нейронные сети) в сочетании с временными феноменами.

6. Визуализация результатов и анализ потерь

Разберитесь в графиках тренировочных и валидационных потерь. Если валидационная потеря снижается при одновременном увеличении обучающей потери, это может указывать на проблемы с переобучением или неправильной инициализацией весов. Один из способов борьбы с этим — использовать техники регуляризации, такие как дропаут.

Заключение

Проблема с постоянными предсказаниями в модели LSTM может быть следствием множества факторов, начиная от неправильной настройки гиперпараметров и заканчивая выбором архитектуры и алгоритма оптимизации. Рекомендуется систематически проводить эксперименты, начиная с базовых настроек и планомерно улучшая модель, базируясь на полученных результатах и анализе. Правильная диагностика и гибкость в подходах помогут вам достичь более стабильных и точных предсказаний.

Оцените материал
Добавить комментарий

Капча загружается...