Aggiunta di funzionalità al modello LSTM di serie storiche


43

ho letto un po 'su LSTM e il loro uso per le serie storiche ed è stato interessante ma allo stesso tempo difficile. Una cosa che ho avuto difficoltà a comprendere è l'approccio all'aggiunta di funzionalità aggiuntive a quello che è già un elenco di funzionalità di serie storiche. Supponendo di avere il set di dati in questo modo:

t-3, t-2, t-1, uscita

Ora diciamo che sai che hai una funzione che influisce sull'output ma che non è necessariamente una serie storica, diciamo che è il tempo fuori. È qualcosa che puoi semplicemente aggiungere e LSTM sarà in grado di distinguere qual è l'aspetto delle serie temporali e cosa no?


Mi piace la tua domanda Tuttavia, è possibile elaborare in che modo questa caratteristica di serie non temporali influenza l'output al momento t, in base alla conoscenza dell'argomento.
horaceT

Risposte:


40

Per gli RNN (ad esempio, LSTM e GRU), l'input di layer è un elenco di timestep e ogni timestep è un tensore di funzionalità. Ciò significa che potresti avere un tensore di input come questo (in notazione Pythonic):

# 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 ],
    ...
]

Quindi assolutamente, puoi avere più funzionalità ad ogni timestep. Nella mia mente, il tempo è una caratteristica delle serie temporali: dove vivo, sembra essere una funzione del tempo. Quindi sarebbe abbastanza ragionevole codificare le informazioni meteorologiche come una delle tue caratteristiche in ogni timestep (con una codifica appropriata, come nuvoloso = 0, soleggiato = 1, ecc.).

Se disponi di dati non relativi a serie temporali, non ha davvero senso passarli attraverso LSTM. Forse l'LSTM funzionerà comunque, ma anche se lo fa, probabilmente arriverà al costo di una maggiore perdita / minore precisione per tempo di allenamento.

In alternativa, è possibile introdurre questo tipo di informazioni "extra" nel modello al di fuori di LSTM mediante livelli aggiuntivi. Potresti avere un flusso di dati come questo:

TIME_SERIES_INPUT ------> LSTM -------\
                                       *---> MERGE ---> [more processing]
AUXILIARY_INPUTS --> [do something] --/

Quindi uniresti i tuoi ingressi ausiliari nelle uscite LSTM e proseguirai la tua rete da lì. Ora il tuo modello è semplicemente multi-input.

Ad esempio, supponiamo che nella tua particolare applicazione, mantieni solo l'ultimo output della sequenza di output LSTM. Diciamo che è un vettore di lunghezza 10. L'ingresso ausiliario potrebbe essere il tuo tempo codificato (quindi uno scalare). Il livello di unione potrebbe semplicemente aggiungere le informazioni meteorologiche ausiliarie alla fine del vettore di output LSTM per produrre un singolo vettore di lunghezza 11. Ma non è necessario solo mantenere l'ultimo timestep di output LSTM: se l'LSTM ha prodotto 100 timestep, ciascuno con un vettore di 10 funzioni, è ancora possibile puntare sulle informazioni meteorologiche ausiliarie, ottenendo 100 timestep, ciascuno costituito da un vettore di 11 punti dati.

La documentazione di Keras sulla sua API funzionale ha una buona panoramica di ciò.

In altri casi, come sottolinea @horaceT, potresti voler condizionare l'LSTM su dati non temporali. Ad esempio, prevedere il tempo domani, data la posizione. In questo caso, ecco tre suggerimenti, ciascuno con aspetti positivi / negativi:

  1. Chiedi al primo timestep di contenere i tuoi dati di condizionamento, dal momento che "imposterà" effettivamente lo stato interno / nascosto del tuo RNN. Francamente, non lo farei, per una serie di motivi: i tuoi dati di condizionamento devono avere la stessa forma del resto delle tue funzionalità, rende più difficile creare RNN con stato (in termini di essere davvero attenti a tenere traccia del modo in cui alimenti i dati nella rete), la rete potrebbe "dimenticare" i dati di condizionamento con tempo sufficiente (ad es. sequenze di allenamento lunghe o sequenze di previsione lunghe), ecc.

  2. Includi i dati come parte dei dati temporali stessi. Pertanto, ogni vettore di funzione in un determinato timestep include dati "principalmente" di serie temporali, ma i dati di condizionamento vengono quindi aggiunti alla fine di ciascun vettore di funzionalità. La rete imparerà a riconoscerlo? Probabilmente, ma anche in questo caso, stai creando un'attività di apprendimento più difficile inquinando i dati della sequenza con informazioni non sequenziali. Quindi scoraggerei anche questo.

  3. Probabilmente l' approccio migliore sarebbe influenzare direttamente lo stato nascosto dell'RNN al tempo zero. Questo è l'approccio adottato da Karpathy e Fei-Fei e da Vinyals et al . È così che funziona:

    1. x
    2. v=Wx+bWb
    3. v

    Questo approccio è il più "teoricamente" corretto, poiché condiziona correttamente l'RNN sugli input non temporali, risolve naturalmente il problema di forma ed evita inoltre di inquinare i timestep degli input con informazioni aggiuntive non temporali. Il rovescio della medaglia è che questo approccio richiede spesso un controllo a livello di grafico della tua architettura, quindi se stai usando un'astrazione di livello superiore come Keras, ti sarà difficile implementare se non aggiungi il tuo tipo di livello.


1
Un buon suggerimento, ma cosa succede se l'output dell'LSTM ha una dipendenza strutturale da un predittore di serie non temporali.
OrazioT

Potresti fare un esempio?
Adam Sypniewski,

6
OK, ecco un esempio molto artificiale. Supponiamo che tu stia cercando di prevedere il tempo al momento t, basandoti su obs degli ultimi n passi temporali. Il tempo dipende dalla parte del mondo in cui ti trovi. Se è estate nell'emisfero settentrionale, è inverno nell'emisfero meridionale. Quindi questo fattore nord / sud dovrebbe essere preso in considerazione. Puoi inserirlo in LSTM?
horaceT

1
Ottima domanda! Ho incluso le modifiche per risolvere questo problema.
Adam Sypniewski,

Grazie per le modifiche e i due riferimenti. Abbastanza utile
Orazio

2

Sulla base di tutte le risposte positive di questo thread, ho scritto una libreria per condizionare gli input ausiliari. Sottrae tutta la complessità ed è stato progettato per essere il più intuitivo possibile:

https://github.com/philipperemy/cond_rnn/ (tensorflow)

Spero che sia d'aiuto!


0

C'è una funzione in keras LSTM reset_states(states).

Tuttavia, il parametro stati è la concatinazione di due stati, lo stato nascosto h e lo stato della cella.

States = [h, c]

sarebbe interessante sapere se è necessario inizializzare ho csecondo gli approcci nei documenti sopra menzionati.


0

Questo probabilmente non è il modo più efficiente, ma le variabili statiche potrebbero essere ripetute alla lunghezza della serie tf.tile().

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.