Как использовать Transformer Networks для построения модели прогнозирования

Обучите модель прогнозирования с помощью Transformers и PyTorch

Недавно я прочитал действительно интересную статью под названием Модели глубокого преобразователя для прогнозирования временных рядов: случай распространенности гриппа. Я подумал, что было бы интересно реализовать что-то подобное с нуля, чтобы узнать больше о прогнозировании временных рядов.

Задача прогнозирования:

В прогнозировании временных рядов цель состоит в том, чтобы предсказать будущие значения временного ряда с учетом его исторических значений. Вот некоторые примеры задач прогнозирования временных рядов:

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

Модель:

Модель, которую мы будем использовать, представляет собой преобразователь кодировщика-декодера, в котором часть кодировщика принимает в качестве входных данных историю временного ряда, а часть декодера предсказывает будущие значения авторегрессивным способом.

Декодер связан с кодировщиком с помощью механизма внимания. Таким образом, декодер может научиться «обращать внимание» на наиболее полезную часть исторических значений временного ряда, прежде чем делать прогноз.

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

Подсеть кодировщика:

Подсеть декодера:

Полная модель:

Эту архитектуру можно построить с помощью PyTorch, используя следующее:

encoder_layer = nn.TransformerEncoderLayer(
    d_model=channels,
    nhead=8,
    dropout=self.dropout,
    dim_feedforward=4 * channels,
)
decoder_layer = nn.TransformerDecoderLayer(
    d_model=channels,
    nhead=8,
    dropout=self.dropout,
    dim_feedforward=4 * channels,
)

self.encoder = torch.nn.TransformerEncoder(encoder_layer, num_layers=8)
self.decoder = torch.nn.TransformerDecoder(decoder_layer, num_layers=8)

Данные:

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

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

def generate_time_series(dataframe):

    clip_val = random.uniform(0.3, 1)

    period = random.choice(periods)

    phase = random.randint(-1000, 1000)

    dataframe["views"] = dataframe.apply(
        lambda x: np.clip(
            np.cos(x["index"] * 2 * np.pi / period + phase), -clip_val, clip_val
        )
        * x["amplitude"]
        + x["offset"],
        axis=1,
    ) + np.random.normal(
        0, dataframe["amplitude"].abs().max() / 10, size=(dataframe.shape[0],)
    )

    return dataframe

Затем модель обучается на всех этих временных рядах сразу:

Полученные результаты:

Теперь мы используем модель для прогнозирования будущих значений этих временных рядов. Результаты несколько неоднозначны:

Плохо:

Добро:

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

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

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

Заключение:

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

Трансформаторы, вероятно, не должны быть вашим первым подходом при работе с временными рядами, поскольку они могут быть тяжелыми и требовательными к данным, но их приятно иметь в своем наборе инструментов машинного обучения, учитывая их универсальность и широкий спектр приложений, начиная с их первого введения. в НЛП для обработки звука, компьютерного зрения и временных рядов.

Не стесняйтесь комментировать, если у вас есть какие-либо вопросы или предложения.

Https://github.com/CVxTz/time_series_forecasting