Обучение LSTM с отслеживанием состояния "многие ко многим" с финальным плотным слоем и без него
Я пытаюсь обучить повторяющуюся модель в Keras, содержащую LSTM, для целей регрессии. Я хотел бы использовать модель в Интернете, и, насколько я понял, мне нужно обучить LSTM с отслеживанием состояния. Поскольку модель должна выводить последовательность значений, я надеюсь, что она вычисляет потери для каждого из ожидаемых выходных векторов. Однако я боюсь, что мой код работает не так, и я был бы признателен, если бы кто-нибудь помог мне понять, правильно ли я поступаю или есть какой-то лучший подход.
Входом в модель является последовательность 128-мерных векторов. Каждая последовательность в обучающем наборе имеет разную длину. Каждый раз модель должна выводить вектор из 3 элементов.
Я пытаюсь обучить и сравнить две модели: A) простой LSTM со 128 входами и 3 выходами; Б) простой 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 ответ
Если вы хотите, чтобы на каждом шаге вашей последовательности по-прежнему было три выхода, вам нужно TimeDistribute вашего слоя Dense следующим образом:
model.add(TimeDistributed(Dense(3, activation="linear")))
Это применяет плотный слой к каждому временному шагу независимо.