Потери становятся NaN через короткое время для классификации временных рядов.

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

Вот мой модельный код для бинарной классификации временного ряда:

def make_model(feature_columns):
  feature_layer = tf.keras.layers.DenseFeatures(feature_columns)
  feature_layer_outputs = feature_layer(feature_layer_inputs)
  feature_layer_outputs = tf.expand_dims(feature_layer_outputs, 1)

  conv = keras.layers.Conv1D(filters=64, kernel_size=3, padding="same",kernel_regularizer=keras.regularizers.l1_l2(l1=0.01, l2=0.01))(feature_layer_outputs)
  conv = keras.layers.BatchNormalization()(conv)
  conv = keras.layers.ReLU()(conv)

  conv = keras.layers.Conv1D(filters=64, kernel_size=3, padding="same",kernel_regularizer=keras.regularizers.l1_l2(l1=0.01, l2=0.01))(conv)
  conv = keras.layers.BatchNormalization()(conv)
  conv = keras.layers.ReLU()(conv)

  conv = keras.layers.Conv1D(filters=64, kernel_size=3, padding="same",kernel_regularizer=keras.regularizers.l1_l2(l1=0.01, l2=0.01))(conv)
  conv = keras.layers.BatchNormalization()(conv)
  conv = keras.layers.ReLU()(conv)
  conv = keras.layers.Dropout(0.25)(conv)

  gap = keras.layers.GlobalAveragePooling1D()(conv)

  output_layer = keras.layers.Dense(1, activation="Softmax")(gap)

  return keras.models.Model(inputs=[v for v in feature_layer_inputs.values()], outputs=output_layer)`

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

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, RobustScaler,MinMaxScaler
dataframe = df
ct = ColumnTransformer([
        ('numeric', RobustScaler(), numerical_features[1:])
    ], remainder="passthrough")

dataframe = ct.fit_transform(dataframe)

numerical_features[0] — это моя метка. Я также попробовал добавить keras.regularizers.l1_l2 для решения проблемы с NaN в потерях и добавить дропаут после каждого слоя ReLU (сейчас он только на последнем). Я также пробовал использовать разные функции потерь, такие как MSE и бинарная кросс-энтропия, также я пытался использовать сигмоиду/softmax в выходном слое. В данный момент я практически в полном замешательстве и у меня такое ощущение, что я пропускаю что-то довольно основное. Есть ли у кого-нибудь идеи?

На моем опыте самой распространенной причиной NaN в потерях является ситуация, когда в контрольной выборке 0 экземпляров. Возможно, у вас есть какое-то вычисление, основанное, например, на усреднении потерь по нескольким временным меткам, но одна из временных меток имеет 0 экземпляров, что вызывает каскад значений NaN.

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

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

Наиболее распространенная причина появления NaN (Not a Number) в функции потерь заключается в перерасходе памяти, неправильном нормировании данных или ошибках в самой архитектуре нейронной сети. Рассмотрим основные аспекты этой проблемы, основываясь на вашем коде для бинарной классификации временных рядов.

1. Нормализация данных

Вы упомянули использование RobustScaler, что является хорошим шагом, поскольку он менее чувствителен к выбросам по сравнению с StandardScaler. Однако стоит удостовериться, что нормализация применена ко всему набору данных (как к обучающему, так и к валидационному набору). Любая ошибка в нормализации может привести к NaN в расчетах потерь.

Также имейте в виду, что NaN могут произойти из-за деления на ноль или неправильно обработанных значений (например, бесконечностей) в данных. Перед обучением модели полезно выполнить проверку данных на наличие таких значений.

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

Ваш код создает модель с несколькими сверточными слоями. Давайте рассмотрим несколько моментов:

  • Активация выхода: Ваша выходная слой определен с активацией Softmax, но для бинарной классификации корректнее использовать sigmoid. Использование Softmax приводит к ошибочному распределению вероятностей для задач, где нужно просто выставить порог (обычно 0.5).

    Корректировка:

    output_layer = keras.layers.Dense(1, activation="sigmoid")(gap)
  • Функция потерь: Если вы используете sigmoid, вам следует применять binary_crossentropy. Если вы используете softmax, то целесообразно использовать categorical_crossentropy, но это менее распространенный подход при бинарной классификации.

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

3. Проверка на пустые батчи

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

4. Отладка

Предлагаю следующие шаги для отладки:

  • Вставьте печать промежуточных значений, таких как выходные данные после каждого слоя, чтобы увидеть, где могут возникнуть NaN.
  • Проверьте данные на наличие NaN и бесконечностей после обработки и перед подачей в модель.
  • Попробуйте уменьшить размер модели (например, количество фильтров или слоев) и проверьте, есть ли изменения в потере.
  • Экспериментируйте с гиперпараметрами, постепенно меняя их, чтобы увидеть влияние на более стабильное обучение.

Общая практика, как и структурирование подхода к задаче, являются важными для успешного решения проблемы. ينبغي عليك أن تدرس جميع الجوانب للتحقق من أن كل شيء يعمل بشكل صحيح وخالي من الأخطاء. Проведение тщательной проверки данных и настройки модели, безусловно, поможет вам справиться с проблемой NaN в функциях потерь.

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

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