Керас - Нан в сводной гистограмме LSTM

Я написал модель LSTM с использованием Keras и предварительной активации LeakyReLU:

    # ADAM Optimizer with learning rate decay
    opt = optimizers.Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0001)

    # build the model
    model = Sequential()

    num_features = data.shape[2]
    num_samples = data.shape[1]

    model.add(
        LSTM(16, batch_input_shape=(None, num_samples, num_features), return_sequences=True, activation='linear'))
    model.add(LeakyReLU(alpha=.001))
    model.add(Dropout(0.1))
    model.add(LSTM(8, return_sequences=True, activation='linear'))
    model.add(Dropout(0.1))
    model.add(LeakyReLU(alpha=.001))
    model.add(Flatten())
    model.add(Dense(1, activation='sigmoid'))

    model.compile(loss='binary_crossentropy', optimizer=opt,
                  metrics=['accuracy', keras_metrics.precision(), keras_metrics.recall(), f1])

Мои данные представляют собой сбалансированный двоичный набор с метками. то есть: 50% помечены 1 50% помечены 0. Я использовал activation='linear' для слоев LSTM, предшествующих активации LeakyReLU, аналогично этот пример, который я нашел на GitHub.

Модель выдает Nan in summary histogram ошибку в этой конфигурации. Изменение активаций LSTM на activation='sigmoid' работает хорошо, но кажется неправильным.

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

Любая помощь / объяснение будет оценено.

Обновление: я вижу, что убыток в первую эпоху составляет нан.

260/260 [==============================] - 6s 23ms/step - 
loss: nan - acc: 0.5000 - precision: 0.5217 - recall: 0.6512 - f1: nan - val_loss: nan - val_acc: 0.0000e+00 - val_precision: -2147483648.0000 - val_recall: -49941480.1860 - val_f1: nan

Обновление 2. Я обновил TensorFlow и Keras до версий 1.12.0 и 2.2.4. Эффекта не было.

Я также попытался добавить потерю к первому слою LSTM, как это было предложено @Oluwafemi Sule, это похоже на шаг в правильном направлении, теперь потеря не равна nan в первую эпоху, однако я все еще получаю ту же ошибку ... вероятно, из-за других значений nan, таких как val_loss / val_f1.

[==============================] - 7s 26ms/step - 
loss: 1.9099 - acc: 0.5077 - precision: 0.5235 - recall: 0.6544 - f1: 0.5817 - val_loss: nan - val_acc: 0.5172 - val_precision: 35.0000 - val_recall: 0.9722 - val_f1: nan

Обновление 3. Я попытался скомпилировать сеть только с метрикой точности, но безуспешно:

Epoch 1/300
260/260 [==============================] - 8s 29ms/step - loss: nan - acc: 0.5538 - val_loss: nan - val_acc: 0.0000e+00

person Shlomi Schwartz    schedule 31.10.2018    source источник
comment
Однажды у меня была аналогичная проблема, но моя возникла из-за значений Nan в наборе данных   -  person kerastf    schedule 31.10.2018
comment
Я не совсем уверен, взрываются ли ваши градиенты, потому что одного LeakyRelu недостаточно, чтобы заставить его сходиться. Но обычно есть опция, называемая clipnorm или clipvalue, которую вы можете передать со всеми оптимизаторами. Это помогает обрезать градиенты и обычно используется для поиска путей выхода из локальных минимумов. Вы можете попробовать это здесь и посмотреть, имеет ли это значение? Источник   -  person kvish    schedule 01.11.2018
comment
Какую версию Keras и TensorFlow вы используете?   -  person today    schedule 05.11.2018
comment
керас 2.2.2, тс 1.5.0   -  person Shlomi Schwartz    schedule 05.11.2018
comment
@ShlomiSchwartz Вы пробовали обновить TensorFlow и Keras и посмотреть, сохраняется ли проблема? Если это так, попробуйте использовать оптимизатор Adam с параметром по умолчанию и просто измените скорость обучения. Попробуйте использовать 1e-3, 1e-4 или 1e-5 в качестве скорости обучения. Кроме того, вы пробовали clipnorm для обрезки градиентов. Кроме того, используйте @user_name в начале вашего комментария, когда вы отвечаете конкретному пользователю, иначе этот пользователь не будет уведомлен о вашем комментарии (я не был уведомлен о вашем предыдущем комментарии, я просто случайно проверил этот вопрос и видел, что вы ответили).   -  person today    schedule 05.11.2018
comment
@today спасибо Я попробую, я не пробовал clipnorm, потому что не уверен, как именно, не могли бы вы добавить ответ с примером кода?   -  person Shlomi Schwartz    schedule 05.11.2018
comment
@ShlomiSchwartz Просто передайте оптимизатору аргумент clipnorm=1.0, например Adam(..., clipnorm=1.0).   -  person today    schedule 05.11.2018
comment
@today clipnorm=1.0 не решил мою проблему при использовании activation='linear' Я все еще получаю Nan in summary histogram ошибку (все те же версии TF и ​​Keras)   -  person Shlomi Schwartz    schedule 05.11.2018
comment
Что произойдет, если вы увеличите аргумент альфа (скажем, до 0,3) от LeakyReLUs?   -  person rvinas    schedule 05.11.2018
comment
@rvinas к сожалению не помогает   -  person Shlomi Schwartz    schedule 05.11.2018
comment
Если проблема вызвана -Inf из выходных данных слоев LSTM, изменение LeakyReLU на обычные слои ReLU может исправить это. Я бы также проверил обучающий набор на значения Nan.   -  person Mete Han Kahraman    schedule 06.11.2018
comment
@ShlomiSchwartz Не могли бы вы попробовать собрать и обучить сеть без этих дополнительных показателей? Используйте только accuracy и посмотрите, по-прежнему ли вы получаете эту ошибку.   -  person today    schedule 07.11.2018
comment
@today, пожалуйста, посмотрите мои правки   -  person Shlomi Schwartz    schedule 07.11.2018
comment
Привет, @ShlomiSchwartz, можешь проверить, как инициализируются веса, и попробовать распечатать их по мере вычисления потерь? Теоретически LSTM или любой вид рекурсивной сети подвержены NaN из-за большого количества рекурсивных умножений и плохой инициализации весов. Таким образом, тот факт, что искаженный набор данных может быть причиной NaN, маловероятен по сравнению с рекурсивной природой LSTM.   -  person najeeb khan    schedule 19.09.2019


Ответы (1)


Этот ответ начинается с предложения ввести небольшое значение при вычислении потерь.

keras.layers.LSTM как и все слои, которые являются прямыми или косвенными подклассами _ 2_ имеет add_loss метод, который можно использовать для установки начального значения убытка.

Я предлагаю сделать это для слоя LSTM и посмотреть, повлияет ли это на ваши результаты.

lstm_layer = LSTM(8, return_sequences=True, activation='linear')
lstm_layer.add_loss(1.0)

model.add(lstm_layer)
person Oluwafemi Sule    schedule 06.11.2018
comment
спасибо за Ваш ответ. Это похоже на шаг в правильном направлении, теперь, в первую эпоху, я вижу 260/260 [==============================] - 7s 26ms/step - loss: 1.9099 - acc: 0.5077 - precision: 0.5235 - recall: 0.6544 - f1: 0.5817 - val_loss: nan - val_acc: 0.5172 - val_precision: 35.0000 - val_recall: 0.9722 - val_f1: nan Таким образом, потери больше не являются nan, однако я все еще получаю ту же ошибку ... возможно, из-за других значений nan, таких как val_loss / val_f1? - person Shlomi Schwartz; 07.11.2018