Тренировка LSTM со многими ко многим с конечным плотным слоем и без него - PullRequest
1 голос
/ 25 сентября 2019

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

Ввод в модель представляет собой последовательность128-мерных векторов.Каждая последовательность в обучающем наборе имеет различную длину.Каждый раз модель должна выводить вектор из 3 элементов.

Я пытаюсь обучить и сравнить две модели: A) простой LSTM с 128 входами и 3 выходами;B) простой LSTM со 128 входами и 100 выходами + плотный слой с 3 выходами;

для модели A) я написал следующий код:

# Model
model = Sequential()
model.add(LSTM(3, batch_input_shape=(1, None, 128),  return_sequences=True, activation = "linear", stateful = True))`
model.compile(loss='mean_squared_error', optimizer=Adam())

# Training
for i in range(n_epoch):
    for j in np.random.permutation(n_sequences):
        X = data[j] # j-th sequences
        X = X[np.newaxis, ...] # X has size 1 x NTimes x 128

        Y = dataY[j] # Y has size NTimes x 3

        history = model.fit(X, Y, epochs=1, batch_size=1, verbose=0, shuffle=False)
        model.reset_states()

С этим кодом модель A), кажется, тренируется нормально, потому что выходная последовательность приближается к последовательности «правда-земля» на обучающем множестве.Однако мне интересно, действительно ли потери рассчитываются с учетом всех выходных векторов NTimes.

Для модели B) я не смог найти какой-либо способ получить всю выходную последовательность из-за плотного слоя.Следовательно, я написал:

# Model
model = Sequential()
model.add(LSTM(100, batch_input_shape=(1, None, 128), , stateful = True))
model.add(Dense(3,   activation="linear"))
model.compile(loss='mean_squared_error', optimizer=Adam())

# Training
for i in range(n_epoch):
    for j in np.random.permutation(n_sequences):
        X = data[j]  #j-th sequence
        X = X[np.newaxis, ...] # X has size 1 x NTimes x 128

        Y = dataY[j] # Y has size NTimes x 3

        for h in range(X.shape[1]):
            x = X[0,h,:]
            x = x[np.newaxis, np.newaxis, ...] # h-th vector in j-th sequence
            y = Y[h,:]
            y = y[np.newaxis, ...]
            loss += model.train_on_batch(x,y)
        model.reset_states() #After the end of the sequence

С этим кодом модель B) не работает нормально.Мне кажется, что обучение не сходится, и значения потерь циклически увеличиваются и уменьшаются. Я также пытался использовать в качестве Y только последний вектор, и они вызывали функцию подбора на всей последовательности обучения X, но без улучшений.

Любая идея?Спасибо!

1 Ответ

2 голосов
/ 25 сентября 2019

Если вы хотите иметь три выхода на шаг вашей последовательности, вам нужно TimeDistribute вашего плотного слоя следующим образом:

model.add(TimeDistributed(Dense(3, activation="linear")))

Это применяет плотный слой к каждому временному шагу независимо.

См. https://keras.io/layers/wrappers/#timedistributed

...