python - lstm keras example
Enmascaramiento de Keras para RNN con diferentes pasos de tiempo (2)
La forma en que implementó el enmascaramiento debe ser correcta. Si tiene datos con la forma (muestras, pasos de tiempo, características) y desea enmascarar los pasos de tiempo que carecen de datos con una máscara de cero del mismo tamaño que el argumento de las características, entonces agrega Masking(mask_value=0., input_shape=(timesteps, features))
. Vea aquí: keras.io/layers/core/#masking
Su modelo podría ser demasiado simple y / o su número de épocas podría ser insuficiente para que el modelo pueda diferenciar entre todas sus clases. Prueba este modelo:
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))
Si eso no funciona, intente duplicar las épocas un par de veces (por ejemplo, 200, 400) y vea si eso mejora los resultados.
Estoy tratando de encajar un RNN en Keras usando secuencias que tienen diferentes tiempos de duración. Mis datos están en una matriz de Numpy con formato (sample, time, feature) = (20631, max_time, 24)
donde el max_time
se determina en tiempo de ejecución como el número de pasos de tiempo disponibles para la muestra con la mayoría de las max_time
tiempo. He completado el comienzo de cada serie de tiempo con 0
, excepto la más larga, obviamente.
Inicialmente he definido mi modelo así que ...
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))
Para completar, aquí está el código para la función de pérdida:
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)
Y aquí está el código para la función de activación personalizada:
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)
Cuando encajo el modelo y hago algunas predicciones de prueba, cada muestra en el conjunto de prueba obtiene exactamente la misma predicción , lo que parece sospechoso.
Las cosas mejoran si quito la capa de enmascaramiento, lo que me hace pensar que hay algo mal con la capa de enmascaramiento, pero por lo que puedo decir, he seguido la documentación exactamente.
¿Hay algo mal especificado con la capa de máscara? ¿Me estoy perdiendo algo más?
No podría validar sin datos reales, pero tuve una experiencia similar con un RNN. En mi caso la normalización solucionó el problema. Agrega una capa de normalización a tu modelo.