Ответ 1
Я не мог проверить без фактических данных, но у меня был аналогичный опыт с RNN. В моем случае нормализация решила проблему. Добавьте к вашей модели слой нормализации.
Я пытаюсь установить RNN в Keras, используя последовательности, которые имеют разную длину. Мои данные находятся в массиве Numpy с форматом (sample, time, feature) = (20631, max_time, 24)
, где max_time
определяется во время выполнения как количество шагов времени, доступных для образца с наибольшим количеством штампов времени. Я добавил начало каждого временного ряда с 0
, за исключением самого длинного, очевидно.
Я изначально определил свою модель так...
model = Sequential()
model.add(Masking(mask_value=0., input_shape=(max_time, 24)))
model.add(LSTM(100, input_dim=24))
model.add(Dense(2))
model.add(Activation(activate))
model.compile(loss=weibull_loglik_discrete, optimizer=RMSprop(lr=.01))
model.fit(train_x, train_y, nb_epoch=100, batch_size=1000, verbose=2, validation_data=(test_x, test_y))
Для полноты здесь приведен код функции потерь:
def weibull_loglik_discrete(y_true, ab_pred, name=None):
y_ = y_true[:, 0]
u_ = y_true[:, 1]
a_ = ab_pred[:, 0]
b_ = ab_pred[:, 1]
hazard0 = k.pow((y_ + 1e-35) / a_, b_)
hazard1 = k.pow((y_ + 1) / a_, b_)
return -1 * k.mean(u_ * k.log(k.exp(hazard1 - hazard0) - 1.0) - hazard1)
И вот код для пользовательской функции активации:
def activate(ab):
a = k.exp(ab[:, 0])
b = k.softplus(ab[:, 1])
a = k.reshape(a, (k.shape(a)[0], 1))
b = k.reshape(b, (k.shape(b)[0], 1))
return k.concatenate((a, b), axis=1)
Когда я подхожу к модели и делаю некоторые предсказания теста, каждый образец в тестовом наборе получает точно такое же предсказание, что кажется подозрительным.
Все становится лучше, если я удаляю маскирующий слой, что заставляет меня думать, что что-то не так с слоем маскировки, но насколько я могу судить, я точно следил за документацией.
Есть ли что-то неправильное с маскирующим слоем? Я что-то пропустил?
Я не мог проверить без фактических данных, но у меня был аналогичный опыт с RNN. В моем случае нормализация решила проблему. Добавьте к вашей модели слой нормализации.
Способ маскировки должен быть правильным. Если у вас есть данные с формой (сэмплы, временные метки, функции), и вы хотите маскировать временные метки без данных с нулевой маской того же размера, что и аргумент features, добавьте Masking(mask_value=0., input_shape=(timesteps, features))
. См. Здесь: keras.io/layers/core/#masking
Ваша модель потенциально может быть слишком простой и/или ваше количество эпох может оказаться недостаточным для того, чтобы модель могла различать все ваши классы. Попробуйте эту модель:
model = Sequential()
model.add(Masking(mask_value=0., input_shape=(max_time, 24)))
model.add(LSTM(256, input_dim=24))
model.add(Dense(1024))
model.add(Dense(2))
model.add(Activation(activate))
model.compile(loss=weibull_loglik_discrete, optimizer=RMSprop(lr=.01))
model.fit(train_x, train_y, nb_epoch=100, batch_size=1000, verbose=2, validation_data=(test_x, test_y))
Если это не сработает, попробуйте удвоить эпохи несколько раз (например, 200, 400) и посмотрите, улучшит ли это результаты.