RNNs: Quando aplicar BPTT e / ou atualizar pesos?

15

Estou tentando entender a aplicação de alto nível das RNNs para rotular sequências via (entre outros) o artigo de Graves, de 2005, sobre classificação de fonemas.

Para resumir o problema: Temos um grande conjunto de treinamento que consiste em arquivos de áudio (de entrada) de frases únicas e horários de início rotulados por especialistas, horários de parada e rótulos de fonemas individuais (incluindo alguns fonemas "especiais", como silêncio, de modo que cada amostra em cada arquivo de áudio seja rotulada com algum símbolo de fonema.)

O objetivo do papel é aplicar um RNN com células de memória LSTM na camada oculta a esse problema. (Ele aplica várias variantes e várias outras técnicas como comparação. No momento, só estou interessado no LSTM unidirecional, para manter as coisas simples.)

Eu acredito que entendo a arquitetura da rede: Uma camada de entrada correspondente a janelas de 10 ms dos arquivos de áudio, pré-processadas de maneira padrão para o trabalho de áudio; uma camada oculta de células LSTM e uma camada de saída com um código quente de todos os 61 símbolos de telefone possíveis.

Acredito que compreendo as equações (intrincadas, mas diretas) da passagem para frente e para trás através das unidades LSTM. Eles são apenas cálculo e a regra da cadeia.

O que eu não entendo, depois de ler este artigo e vários similares várias vezes, é quando exatamente aplicar o algoritmo de retropropagação e quando exatamente atualizar os vários pesos nos neurônios.

Existem dois métodos plausíveis:

1) Backprop frame-wise e atualização

Load a sentence.  
Divide into frames/timesteps.  
For each frame:
- Apply forward step
- Determine error function
- Apply backpropagation to this frame's error
- Update weights accordingly
At end of sentence, reset memory
load another sentence and continue.

ou,

2) Backprop sentimental e atualização:

Load a sentence.  
Divide into frames/timesteps.  
For each frame:
- Apply forward step
- Determine error function
At end of sentence:
- Apply backprop to average of sentence error function
- Update weights accordingly
- Reset memory
Load another sentence and continue.

Observe que esta é uma pergunta geral sobre o treinamento da RNN usando o artigo de Graves como um exemplo apontado (e pessoalmente relevante): Ao treinar RNNs em sequências, o backprop é aplicado a cada passo do tempo? Os pesos são ajustados a cada passo do tempo? Ou, em uma analogia frouxa ao treinamento em lote em arquiteturas estritamente feed-forward, são acumulados erros e calculados a média de uma sequência específica antes da aplicação das atualizações de backprop e peso?

Ou estou ainda mais confuso do que penso?

Novak
fonte

Respostas:

25

Suponho que estamos falando de redes neurais recorrentes (RNNs) que produzem uma saída a cada passo (se a saída estiver disponível apenas no final da sequência, faz sentido executar backprop no final). Os RNNs nessa configuração geralmente são treinados usando a retropropagação truncada ao longo do tempo (BPTT), operando sequencialmente nos 'pedaços' de uma sequência. O procedimento fica assim:

  1. Encaminhamento: avance pelas próximas etapas do tempo , calculando os estados de entrada, oculto e saída.k1 1
  2. Calcule a perda, resumida nos passos de tempo anteriores (veja abaixo).
  3. Retrocesso: calcule o gradiente da perda em todos os parâmetros, acumulando-se nas etapas de tempo anteriores (isso requer ter armazenado todas as ativações para essas etapas de tempo). Clipe gradientes para evitar o problema de gradiente explosivo (acontece raramente).k2
  4. Atualizar parâmetros (isso ocorre uma vez por bloco, não incrementalmente a cada etapa).
  5. Se estiver processando vários pedaços de uma sequência mais longa, armazene o estado oculto na última etapa do tempo (será usado para inicializar o estado oculto para o início do próximo pedaço). Se chegamos ao final da sequência, redefina o estado de memória / oculto e vá para o início da próxima sequência (ou o início da mesma sequência, se houver apenas uma).
  6. Repita da etapa 1.

