Recentemente, aprendi como uma rede neural de baunilha funcionaria, com determinado número de entradas, nós ocultos e o mesmo número de saídas que as entradas.
Estive observando várias postagens agora relacionadas à rede neural recorrente e entendo o conceito por trás dela, mas não entendo certas partes da lógica por trás da RNN.
Aqui estão quatro perguntas principais que tenho:
- Como a retropropagação funciona em redes neurais recorrentes?
- Os pesos que levam da entrada para os nós ocultos são os mesmos para todas as outras etapas? E os pesos dos nós ocultos às saídas?
- Como os vieses funcionam exatamente em uma rede neural recorrente?
- Por que a função tanh é normalmente usada em vez da função sigmóide como função de ativação?
Sei que algumas dessas perguntas são muito básicas, mas acho que o básico é exatamente o que eu preciso agora.
Até links para vídeos ou postagens relacionados serão extremamente úteis, assim como as palavras-chave do Google que mostram os resultados certos. Essas quatro perguntas estão me impedindo de entender os códigos de exemplo de Python, então eu realmente preciso de ajuda.
fonte
Respostas:
Essa questão atinge algumas qualidades muito importantes de RNNs e DNNs em geral. Responderei a cada uma das suas sub-perguntas, embora não na mesma ordem (tentarei destacar onde faço)
Compartilhamento de parâmetros
Primeiro, a qualidade mais importante das RNNs é chamada de compartilhamento de parâmetros . Dados sequenciais são normalmente inseridos em camadas separadas. Para uma entrada de comprimento 20, uma rede RNN teria 20 camadas. Os mesmos parâmetros internos são usados para cada camada, portanto, todas as 20 camadas usam os mesmos pesosW e preconceito b . Compare isso com um perceptron de múltiplas camadas que teria 20 pesos e desvios separados.
O compartilhamento de parâmetros tem vários benefícios:
Arquitetura de rede
Você pergunta sobre ativações tanh e sigmóide. Para responder a isso, precisamos falar sobre arquiteturas RNN específicas. O RNN simples discutido acima tem uma única ativação. RNNs simples tendem a criar o problema de gradientes de fuga (ou explosão!) Devido à aplicação repetida dos mesmos pesos e função de ativação.
Blocos RNN bloqueados (como GRUs e LSTMs) usam mecanismos de bloqueio para passar ativações para dentro e fora da memória e combinar estados de memória com entrada para gerar a saída de cada bloco. Por esse motivo, os portões podem impedir que o gradiente se propague para trás. Sigmoid é uma função de ativação comum para portões, porque esmaga as ativações para (0,1) --- 0 para completamente a ativação e 1 permite que ela passe. Qualquer função de ativação decente com um perfil de compressão semelhante funciona, no entanto. Curiosamente, sigmoide duro é bastante comum nos dias de hoje.
Além dos portões, os blocos RNN fechados têm um estado interno para o qual a ativação varia bastante. Como o gating limita o gradiente backprop, temos muita flexibilidade nessa ativação. Não precisa ser esmagado, por exemplo, e é aqui que as ativações retificadoras (relu, elu, islu, etc.) são frequentemente vistas. Tanh também é uma escolha perfeitamente sensata.
Com relação a vieses e pesos, cada ativação em uma célula RNN geralmente tem seu próprio peso e viés. Portanto, uma GRU possui 3 ativações (ocultas, atualizadas e redefinidas) e cada uma possui seu próprio peso e tendência. No entanto, lembre-se de que, como RNN, cada um deles é reutilizado para cada passo de tempo.
Retrocesso
Isso cobre a passagem direta muito bem, mas você também faz uma pergunta importante sobre como o erro se propaga para trás. Existem dois métodos para abordar isso.
Forçar professor
Para RNNs que produzem uma previsão a cada etapa do tempo (como prever o resultado das etapas a seguir, tradução ou reconhecimento de fonemas), a obrigatoriedade do professor é um método para isolar cada etapa da RNN. Ao remover essas dependências, o Teacher Forcing permite que a RNN use backprop convencional com a regra de cadeia.
Mas como isso funciona? As redes de forçadores de professores têm arquiteturas de trem e teste separadas. Para treinamento, a cada passot , a entrada xt é concatenado com o destino anterior, yt - 1 . Imagine isso para uma rede encarregada de prever o seguinte caractere. A rede acabou de tentar prever o caractere para o timestep anterior. Mas, em vez disso, usamos o caractere observado nesse momento (sabemos disso porque estamos na fase de treinamento). Assim, o erro na timestept depende apenas do valor observado em t - 1 e a entrada em t . Assim, removemos quaisquer conexões ao longo do tempo da rede.
No teste, não sabemos o valor real a cada passo do tempo, então substituímosyt - 1 com a saída da camada anterior ot - 1 . Nesse caso, as conexões temporais retornaram, mas apenas para a fase de teste.
Back Propagation Through Time
Mas não precisamos recorrer à força do professor. A propagação de retorno ao longo do tempo nos permite aplicar o algoritmo de backprop às RNNs. Considere a rede comn timesteps e uma entrada x estado oculto h , resultado o e valor observado y para cada timestep.
O BPTT funciona nas seguintes etapas.
Leitura adicional
Eu recomendo o capítulo 10 do Deep Learning de Goodfellow, Bengio e Courville para obter mais informações sobre RNNs. Além disso, o livro RNN da Graves é fantástico para detalhes de nível superior
fonte