Состояние потерь и онлайн-регрессия

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

Работая с tensorflow + keras, я пытаюсь определить пользовательскую функцию потерь. Примечание: меня больше интересует значение потерь, чем фактическое значение предсказаний (это будет использоваться для обнаружения аномалий).

Моя сеть выдает прогнозы на следующие n шагов вперед.

В момент времени t я получаю входные данные, которые представляют собой текущее наблюдение (y_t), у меня есть история x временных шагов назад. Я хочу сравнить значение y_t с предсказаниями для y_t на каждом из t-1,…t-n.

Для этого я представляю себе ‘треугольный’ массив массивов длиной от 1 до n. Я добавляю предсказанные значения в конец соответствующих массивов и удаляю первое значение из каждого, чтобы получить мой тензор y_pred. Затем y_t дублируется в тензор равной длины (y_true), который будет использоваться для вычисления потерь в момент времени t (вероятно, MSE или что-то подобное).

Сложность, с которой я сталкиваюсь, заключается в том, как сохранить состояния этих массивов предсказаний между пакетами.

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

Вы можете сформулировать свою задачу как обучение с подкреплением (RL). Обучение с подкреплением (RL) — это последовательное принятие решений в условиях неопределенности.

“Значение потерь” можно рассматривать как максимизацию вознаграждений. Выход — это последовательность, которая максимизирует вознаграждение на n шагов вперед. “Треугольный массив массивов” — это история.

Обучение с подкреплением (RL) имеет возможность делать предсказания с текущим наилучшим набором параметров, часто называемым “эксплуатацией”.

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

Для решения вашей задачи с кастомной функцией потерь и онлайн-регрессией в TensorFlow и Keras, вам действительно нужно сохранить состояния массивов предсказаний между пакетами (батчами). Это можно сделать, используя Keras’ функциональность для хранения состояния в кастомных слоях или функциях потерь.

Шаги для реализации кастомной функции потерь

  1. Создание состояния: Для того чтобы сохранять предсказания, вам надо создать класс, который будет хранить состояние (например, массивы предсказаний). Используйте атрибуты для хранения состояний между вызовами функции потерь.

  2. Определите кастомную функцию потерь: Ваша функция потерь должна иметь доступ к состояниям предыдущих предсказаний и текущему наблюдению. Это можно достичь через замыкания (closures).

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

  4. Расчет потерь: При вычислении ошибки используйте Mean Squared Error (MSE) или другую метрику, сравнивая текущее наблюдение с предсказаниями из массивов.

Вот пример кода на Python с использованием TensorFlow и Keras:

import tensorflow as tf
import numpy as np

class StatefulLoss(tf.keras.losses.Loss):
    def __init__(self, n_steps):
        super(StatefulLoss, self).__init__()
        self.n_steps = n_steps
        self.predictions_history = [[] for _ in range(n_steps)]

    def update_predictions(self, predictions):
        # Обновляем историю предсказаний
        for i in range(self.n_steps):
            if len(self.predictions_history[i]) >= i + 1:
                self.predictions_history[i].pop(0)  # Удаляем самое старое предсказание
            self.predictions_history[i].append(predictions[i])

    def call(self, y_true, y_pred):
        # Сравниваем с текущим наблюдением
        y_true = tf.repeat(tf.expand_dims(y_true, axis=-1), repeats=self.n_steps, axis=-1)

        self.update_predictions(y_pred.numpy())  # Обновляем массив предсказаний
        y_pred_tensor = tf.convert_to_tensor([np.mean(arr) for arr in self.predictions_history], dtype=tf.float32)

        return tf.reduce_mean(tf.square(y_true - y_pred_tensor))

# Пример использования модели
model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(64, activation='relu', input_shape=(input_shape,)),
    tf.keras.layers.Dense(n_steps)  # Предсказание на n шагов вперед
])

loss_function = StatefulLoss(n_steps=5)  # Пример с 5 шагами
model.compile(optimizer='adam', loss=loss_function)

# Обучение модели с использованием батчей размера 1
for observation in observations:  # Ваши наблюдения
    model.train_on_batch(observation_input, observation_target)  # Предполагается, что у вас есть соответствующие входы и цели

Объяснение:

  • StatefulLoss: Этот класс реализует вашу кастомную функцию потерь с состоянием. Он сохраняет предсказания и обновляет их на каждом шаге.
  • update_predictions: Метод обновляет историю предсказаний, сохраняя последние предсказания и удаляя старые.
  • call: Этот метод реализует логику вычисления потерь. Сравнивается текущее наблюдение с предсказаниями, полученными из истории.

Заключение

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

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

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