A soma da perda depende de e . Por exemplo, quando , a perda é somada nos últimos passos de tempo , mas o procedimento é diferente quando (ver Williams e Peng 1990).k 2 k 1 = k 2 k 1 = k 2 k 2 > k 1k1 1k2k1 1=k2k1 1=k2k2>k1 1

O cálculo e as atualizações de gradiente são executados a cada etapas de tempo, porque é computacionalmente mais barato do que atualizar a cada etapa de tempo. Atualizar várias vezes por sequência (ou seja, definir menor que o comprimento da sequência) pode acelerar o treinamento porque as atualizações de peso são mais frequentes.k 1k1 1k1 1

A retropropagação é realizada apenas por etapas de tempo, porque é computacionalmente mais barato do que propagando de volta ao início da sequência (o que exigiria o armazenamento e o processamento repetido de todas as etapas de tempo). Os gradientes calculados dessa maneira são uma aproximação ao gradiente 'verdadeiro' calculado em todas as etapas do tempo. Mas, devido ao problema de gradiente que desaparece, os gradientes tendem a se aproximar de zero após algumas etapas de tempo; propagando além desse limite não traria nenhum benefício. Definir muito curto pode limitar a escala temporal na qual a rede pode aprender. No entanto, a memória da rede não se limita a etapas de tempo, porque as unidades ocultas podem armazenar informações além desse período (por exemplo,k 2 k 2k2k2k2)

Além das considerações computacionais, as configurações apropriadas para e dependem das estatísticas dos dados (por exemplo, a escala temporal das estruturas que são relevantes para produzir bons resultados). Eles provavelmente também dependem dos detalhes da rede. Por exemplo, existem várias arquiteturas, truques de inicialização etc. projetados para atenuar o problema do gradiente em decomposição.k 2k1 1k2

Sua opção 1 ('backprop frame-wise') corresponde à configuração como e para o número de etapas desde o início da frase até o ponto atual. A opção 2 ('backprop sábio da sentença') corresponde à configuração de e no comprimento da sentença. Ambas são abordagens válidas (com considerações computacionais / de desempenho como acima; o nº 1 seria bastante computacionalmente intensivo para seqüências mais longas). Nenhuma dessas abordagens seria chamada de 'truncada' porque a retropropagação ocorre em toda a sequência. Outras configurações de e são possíveis; Vou listar alguns exemplos abaixo. 1 k 2 k 1 k 2 k 1 k 2k1 11 1k2k1 1k2k1 1k2

Referências que descrevem o BPTT truncado (procedimento, motivação, questões práticas):

  • Sutskever (2013) . Treinamento de redes neurais recorrentes.
  • Mikolov (2012) . Modelos estatísticos de linguagem baseados em redes neurais.
    • k1 1k2
    • k1 1
    • A execução de atualizações uma vez por bloco é melhor do que incrementalmente (o que pode ser instável)
  • Williams e Peng (1990) . Um algoritmo eficiente baseado em gradiente para treinamento on-line de trajetórias de rede recorrentes.
    • Proposta original (?) Do algoritmo
    • k1 1k2hhk2k1 1
    • k1 1=1 1

Outros exemplos usando BPTT truncado:

  • (Karpathy 2015). char-rnn.
  • Graves (2014) . Gerando seqüências com redes neurais recorrentes.
    • k1 1=k2=10010,000
  • Sak et al. (2014) . Arquiteturas de redes neurais recorrentes baseadas em memória de longo prazo para reconhecimento de fala de grande vocabulário.
    • k1 1=k2=20
  • Ollivier et al. (2015) . Treinar redes recorrentes online sem retroceder.
    • k1 1=k2=15
  • Hochreiter e Schmidhuber (1997) . Memória de curto prazo.
    • Eles descrevem um procedimento modificado para LSTMs
user20160
fonte
Esta é uma resposta excelente e eu gostaria de ter a posição neste fórum para conceder uma recompensa substancial a ela. Especialmente úteis são as discussões concretas de k1 vs k2 para contextualizar meus dois casos em relação a usos mais gerais e exemplos numéricos dos mesmos.
Novak