Вопрос или проблема
Я пытаюсь обучить модель машинного обучения на данных временных рядов. Входные данные представляют собой 10 временных рядов, которые по сути являются данными с датчиков. Выходные данные – это другой набор из трех временных рядов. Я подаю на вход модели окно размером 100. Таким образом, форма входных данных становится (100, 10)
. Я хочу предсказать значения выходных временных рядов для одного временного шага. Таким образом, форма выходных данных становится (1, 3)
. (Если я создаю мини-пакеты размера, скажем, x
, то формы входных и выходных данных становятся (x, 100, 10)
и (x, 1, 3)
).
Мой подход заключается в том, чтобы сначала переобучить модель на меньшем количестве записей. Посмотреть, действительно ли модель обучается / способна переобучить данные. Затем добавить немного регуляризации (в основном, dropout) и попробовать обучить модель на полном наборе данных.
Сначала я попытался переобучить модель LSTM на небольшом наборе данных и визуализировал результат. Она справилась хорошо. Поэтому я попытался обучить ее на всем наборе данных. Результаты были умеренными, но все же возникали трудности в некоторых местах. Модель LSTM, которую я пробовал, выглядит следующим образом:
class LSTMModel(nn.Module):
def __init__(self, in_dim=10, hidden_size=1400, num_layers=1, output_size=3):
super(LSTMModelV3, self).__init__()
self.lstm_1 = nn.LSTM(in_dim, hidden_size, num_layers, batch_first=True)
self.lstm_2 = nn.LSTM(hidden_size, hidden_size, num_layers, batch_first=True)
self.lstm_3 = nn.LSTM(hidden_size, hidden_size, num_layers, batch_first=True)
self.lstm_4 = nn.LSTM(hidden_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
x, _ = self.lstm_1(x)
x, _ = self.lstm_2(x)
x, _ = self.lstm_3(x)
x, _ = self.lstm_4(x)
output = self.fc(x[:, -1, :])
return output
Я также пробовал добавить dropout, но это не привело к значительному улучшению. Поэтому я попытался обучить модель трансформера PatchTST. Сначала я попытался переобучить меньшую модель, и это удалось. На самом деле, когда я визуализировал результат, я понял, что она смогла переобучиться лучше, чем модель LSTM. Поэтому я попытался обучить ее на всем наборе данных. Но производительность была вообще не сопоставима с LSTM.
Начальная версия PatchTST, которую я попробовал, выглядит следующим образом:
config = PatchTSTConfig(
num_input_channels=10,
context_length=100,
num_targets=3,
patch_length=10,
patch_stride=5,
prediction_length=1,
num_hidden_layers=5,
num_attention_heads=3,
d_model=300,
)
model = PatchTSTForRegression(config)
С этой основной конфигурацией я попробовал разные изменения для оптимизации гиперпараметров:
- d_model = 600
- d_model = 800
- d_model = 600, num_hidden_layer = 7
- d_model = 600, patch_stride = 7
- d_model = 300, patch_stride = 7, num_hidden_layers = 8
И еще несколько комбинаций. Эти комбинации гиперпараметров подобраны так, чтобы я мог обучить модель на GPU с 24 ГБ памяти. Однако ни одна конфигурация не дала потери валидации, сопоставимой с LSTM. Вот графики LSTM и PatchTST:
Соответствующие кривые скорости обучения выглядят следующим образом:
Я использую понижение скорости обучения, если производительность не улучшается в течение 7 эпох.
Что мне здесь не хватает? Не хватает ли мне каких-нибудь инсайтов о трансформерах временных рядов?
PS1: Да, базовая скорость обучения начинается с 0.00005, затем уменьшается до 0.000005, 0.0000005, 0.00000005. Я знаю, что это очень мало. Но в начале я пробовал обучить LSTM с большей базовой скоростью, такой как 0.001, 0.005, 0.0005 и т. д., но это вообще не сработало. Всё начало работать только после старта с 0.00005. Возможно, потому что значения моих датчиков действительно очень малы.
PS2: Может показаться, что валидирующая потеря LSTM уже достигла близких к 0 значений. Но это только потому, что у меня в графике высокая потеря валидации для PatchTST. Если я уберу их и добавлю график переобученной модели LSTM, то это будет выглядеть следующим образом:
PS3: Я использую оптимизатор AdamW.
Ответ или решение
Для оптимизации гиперпараметров трансформера для временных рядов и достижения результатов лучше, чем у LSTM, важно учитывать несколько аспектов, связанных с архитектурой модели, процессом обучения и спецификой данных. Вот инструкции по настройке и подходам:
1. Архитектура модели
a. Параметры трансформера
Ваши текущие настройки конфигурации PatchTST могли не обеспечить нужной гибкости или выразительности. Попробуйте следующие настройки:
-
d_model: Увеличьте количество параметров, например до 1024 или 1280. Большие модели могут захватывать более сложные зависимости в данных.
-
num_hidden_layers: Попробуйте увеличить количество скрытых слоев до 8–10, чтобы модель могла учиться на более глубоком уровне.
-
num_attention_heads: Увеличьте количество голов внимания, чтобы модель могла более эффективно обрабатывать различные аспекты временных рядов.
-
patch_length и patch_stride: Экспериментируйте с этими параметрами, чтобы лучше резать данные на патчи, которые могут представлять разные временные контексты.
b. Использование позиционных кодов
Так как трансформеры не имеют встроенной последовательной информации, рассмотрите возможность добавления синусоидальных или обучаемых позиционных кодов, чтобы модель могла учитывать временные зависимости в ваших данных.
2. Процесс обучения
a. Разделение данных
Убедитесь, что ваши данные разделены на обучающую, валидационную и тестовую выборки. Используйте временное разделение для предотвращения утечек информации (например, делите данные на 70% обучающих, 15% валидационных и 15% тестовых).
b. Регуляризация
Помимо дропаутов, попробуйте использовать другие техники регуляризации, например, L2-регуляризацию. Также можно применить агрегационные функции (например, ensemble learning) для объединения нескольких моделей, что может помочь в улучшении общего результата.
c. Параметры обучения
Использование метода AdamW – это хороший выбор, но важно провести дополнительные эксперименты с различными значениями скорости обучения. Рассмотрите следующие подходы:
-
Пробуйте разные стратегии изменения скорости обучения. Например, используйте циклическое обучение (Cyclical Learning Rates), которые могут привести к лучшему обучению за счет адаптивного изменения скорости.
-
Проверьте и измените начальную скорость обучения для более высоких значений, например, начните с 0.001 или 0.0001, а не 0.00005, и наблюдайте за реакцией модели после предварительного обучения.
3. Визуализация и анализ
-
Визуализируйте метрики: Регулярно визуализируйте как графики потерь, так и кривые обучения. Это поможет обнаружить переобучение или недообучение. поиск точки, где ни одна из этих метрик не улучшается.
-
Анализируйте ошибки: Обратите особое внимание на ошибки модели. Используйте графики для понимания того, где модель не справляется, чтобы уточнить данные (например, удалить выбросы или улучшить разделение).
4. Использование агрегации моделей
- Рассмотрите возможность использования ансамблей моделей, где вы обучаете несколько моделей (включая LSTM и PatchTST) и комбинируете их прогнозы. Это может значительно повысить качество предсказаний.
Заключение
Тщательный выбор гиперпараметров является ключевым аспектом успеха при работе с моделями временных рядов. Настройка трансформеров в рамках вашей задачи подразумевает многократное экспериментирование с различными гиперпараметрами, а также структурой самой модели. Убедитесь, что вы проводите достаточно испытаний и анализируете результаты для достижения наилучших результатов.