Aula 4, GRU
Esta aula apresenta a GRU, uma célula recorrente com portões mais enxuta que a LSTM, e fecha o módulo com o projeto integrador, um classificador neural de intenção de mensagens curtas. Vamos ver os portões da GRU e treinar um classificador de texto do zero.
A LSTM resolveu o problema da memória longa, mas com um custo, são três portões e dois estados, o que significa muitos parâmetros e treino mais pesado. Surge então uma pergunta natural, dá para ter os benefícios dos portões com menos peças? A GRU, proposta por Cho e colegas em 2014, responde que sim.
A GRU simplifica a ideia da LSTM. Ela usa apenas dois portões e um único estado, e ainda assim aprende dependências longas muito bem. Em muitas tarefas, GRU e LSTM têm desempenho parecido, como comparou o estudo de Chung e colegas, e a GRU costuma ser preferida quando se quer um modelo mais leve. Nesta aula você vai entender os portões da GRU e, no projeto que fecha o módulo, construir um classificador neural de intenção, juntando o que aprendeu sobre redes e texto.
Objetivos
Ao final desta aula, você deve ser capaz de:
- Explicar os portões de atualização e de reinício da GRU.
- Comparar a GRU com a LSTM em estrutura e custo.
- Implementar a passagem para frente de uma célula GRU.
- Construir um classificador neural de intenção de mensagens curtas.
Teoria
A GRU funde algumas ideias da LSTM em uma estrutura mais simples. Ela tem um único estado escondido, sem o estado de célula separado, e usa dois portões. O portão de atualização decide quanto do estado anterior manter e quanto do novo candidato incorporar, juntando em uma só válvula os papéis que na LSTM eram do esquecimento e da entrada. O portão de reinício decide quanto do passado considerar ao calcular o novo candidato.
flowchart LR
H0[h anterior] --> R[portão de reinício]
X[entrada] --> R
X --> U[portão de atualização]
R --> C[candidato a novo estado]
X --> C
H0 --> U
C --> H1[h novo]
U --> H1
H0 --> H1
Com menos portões e um só estado, a GRU tem menos parâmetros que a LSTM, treina um pouco mais rápido e ocupa menos memória. Em troca, abre mão de parte da flexibilidade da LSTM. Na prática, a escolha entre as duas costuma ser empírica, testa-se as duas e fica-se com a que vai melhor na tarefa, embora a GRU seja uma ótima primeira escolha pela simplicidade.
Explicação Intuitiva
Se a LSTM é uma esteira de memória com três operários cuidando dela, a GRU é uma versão enxuta com dois. O portão de atualização é o operário principal, ele decide, em uma única alavanca, o quanto da memória antiga fica e o quanto da nova entra, fazendo o trabalho que na LSTM era dividido entre dois portões. O portão de reinício é um ajudante que, quando conveniente, manda ignorar parte do passado para formar a nova ideia.
O efeito prático é parecido com o da LSTM, a GRU também consegue segurar informações por muitos passos quando o portão de atualização escolhe preservar o estado. Ela faz isso com menos maquinaria, o que costuma render um modelo mais leve e quase tão capaz, uma troca muito atraente na maioria das aplicações.
Explicação Matemática
A GRU calcula, a cada passo, o portão de reinício $r_t$ e o de atualização $u_t$, ambos com a sigmoide, a partir da entrada $x_t$ e do estado anterior $h_{t-1}$:
\[r_t = \sigma(W_r [x_t, h_{t-1}] + b_r), \qquad u_t = \sigma(W_u [x_t, h_{t-1}] + b_u).\]Em seguida, calcula um candidato a novo estado, usando o portão de reinício para modular o quanto do passado entra nessa conta:
\[\tilde{h}_t = \tanh\left(W_h [x_t, r_t \odot h_{t-1}] + b_h\right).\]Por fim, o portão de atualização combina o estado anterior com o candidato:
\[h_t = (1 - u_t) \odot h_{t-1} + u_t \odot \tilde{h}_t.\]Repare na última equação. Quando $u_t \approx 0$, o estado quase não muda, $h_t \approx h_{t-1}$, preservando a memória, exatamente o mecanismo aditivo que dá à GRU a capacidade de lembrar por longos períodos, com uma equação a menos que a LSTM.
Exemplo Prático
Esta aula tem duas partes práticas. Primeiro, implementamos a passagem para frente de uma célula GRU, para ver os dois portões em ação e confirmar que a célula processa uma sequência. Depois, no projeto que fecha o módulo, construímos um classificador neural de intenção, que decide se uma mensagem curta de aluno é uma dúvida, um elogio ou um problema técnico.
Para o classificador, juntamos o que vimos no curso, representamos a mensagem com Bag of Words, do Módulo 3, e classificamos com a rede neural da primeira aula deste módulo. O código está no notebook notebooks/modulo-05/04-gru.ipynb, então abra-o ao lado para acompanhar, inclusive a versão opcional do classificador com uma GRU de verdade em PyTorch.
Código Comentado
import numpy as np
def sigmoide(z):
return 1 / (1 + np.exp(-z))
def gru_passo(x, h, P):
"""Uma passagem da célula GRU, com portões de reinício e atualização."""
z = np.concatenate([x, h])
r = sigmoide(P["Wr"] @ z + P["br"]) # portão de reinício
u = sigmoide(P["Wu"] @ z + P["bu"]) # portão de atualização
candidato = np.tanh(P["Wh"] @ np.concatenate([x, r * h]) + P["bh"])
h_novo = (1 - u) * h + u * candidato # combina passado e candidato
return h_novo
# Inicializa os parâmetros de uma GRU pequena e processa uma sequência.
H, Dx = 5, 1
rng = np.random.default_rng(2)
P = {k: rng.normal(0, 0.3, (H, H + Dx)) for k in ["Wr", "Wu", "Wh"]}
P.update({k: np.zeros(H) for k in ["br", "bu", "bh"]})
h = np.zeros(H)
for x in [0.0, 1.0, 0.0, 1.0]:
h = gru_passo(np.array([x]), h, P)
print("estado final da GRU após a sequência:")
print(np.round(h, 3))
Ao rodar, a célula GRU processa a sequência e produz um estado final, mostrando que os dois portões funcionam como esperado. Com menos parâmetros que a LSTM, ela chega a um mecanismo de memória semelhante. No notebook, o projeto usa esses conceitos para treinar um classificador de intenção de verdade, fechando o módulo.
Exercícios
1) Conceitual: Quais são os dois portões da GRU e o que cada um controla? 2) Conceitual: Como o portão de atualização da GRU reúne, em uma só alavanca, os papéis do esquecimento e da entrada da LSTM? 3) Prático: No classificador de intenção do notebook, acrescente exemplos de uma nova intenção e veja se a rede passa a reconhecê-la. 4) Prático: Compare o número de parâmetros de uma GRU e de uma LSTM com a mesma dimensão de estado, e comente a diferença. 5) Extensão: Leia o estudo de Chung e colegas e resuma em um parágrafo as conclusões sobre quando GRU e LSTM se equivalem.
Projeto da Aula e Projeto do Módulo
Este é o projeto que fecha o módulo. A entrega é um classificador neural de intenção de mensagens curtas de alunos, que separa, por exemplo, dúvidas de conteúdo, elogios e problemas técnicos. A versão principal, que roda do zero, representa cada mensagem com Bag of Words e a classifica com a rede neural da primeira aula. A versão avançada, opcional, usa uma GRU em PyTorch sobre a sequência de palavras.
O roteiro sugerido é o seguinte. Monte um conjunto de mensagens rotuladas por intenção, separando algumas para teste. Treine a rede neural sobre os vetores Bag of Words e meça a acurácia. Em seguida, se quiser, implemente a versão com GRU em PyTorch e compare.
Considere o projeto pronto quando você tiver a acurácia do classificador nas mensagens de teste e um parágrafo discutindo os acertos e os erros, e o que uma versão recorrente poderia capturar que a Bag of Words ignora, como a ordem das palavras. Com isso, você fecha o módulo de Deep Learning para NLP e fica pronto para o Módulo 6, em que os Transformers substituem a recorrência pela atenção.
Leituras Recomendadas
- O artigo de Cho e colegas que introduziu a GRU, no contexto de tradução automática.
- O estudo de Chung e colegas comparando GRU e LSTM em modelagem de sequências.
- Tutoriais do PyTorch sobre módulos recorrentes, úteis para a versão avançada do projeto.
Referências Científicas
As referências abaixo são reais e estão registradas em references/referencias.bib. As chaves entre parênteses são as do BibTeX.
- Cho, K., et al. (2014). Learning Phrase Representations using RNN Encoder-Decoder for
Statistical Machine Translation. EMNLP. (
cho2014gru) - Chung, J., Gulcehre, C., Cho, K., e Bengio, Y. (2014). Empirical Evaluation of Gated
Recurrent Neural Networks on Sequence Modeling. (
chung2014empirical) - Hochreiter, S., e Schmidhuber, J. (1997). Long Short-Term Memory. Neural Computation,
9(8), 1735-1780. (
hochreiter1997lstm)