Обучение автокодеру LSTM приводит к NaN / сверхвысоким потерям MSE - PullRequest
1 голос
/ 06 марта 2020

Я пытаюсь тренировать LSTM ae. Это как модель seq2seq, вы добавляете сигнал, чтобы получить восстановленную последовательность сигналов. И я использую последовательность, которая должна быть довольно простой. Функция потерь и метри c является MSE. Первые сто эпох прошли хорошо. Однако через несколько эпох я получил MSE, который очень высок, и иногда он идет в NaN. Я не знаю, что вызывает это. Можете ли вы проверить код и дать мне подсказку? Последовательность нормализуется раньше, поэтому она находится в диапазоне [0,1], как она может вызвать такую ​​высокую ошибку MSE? Это входная последовательность, которую я получаю из обучающего набора:

sequence1 = x_train[0][:128]

выглядит следующим образом:

Я получаю данные из набора данных сигнала publi c (128 * 1) Это Код: (я изменяю его из блога keras)

# lstm autoencoder recreate sequence
from numpy import array
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import RepeatVector
from keras.layers import TimeDistributed
from keras.utils import plot_model
from keras import regularizers

# define input sequence. sequence1 is only a one dimensional list
# reshape sequence1 input into [samples, timesteps, features]
n_in = len(sequence1)
sequence = sequence1.reshape((1, n_in, 1))
# define model
model = Sequential()
model.add(LSTM(1024, activation='relu', input_shape=(n_in,1)))
model.add(RepeatVector(n_in))
model.add(LSTM(1024, activation='relu', return_sequences=True))
model.add(TimeDistributed(Dense(1)))
model.compile(optimizer='adam', loss='mse')
for epo in [50,100,1000,2000]:
   model.fit(sequence, sequence, epochs=epo)

Первые несколько эпох прошли хорошо. все потери около 0,003X или около того. Затем он внезапно стал большим, до какого-то очень большого числа, - все это поднимается к NaN.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

'relu' является основным виновником - см. здесь . Возможные решения:

  1. Инициализация весов с меньшими значениями, например, keras.initializers.TruncatedNormal(mean=0.0, stddev=0.01)
  2. Вес клипа (при инициализации или через kernel_constraint, recurrent_constraint, ...)
  3. Увеличение снижения веса
  4. Использование схемы ускоренного обучения (начните с низкого уровня, постепенно увеличивайте)
  5. Используйте 'selu' активацию, которая более стабильна, похожа на ReLU и работает лучше, чем ReLU в некоторых задачах

Поскольку ваши тренировки прошли стабильно на протяжении многих эпох, 3 звучит наиболее многообещающе, так как кажется, что в конечном итоге ваша норма веса становится слишком большой и градиенты взрываются , Как правило, я рекомендую держать весовые нормы около 1 для 'relu'; Вы можете контролировать нормы l2, используя функцию ниже. Я также рекомендую См. RNN для проверки активаций и градиентов слоев.


def inspect_weights_l2(model, names='lstm', axis=-1):
    def _get_l2(w, axis=-1):
        axis = axis if axis != -1 else len(w.shape) - 1
        reduction_axes = tuple([ax for ax in range(len(w.shape)) if ax != axis])
        return np.sqrt(np.sum(np.square(w), axis=reduction_axes))

    def _print_layer_l2(layer, idx, axis=-1):
        W = layer.get_weights()
        l2_all = []
        txt = "{} "

        for w in W:
            txt += "{:.4f}, {:.4f} -- "
            l2 = _get_l2(w, axis)
            l2_all.extend([l2.max(), l2.mean()])
        txt = txt.rstrip(" -- ")

        print(txt.format(idx, *l2_all))

    names = [names] if isinstance(names, str) else names

    for idx, layer in enumerate(model.layers):
        if any([name in layer.name.lower() for name in names]):
            _print_layer_l2(layer, idx, axis=axis)
1 голос
/ 06 марта 2020

При обратном распространении может возникнуть проблема с разрывом значений градиента. Попробуйте использовать параметры clipnorm и clipvalue для управления градиентным отсечением: https://keras.io/optimizers/

В качестве альтернативы, какую скорость обучения вы используете? Я также попытался бы уменьшить скорость обучения на 10 100 000, чтобы проверить, наблюдаете ли вы такое же поведение.

...