Por que propagar de volta no tempo em uma RNN?

14

Em uma rede neural recorrente, você costuma encaminhar a propagação por várias etapas de tempo, "desenrolar" a rede e depois propagá-la pela sequência de entradas.

Por que você não atualiza apenas os pesos após cada etapa individual da sequência? (o equivalente a usar um comprimento de truncamento de 1, para que não haja nada para desenrolar) Isso elimina completamente o problema de gradiente de fuga, simplifica bastante o algoritmo, provavelmente reduziria as chances de ficar preso em mínimos locais e, o mais importante, parece funcionar bem . Treinei um modelo dessa maneira para gerar texto e os resultados pareciam comparáveis ​​aos resultados dos modelos treinados pelo BPTT. Só estou confuso com isso, porque todo tutorial sobre RNNs que eu vi diz usar BPTT, quase como se fosse necessário para o aprendizado adequado, o que não é o caso.

Atualização: adicionei uma resposta

Frobot
fonte
Uma direção interessante para realizar esta pesquisa seria comparar os resultados que você obteve no seu problema com os benchmarks publicados na literatura sobre os problemas padrão da RNN. Isso daria um artigo muito legal.
Sycorax diz Restabelecer Monica
Sua "Atualização: adicionei uma resposta" substituiu a edição anterior pela descrição da sua arquitetura e uma ilustração. É de propósito?
Ameba diz Reinstate Monica
Sim, tirei-o porque realmente não parecia relevante para a pergunta real e ocupava muito espaço, mas posso adicioná-lo novamente se ajudar
Frobot
Bem, as pessoas parecem ter grandes problemas para entender sua arquitetura, então acho que quaisquer explicações adicionais são úteis. Você pode adicioná-lo à sua resposta, e não à sua pergunta, se preferir.
Ameba diz Reinstate Monica

Respostas:

4

Edit: Eu cometi um grande erro ao comparar os dois métodos e tenho que mudar minha resposta. Acontece que eu estava fazendo isso, apenas voltando a propagação na etapa atual, realmente começa a aprender mais rápido. As atualizações rápidas aprendem os padrões mais básicos muito rapidamente. Mas em um conjunto de dados maior e com mais tempo de treinamento, o BPTT de fato sai por cima. Eu estava testando uma pequena amostra por apenas algumas épocas e presumi que quem começar a ganhar a corrida será o vencedor. Mas isso me levou a uma descoberta interessante. Se você iniciar a propagação de seu treinamento de volta apenas uma única etapa, mude para BPTT e aumente lentamente a distância de propagação, obtendo uma convergência mais rápida.

Frobot
fonte
Obrigado pela sua actualização. Na fonte dessa última imagem, ele diz isso sobre a configuração de um para um : "Modo de processamento baunilha sem RNN, da entrada de tamanho fixo à saída de tamanho fixo (por exemplo, classificação de imagem)". Então é isso que estávamos dizendo. Se é como você descreveu, não tem estado e não é uma RNN. "propagação direta através de uma única entrada antes da propagação traseira" - eu chamaria isso de ANN. Mas estes não iria realizar tão bom com o texto assim que algo está acontecendo e eu não tenho idéia do que porque eu não tenho o código
ragulpr
Não li essa parte e você está correto. O modelo que estou usando é realmente o "muitos para muitos" na extrema direita. Presumi que na seção "um para um" havia realmente muitos deles todos conectados e o desenho o deixou de fora. mas essa é realmente uma das opções na extrema direita que eu não percebi (é estranho ter essa em um blog sobre RNNs, então presumi que eram todas recorrentes). Vou editar essa parte da resposta para fazer mais sentido.
Frobot 13/10
Imaginei que era esse o caso, por isso insisti em ver sua função de perda. Se é muitos para muitos a sua perda é semelhante ao e é idêntica um RNN e você está de propagação / entrando com toda a sequência, mas, em seguida, apenas truncar BPTT ou seja, você' d calculo a parte vermelha no meu post, mas não recuo mais. error=t(yt-y^t)2
Ragulpr 13/10/2016
Minha função de perda não soma ao longo do tempo. Pego uma entrada, obtenho uma saída, calculo uma perda e atualizo os pesos, depois passo para t + 1, para que não haja nada a somar. Vou acrescentar a função de perda exata para o post original
Frobot
Basta postar seu código. Não estou mais adivinhando, isso é bobagem.
Ragulpr 13/10
2

Uma RNN é uma Rede Neural Profunda (DNN), na qual cada camada pode receber novas entradas, mas tem os mesmos parâmetros. BPT é uma palavra chique para Propagação Traseira em uma rede que, por si só, é uma palavra chique para Gradient Descent.

Digamos que o RNN saídas Y t em cada passo e e r r o r t = ( y t - y t ) 2y^t

errort=(yt-y^t)2

Para aprender os pesos, precisamos de gradientes para que a função responda à pergunta "quanto uma alteração no parâmetro afeta a função de perda?" e mova os parâmetros na direção dada por:

errort=-2(yt-y^t)y^t

Ou seja, temos um DNN onde obtemos feedback sobre o quão boa é a previsão em cada camada. Como uma mudança no parâmetro alterará todas as camadas no DNN (timestep) e cada camada contribuirá para as próximas saídas, isso precisa ser levado em consideração.

