Estoy tratando de ajustar un RNN en Keras usando secuencias que tienen diferentes duraciones de tiempo. Mis datos están en una matriz Numpy con formato (sample, time, feature) = (20631, max_time, 24) donde max_time se determina en tiempo de ejecución como la cantidad de pasos de tiempo disponibles para la muestra con la mayor cantidad de marcas de tiempo. He rellenado el comienzo de cada serie temporal con 0 , a excepción de la más larga, obviamente.
Inicialmente he definido mi modelo así...
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 ajusto 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 elimino 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 enmascaramiento? ¿Me estoy perdiendo algo más?
La forma en que implementó el enmascaramiento debe ser correcta. Si tiene datos con la forma (muestras, intervalos de tiempo, características) y desea enmascarar los intervalos de tiempo que carecen de datos con una máscara cero del mismo tamaño que el argumento de las características, agregue Masking(mask_value=0., input_shape=(timesteps, features)) . Ver aquí: keras.io/layers/core/#masking
Su modelo podría ser potencialmente demasiado simple y/o su número de épocas podría ser insuficiente para que el modelo diferencie 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 varias veces (por ejemplo, 200, 400) y vea si eso mejora los resultados.
No pude validar sin datos reales, pero tuve una experiencia similar con un RNN. En mi caso, la normalización resolvió el problema. Agregue una capa de normalización a su modelo.