Adicionando recursos ao modelo de série temporal LSTM

43

estiveram lendo um pouco sobre LSTM e seu uso para séries temporais e tem sido interessante, mas difícil ao mesmo tempo. Uma coisa que tive dificuldades em entender é a abordagem para adicionar recursos adicionais ao que já é uma lista de recursos de séries temporais. Supondo que você tenha seu conjunto de dados assim:

t-3, t-2, t-1, saída

Agora, digamos que você saiba que possui um recurso que afeta a saída, mas não é necessariamente um recurso de série temporal, digamos que é o clima lá fora. Isso é algo que você pode adicionar e o LSTM poderá distinguir qual é o aspecto da série temporal e o que não é?

Rjay155
fonte
Eu gosto da sua pergunta. No entanto, você pode elaborar como esse recurso de série não temporal influencia a saída no tempo t, com base no conhecimento do assunto.
horaceT

Respostas:

39

Para RNNs (por exemplo, LSTMs e GRUs), a entrada da camada é uma lista de intervalos de tempo e cada intervalo de tempo é um tensor de recurso. Isso significa que você pode ter um tensor de entrada como este (na notação 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 ],
    ...
]

Então, absolutamente, você pode ter vários recursos a cada passo do tempo. Na minha opinião, o clima é uma característica da série temporal: onde eu moro, isso acontece em função do tempo. Portanto, seria bastante razoável codificar as informações meteorológicas como um dos seus recursos em cada timestep (com uma codificação apropriada, como nublado = 0, ensolarado = 1 etc.).

Se você possui dados que não são de séries temporais, não faz sentido transmiti-los pelo LSTM. Talvez o LSTM funcione de qualquer maneira, mas mesmo se funcionar, provavelmente terá um custo de maior perda / menor precisão por tempo de treinamento.

Como alternativa, você pode introduzir esse tipo de informação "extra" em seu modelo fora do LSTM por meio de camadas adicionais. Você pode ter um fluxo de dados como este:

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

Então, você mesclaria suas entradas auxiliares nas saídas LSTM e continuaria sua rede a partir daí. Agora seu modelo é simplesmente multi-entrada.

Por exemplo, digamos que em seu aplicativo específico, você mantenha apenas a última saída da sequência de saída LSTM. Digamos que seja um vetor de comprimento 10. Sua entrada auxiliar pode ser seu clima codificado (portanto, escalar). Sua camada de mesclagem pode simplesmente anexar as informações meteorológicas auxiliares no final do vetor de saída LSTM para produzir um único vetor de comprimento 11. Mas você não precisa manter apenas o último timestep de saída do LSTM: se o LSTM produziu 100 timesteps, cada com um vetor de 10 vetores, você ainda pode adicionar informações meteorológicas auxiliares, resultando em 100 intervalos de tempo, cada um consistindo em um vetor de 11 pontos de dados.

A documentação do Keras em sua API funcional tem uma boa visão geral disso.

Em outros casos, como aponta o @horaceT, convém condicionar o LSTM em dados não temporais. Por exemplo, preveja o tempo amanhã, com o local. Nesse caso, aqui estão três sugestões, cada uma com positivo / negativo:

  1. Faça com que o primeiro intervalo de tempo contenha seus dados de condicionamento, uma vez que "efetivamente" definirá o estado interno / oculto da sua RNN. Francamente, eu não faria isso por várias razões: seus dados de condicionamento precisam ter a mesma forma que o restante de seus recursos, dificulta a criação de RNNs com estado (em termos de ter muito cuidado em rastrear como você alimenta dados) na rede), a rede pode "esquecer" os dados de condicionamento com tempo suficiente (por exemplo, sequências longas de treinamento ou sequências longas de previsão), etc.

  2. Inclua os dados como parte dos próprios dados temporais. Portanto, cada vetor de característica em um passo específico inclui "principalmente" dados de séries temporais, mas os dados de condicionamento são anexados ao final de cada vetor de característica. A rede aprenderá a reconhecer isso? Provavelmente, mas mesmo assim, você está criando uma tarefa de aprendizado mais difícil poluindo os dados da sequência com informações não sequenciais. Então, eu também desencorajaria isso.

  3. Provavelmente, a melhor abordagem seria afetar diretamente o estado oculto da RNN no tempo zero. Essa é a abordagem adotada por Karpathy e Fei-Fei e por Vinyals et al . É assim que funciona:

    1. Para cada amostra de treinamento, leve suas variáveis ​​de condição .x
    2. Transforme / reformule suas variáveis ​​de condição com uma transformação afim para colocá-las na forma correta como o estado interno do RNN: (esses e são pesos treináveis). Você pode obtê-lo com uma camada densa em keras.v=Wx+bWb
    3. Para o primeiro timestep, adicione ao estado oculto da RNN ao calcular seu valor.v

    Essa abordagem é a mais "teoricamente" correta, uma vez que condiciona adequadamente o RNN em suas entradas não temporais, naturalmente resolve o problema de forma e também evita poluir os passos de entrada com informações adicionais não temporais. A desvantagem é que essa abordagem geralmente requer controle de arquitetura em nível de gráfico; portanto, se você estiver usando uma abstração de nível superior como Keras, será difícil implementá-la, a menos que adicione seu próprio tipo de camada.

Adam Sypniewski
fonte
11
Boa sugestão, mas e se a saída do LSTM tiver dependência estrutural de um preditor de série não temporal.
horaceT
Você poderia dar um exemplo?
Adam Sypniewski 23/02
6
OK, aqui está um exemplo muito artificial. Digamos que você esteja tentando prever o tempo no tempo t, com base nas observações dos últimos n passos. O clima depende da parte do mundo em que você está. Se é verão no hemisfério norte, é inverno no hemisfério sul. Portanto, esse fator norte / sul deve ser levado em consideração. Você pode incorporá-lo ao LSTM?
horaceT
11
Ótima pergunta! Incluí edições para resolver isso.
Adam Sypniewski
Agradece as edições e as duas referências. Bem útil.
horaceT
2

Com base em todas as boas respostas deste tópico, escrevi uma biblioteca para condicionar as entradas auxiliares. Ele abstrai toda a complexidade e foi projetado para ser o mais amigável possível:

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

Espero que ajude!

Philippe Remy
fonte
0

Há uma função no keras LSTM reset_states(states).

No entanto, o parâmetro states é a concatinação de dois estados, estado oculto he estado da célula.

States = [h, c]

seria interessante saber se você deveria inicializar hou de cacordo com as abordagens nos documentos mencionados acima.

user2614596
fonte
0

Provavelmente, essa não é a maneira mais eficiente, mas as variáveis ​​estáticas podem ser repetidas com o uso de séries temporais tf.tile().

duplo d
fonte