Потеря NaN при тренировке регрессионной сети

У меня есть матрица данных в «однократной кодировке» (все единицы и нули) с 260 000 строк и 35 столбцов. Я использую Keras для обучения простой нейронной сети для прогнозирования непрерывной переменной. Код для создания сети следующий:

model = Sequential() model.add(Dense(1024, input_shape=(n_train,))) model.add(Activation('relu')) model.add(Dropout(0.1)) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dropout(0.1)) model.add(Dense(256)) model.add(Activation('relu')) model.add(Dropout(0.1)) model.add(Dense(1)) sgd = SGD(lr=0.01, nesterov=True); #rms = RMSprop() #model.compile(loss='categorical_crossentropy', optimizer=rms, metrics=['accuracy']) model.compile(loss='mean_absolute_error', optimizer=sgd) model.fit(X_train, Y_train, batch_size=32, nb_epoch=3, verbose=1, validation_data=(X_test,Y_test), callbacks=[EarlyStopping(monitor='val_loss', patience=4)] ) 

Тем не менее, во время тренировочного процесса я вижу снижение потерь красиво, но в середине второй эпохи он идет на nan:

 Train on 260000 samples, validate on 64905 samples Epoch 1/3 260000/260000 [==============================] - 254s - loss: 16.2775 - val_loss: 13.4925 Epoch 2/3 88448/260000 [=========>....................] - ETA: 161s - loss: nan 

Я попытался использовать RMSProp вместо SGD , я попробовал tanh вместо relu , я пробовал с и без отсева, все безрезультатно. Я пробовал с меньшей моделью, т. Е. С одним скрытым слоем, и с той же проблемой (она становится нано в другой точке). Однако он работает с меньшими возможностями, т. Е. Если имеется только 5 столбцов и дает неплохие прогнозы. Кажется, что есть что-то переполнение, но я не могу себе представить, почему – потеря не является неоправданно большой.

Python версии 2.7.11, работающий на Linux-машине, только CPU. Я тестировал его с последней версией Theano, и я также получаю Nans, поэтому я попытался перейти к Theano 0.8.2 и иметь такую ​​же проблему. С последней версией Keras такая же проблема, а также с версией 0.3.2.

3 Solutions collect form web for “Потеря NaN при тренировке регрессионной сети”

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

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

Вот некоторые вещи, которые вы могли бы попробовать:

  1. Нормализуйте свои выходы с помощью нормализации квантиля или z . Чтобы быть строгим, вычислите это преобразование на данных обучения, а не на весь набор данных. Например, при нормализации квантилей, если пример находится в 60-м процентиле обучающего набора, он получает значение 0,6. (Вы также можете сдвинуть нормированные значения квантиля на 0,5, чтобы 0-й процентиль составлял -0,5, а 100-й процентиль – +0,5).

  2. Добавьте регуляризацию, либо путем увеличения скорости отсева, либо добавления штрафов L1 и L2 к весам. Регуляция L1 аналогична выбору функции, и, поскольку вы сказали, что уменьшение числа функций до 5 дает хорошую производительность, L1 также может быть.

  3. Если они по-прежнему не помогают, уменьшите размер вашей сети. Это не всегда лучшая идея, так как это может нанести вред производительности, но в вашем случае у вас есть большое количество нейронов первого уровня (1024) по сравнению с функциями ввода (35), поэтому это может помочь.

  4. Увеличьте размер партии от 32 до 128. 128 является довольно стандартным и потенциально может повысить стабильность оптимизации.

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

В Keras вы можете использовать clipnorm=1 (см. https://keras.io/optimizers/ ), чтобы просто clipnorm=1 все градиенты с нормой выше 1.

Раньше я столкнулся с такой же проблемой. Я ищу и нахожу этот вопрос и ответы. Все эти уловки, упомянутые выше, важны для обучения глубокой нейронной сети. Я попробовал их всех, но все равно получил НАН.

Я также здесь задаю этот вопрос. https://github.com/fchollet/keras/issues/2134 . Я процитировал резюме автора следующим образом: «Я хотел указать на это, чтобы он архивировался для других, которые могут столкнуться с этой проблемой в будущем. Я бегала в свою функцию потерь, внезапно возвращав нано, после того, как она дошла до учебного процесса. Я проверил relus, оптимизатор, функцию потерь, мой отсева в соответствии с relus, размер моей сети и форму сети. Я все еще получал убытки, которые в конечном итоге превратились в нан, и я очень разочаровался.

Затем меня осенило. У меня может быть плохой ввод. Оказывается, одно из изображений, которые я передавал своему CNN (и делаю среднюю нормализацию), было всего лишь 0. Я не проверял этот случай, когда я вычитал среднее значение и нормировался на отклонение std, и, таким образом, я закончил с образцовой матрицей, которая была не чем иным, как наном. Как только я исправил свою функцию нормализации, моя сеть теперь отлично тренируется ».

Я согласен с приведенной выше точкой зрения: вход чувствителен к вашей сети. В моем случае я использую значение логарифма оценки плотности как входной. Абсолютное значение может быть очень большим, что может привести к NaN после нескольких шагов градиентов. Я считаю, что проверка ввода необходима. Во-первых, вы должны убедиться, что вход не включает -inf или inf , или некоторые чрезвычайно большие числа в абсолютном значении.

  • Как заставить Theano распараллелить операцию на GPU (тестовый пример: numpy.bincount)
  • Использование глубокого обучения для прогнозирования подпоследовательности из последовательности
  • Значение переменной Anano, вызывающее ошибку в функции anano
  • Почему я не могу оценить измененную тензорную переменную в анано?
  • Как использовать предварительно обработанное слово2vec в anano
  • logistic_sgd, где его найти?
  • Как реализовать взвешенную двоичную кросс-энтропию на анано?
  • Точность Keras не изменяется
  • Как обрабатывать форму ввода и вывода для keras LSTM
  • Ошибка импорта Keras Nadam
  • Keras: "RuntimeError: не удалось импортировать pydot." После установки graphviz и pydot
  • Python - лучший язык программирования в мире.