Pegue uma rede simples de uma camada de neurônios e uma para ver isso de forma semi-explícita:

y^t+1=f(uma+bxt+cy^t)umay^t+1=f(uma+bxt+cy^t)cumay^tby^t+1=f(uma+bxt+cy^t)(xt+cby^t)cy^t+1=f(uma+bxt+cy^t)(y^t+ccy^t)y^t+1=f(uma+bxt+cy^t)([0 0xty^t]+cy^t)

Com a um passo de treinamento taxa de aprendizagem é então: [ ~ um ~ b ~ cδ

[uma~b~c~][umabc]+δ(yt-y^t)y^t

y^t+1y^tt

error=t(yt-y^t)2

Talvez cada passo contribua com uma direção bruta que seja suficiente em agregação? Isso poderia explicar seus resultados, mas eu estaria realmente interessado em saber mais sobre sua função de método / perda! Também estaria interessado em uma comparação com uma ANN com duas janelas com timestep.

edit4: Depois de ler os comentários, parece que sua arquitetura não é uma RNN.

ht Statefull

Seu modelo: Sem estado - estado oculto reconstruído em cada etapa apátrida edit2: adicionou mais refs aos DNNs edit3: passo fixo corrigido e algumas notações edit5: corrigiu a interpretação do seu modelo após sua resposta / esclarecimento.

ragulpr
fonte
1
Obrigado pela sua resposta. Eu acho que você pode ter entendido mal o que estou fazendo. Na propagação direta, eu apenas dou um passo, de modo que na propagação traseira também há apenas um passo. Não encaminhar a propagação por várias entradas na sequência de treinamento. Entendo o que você quer dizer com uma direção grosseira que é suficiente na agregação para permitir o aprendizado, mas verifiquei meus gradientes com gradientes calculados numericamente e eles correspondem a mais de 10 casas decimais. O suporte traseiro funciona bem. Estou usando perda de entropia cruzada.
Frobot 10/10
1
Estou trabalhando para pegar meu mesmo modelo e treiná-lo novamente com o BPTT, enquanto falamos para ter uma comparação clara. Também treinei um modelo usando esse algoritmo de "uma etapa" para prever se o preço das ações aumentará ou diminuirá no dia seguinte, o que está obtendo uma precisão decente; portanto, terei dois modelos diferentes para comparar o BPTT versus o suporte de passo único.
Frobot 10/10
Se você propagar apenas uma etapa para a frente, essa não é uma RNA de duas camadas com entrada de recurso da última etapa para a primeira camada, entrada de recurso para a etapa atual na segunda camada, mas possui os mesmos pesos / parâmetros para as duas camadas? Eu esperaria resultados similares ou melhores com uma RNA que leva entrada yy^t+1=f(xt,xt-1)
1
Estou usando uma janela deslizante de tamanho 1, mas os resultados são muito diferentes de criar uma janela deslizante de tamanho 2 ANN com entradas (xt, xt-1). Eu posso propositadamente deixá-lo se ajustar demais ao aprender um corpo enorme de texto e ele pode reproduzir o texto inteiro com 0 erros, o que requer conhecer dependências de longo prazo que seriam impossíveis se você tivesse apenas (xt, xt-1) como entrada. a única pergunta que me resta é se o uso do BPTT permitiria que as dependências se tornassem mais longas, mas honestamente não parece.
Frobot 10/10
y^t-2y^t=0 0
1

dF(g(x),h(x),m(x))dx=Fgdgdx+Fhdhdx+Fmdmdx

tHtθxtHt-1Htteuθ de tal maneira que, se o mesmo exemplo for novamente apresentado, nosso erro será reduzido.

θxtθuma(xt,θ)θHt-1θθHt-1xt-1θHt-2Ht-2θ

Matthew Hampsey
fonte
Entendo por que você volta a se propagar através do tempo em uma RNN tradicional. Eu estou tentando descobrir por que uma RNN tradicional utiliza múltiplas entradas ao mesmo tempo para o treinamento, quando se utiliza apenas um de cada vez é muito mais simples e também trabalha
Frobot
O único sentido em que você pode alimentar várias entradas de uma vez em uma RNN é alimentar vários exemplos de treinamento, como parte de um lote. O tamanho do lote é arbitrário e a convergência é garantida para qualquer tamanho, mas tamanhos maiores podem levar a estimativas de gradiente mais precisas e convergência mais rápida.
Matthew Hampsey
Não foi isso que eu quis dizer com "múltiplas entradas de uma só vez". Não falei muito bem. Eu quis dizer que você costuma encaminhar a propagação através de várias entradas na sequência de treinamento, depois propagar novamente através de todas elas e, em seguida, atualizar os pesos. Então a questão é, por que se propagam através de toda uma seqüência ao fazer apenas uma entrada de cada vez é muito mais fácil e ainda funciona
Frobot
Eu acho que alguns esclarecimentos aqui são necessários. Quando você diz "entradas", está se referindo a vários exemplos de treinamento ou está se referindo a várias etapas de tempo em um único exemplo de treinamento?
Matthew Hampsey
1
Vou postar uma resposta a esta pergunta até o final de hoje. Eu terminei de fazer uma versão BPTT, só tenho que treinar e comparar. Depois disso, se você ainda quiser ver algum código, deixe-me saber o que você quer ver e acho que ainda posso postá-lo
Frobot