Para los RNN (p. Ej., LSTM y GRU), la entrada de capa es una lista de pasos de tiempo, y cada paso de tiempo es un tensor de características. Eso significa que podría tener un tensor de entrada como este (en notación pitónica):
# Input tensor to RNN
[
# Timestep 1
[ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
# Timestep 2
[ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
# Timestep 3
[ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
...
]
Absolutamente, puede tener múltiples funciones en cada paso de tiempo. En mi opinión, el clima es una característica de la serie temporal: donde vivo, resulta ser una función del tiempo. Por lo tanto, sería bastante razonable codificar la información meteorológica como una de sus características en cada paso de tiempo (con una codificación adecuada, como nublado = 0, soleado = 1, etc.).
Sin embargo, si tiene datos que no son series de tiempo, entonces no tiene sentido pasarlos a través del LSTM. Tal vez el LSTM funcionará de todos modos, pero incluso si lo hace, probablemente tendrá el costo de una mayor pérdida / menor precisión por tiempo de entrenamiento.
Alternativamente, puede introducir este tipo de información "extra" en su modelo fuera del LSTM por medio de capas adicionales. Es posible que tenga un flujo de datos como este:
TIME_SERIES_INPUT ------> LSTM -------\
*---> MERGE ---> [more processing]
AUXILIARY_INPUTS --> [do something] --/
Por lo tanto, fusionaría sus entradas auxiliares en las salidas LSTM y continuaría su red desde allí. Ahora su modelo es simplemente de entrada múltiple.
Por ejemplo, supongamos que en su aplicación particular, solo mantiene la última salida de la secuencia de salida LSTM. Digamos que es un vector de longitud 10. Su entrada auxiliar podría ser su clima codificado (por lo tanto, un escalar). Su capa de combinación podría simplemente agregar la información meteorológica auxiliar al final del vector de salida LSTM para producir un solo vector de longitud 11. Pero no necesita simplemente mantener el último paso de tiempo de salida de LSTM: si el LSTM emitió 100 pasos de tiempo, cada uno con un vector de 10 características, aún podría agregar su información meteorológica auxiliar, lo que da como resultado 100 pasos de tiempo, cada uno de los cuales consta de un vector de 11 puntos de datos.
La documentación de Keras sobre su API funcional tiene una buena descripción de esto.
En otros casos, como señala @horaceT, es posible que desee condicionar el LSTM en datos no temporales. Por ejemplo, pronostique el clima mañana, dada la ubicación. En este caso, aquí hay tres sugerencias, cada una con positivos / negativos:
Haga que el primer paso contenga sus datos de acondicionamiento, ya que efectivamente "establecerá" el estado interno / oculto de su RNN. Francamente, no haría esto, por varias razones: sus datos de acondicionamiento deben tener la misma forma que el resto de sus características, lo que dificulta la creación de RNN con estado (en términos de tener mucho cuidado de rastrear cómo alimenta los datos en la red), la red puede "olvidar" los datos de acondicionamiento con suficiente tiempo (p. ej., largas secuencias de entrenamiento o largas secuencias de predicción), etc.
Incluya los datos como parte de los datos temporales en sí. Por lo tanto, cada vector de características en un paso de tiempo particular incluye "en su mayoría" datos de series de tiempo, pero luego se adjuntan los datos de acondicionamiento al final de cada vector de características. ¿Aprenderá la red a reconocer esto? Probablemente, pero aun así, está creando una tarea de aprendizaje más difícil al contaminar los datos de secuencia con información no secuencial. Así que también desalentaría esto.
Probablemente el mejor enfoque sería afectar directamente el estado oculto del RNN en el tiempo cero. Este es el enfoque adoptado por Karpathy y Fei-Fei y por Vinyals et al . Así es como funciona:
- X⃗
- v⃗ = W x⃗ + b⃗ Wsi⃗
- v⃗
Este enfoque es el más "teóricamente correcto", ya que condiciona adecuadamente el RNN en sus entradas no temporales, resuelve naturalmente el problema de la forma y también evita contaminar los pasos de las entradas con información adicional no temporal. La desventaja es que este enfoque a menudo requiere un control de nivel de gráfico de su arquitectura, por lo que si está utilizando una abstracción de nivel superior como Keras, le resultará difícil de implementar a menos que agregue su propio tipo de capa.