Modelos de transformadores 101: Introdução — Parte 1

Feb 19 2023
A matemática complexa por trás dos modelos de transformadores, em palavras simples Não é segredo que a arquitetura do transformador foi um avanço no campo do Processamento de Linguagem Natural (NLP). Ele superou a limitação de modelos seq-to-seq como RNNs, etc por serem incapazes de capturar dependências de longo prazo em texto.

A matemática complexa por trás dos modelos de transformadores, em palavras simples

Imagem de Kerttu do Pixabay

Não é segredo que a arquitetura do transformador foi um avanço no campo do Processamento de Linguagem Natural (NLP). Ele superou a limitação de modelos seq-to-seq como RNNs, etc por serem incapazes de capturar dependências de longo prazo em texto. A arquitetura do transformador acabou sendo a pedra fundamental de arquiteturas revolucionárias como BERT, GPT e T5 e suas variantes. Como muitos dizem, a PNL está no meio de uma era de ouro e não seria errado dizer que o modelo do transformador é onde tudo começou.

Necessidade de Arquitetura Transformer

Como disse, a necessidade é a mãe da invenção. Os modelos tradicionais seq-to-seq não eram bons quando se tratava de trabalhar com textos longos. O que significa que o modelo tende a esquecer os aprendizados das partes anteriores da sequência de entrada à medida que se move para processar a última parte da sequência de entrada . Esta perda de informação é indesejável.

Embora arquiteturas fechadas como LSTMs e GRUs mostrassem alguma melhoria no desempenho para lidar com dependências de longo prazo, descartando informações inúteis ao longo do caminho para lembrar informações importantes, ainda não era suficiente. O mundo precisava de algo mais poderoso e em 2015, os “ mecanismos de atenção” foram introduzidos por Bahdanau et al .Eles foram usados ​​em combinação com RNN/LSTM para imitar o comportamento humano para se concentrar em coisas seletivas, ignorando o resto. Bahdanau sugeriu atribuir importância relativa a cada palavra em uma frase para que o modelo se concentre nas palavras importantes e ignore o resto. Emergiu como uma grande melhoria em relação aos modelos de codificador-decodificador para tarefas de tradução automática neural e, em breve, a aplicação do mecanismo de atenção também foi lançada em outras tarefas.

A era dos modelos transformadores

Os modelos transformadores são inteiramente baseados em um mecanismo de atenção também conhecido como “autoatenção” . Essa arquitetura foi apresentada ao mundo no artigo “ Atenção é tudo que você precisa ” em 2017. Ela consistia em uma arquitetura codificadora-decodificadora.

Fig. Arquitetura do modelo de transformador em alto nível (Fonte: Autor)

Em alto nível,

  • O codificador é responsável por aceitar a sentença de entrada e convertê-la em uma representação oculta com todas as informações inúteis descartadas.
  • O decodificador aceita essa representação oculta e tenta gerar a sentença de destino.

Codificador do Transformador

O bloco codificador do transformador consiste em uma pilha de N codificadores que funcionam sequencialmente. A saída de um encoder é a entrada para o próximo encoder e assim por diante. A saída do último codificador é a representação final da sentença de entrada que alimenta o bloco decodificador.

Fig. Bloco Enoder com encoders empilhados (Fonte: Autor)

Cada bloco do codificador pode ser dividido em dois componentes, conforme mostrado na figura abaixo.

Fig. Componentes da Camada do Codificador (Fonte: Autor)

Vamos examinar cada um desses componentes um por um em detalhes para entender como o bloco codificador está funcionando. O primeiro componente no bloco do codificador é a atenção de várias cabeças , mas antes de entrarmos nos detalhes, vamos primeiro entender um conceito subjacente: auto-atenção .

Mecanismo de auto-atenção

A primeira pergunta que pode surgir na cabeça de todos: atenção e auto-atenção são conceitos diferentes? Sim, eles estão. (Duh!)

Tradicionalmente, os mecanismos de atenção surgiram para a tarefa de tradução automática neural, conforme discutido na seção anterior. Então, essencialmente, o mecanismo de atenção foi aplicado para mapear a frase fonte e alvo. Como os modelos seq-to-seq executam a tarefa de tradução token por token, o mecanismo de atenção nos ajuda a identificar em qual token (s) da frase de origem focar mais ao gerar o token x para a frase de destino. Para isso, faz uso de representações de estado oculto de codificadores e decodificadores para calcular os escores de atenção e gerar vetores de contexto com base nesses escores como entrada para o decodificador. Se você deseja aprender mais sobre o Mecanismo de Atenção, acesse este artigo (brilhantemente explicado!).

Voltando à auto-atenção , a ideia principal é calcular os escores de atenção ao mapear a frase de origem para si mesma. Se você tem uma frase como,

“O menino não atravessou a rua porque era muito larga.”

É fácil para nós, humanos, entender que a palavra “isso” se refere a “estrada” na frase acima, mas como fazemos nosso modelo de linguagem entender essa relação também? É aí que a auto-atenção entra em cena!

Em um alto nível, cada palavra na frase é comparada com todas as outras palavras na frase para quantificar as relações e entender o contexto. Para fins de representação, você pode consultar a figura abaixo.

Vejamos detalhadamente como essa autoatenção é calculada (em real).

  • Gerar incorporações para a frase de entrada
  • Transforme a matriz de entrada em Q, K e V

Para calcular essas três matrizes, inicializaremos aleatoriamente três matrizes de peso, ou seja, Wq, Wk e Wv . A matriz de entrada X será multiplicada por essas matrizes de peso Wq, Wk e Wv para obter valores para Q, K e V, respectivamente. Os valores ideais para matrizes de peso serão aprendidos durante o processo para obter valores mais precisos para Q, K e V.

  • Calcule o produto escalar de Q e K-transposta
Fig. Exemplo de produto escalar de Q e K-transposta (Fonte: Autor)

A primeira linha da matriz de saída informará como a palavra1 representada por q1 está relacionada ao restante das palavras na frase usando o produto escalar. Quanto maior o valor do produto escalar, mais relacionadas são as palavras. Para saber por que esse produto escalar foi calculado, você pode entender as matrizes Q (consulta) e K (chave) em termos de recuperação de informações. Então, aqui,
- Q ou Query = Termo que você está procurando
- K ou Key = um conjunto de palavras-chave em seu mecanismo de pesquisa com o qual Q é comparado e correspondido.

  • Escale o produto escalar
  • Normalize os valores usando softmax
  • Calcular a matriz de atenção Z

Mas espere, por que multiplicar?

Suponha que Si = [0,9, 0,07, 0,03] seja o valor da matriz de pontuação para a i-ésima palavra de uma sentença. Este vetor é multiplicado pela matriz V para calcular Zi (matriz de atenção para i-ésima palavra).

Zi = [0,9 * V1 + 0,07 * V2 + 0,03 * V3]

Podemos dizer que, para entender o contexto da i-ésima palavra, devemos nos concentrar apenas na palavra1 (ou seja, V1), pois 90% do valor da pontuação de atenção vem de V1? Podemos definir claramente as palavras importantes onde mais atenção deve ser dada para entender o contexto da i-ésima palavra.

Assim, podemos concluir que quanto maior a contribuição de uma palavra na representação Zi, mais críticas e relacionadas são as palavras entre si.

Agora que sabemos como calcular a matriz de autoatenção, vamos entender o conceito do mecanismo de atenção multicabeças .

Mecanismo de atenção multicabeça

O que acontecerá se sua matriz de pontuação for tendenciosa para uma representação de palavra específica? Isso enganará seu modelo e os resultados não serão tão precisos quanto esperamos. Vejamos um exemplo para entender melhor.

S1: “ Está tudo bem ”

Z(poço) = 0,6 * V(todos) + 0,0 * v(é) + 0,4 * V(poço)

S2: “ O cachorro comeu a comida porque estava com fome ”

Z(it) = 0,0 * V(o) + 1,0 * V(cachorro) + 0,0 * V(comeu) + …… + 0,0 * V(com fome)

No caso S1, ao calcular Z(bem), mais importância é dada a V(todos). É ainda mais do que o próprio V(bem). Não há garantia de quão preciso isso será.

No caso S2, ao calcular Z(it), toda a importância é dada a V(cachorro), enquanto as pontuações para o restante das palavras são 0,0 incluindo V(it) também. Isso parece aceitável, pois a palavra “isso” é ambígua. Faz sentido relacioná-lo mais com outra palavra do que com a própria palavra. Esse era todo o propósito desse exercício de calcular a autoatenção. Para lidar com o contexto de palavras ambíguas nas frases de entrada.

Em outras palavras, podemos dizer que, se a palavra atual for ambígua, não há problema em dar mais importância a alguma outra palavra ao calcular a autoatenção, mas em outros casos, pode ser enganoso para o modelo. Então o que fazemos agora?

E se calcularmos múltiplas matrizes de atenção em vez de calcular uma matriz de atenção e derivarmos a matriz de atenção final a partir delas?

É exatamente disso que se trata a atenção com várias cabeças ! Calculamos várias versões de matrizes de atenção z1, z2, z3, ….., zm e as concatenamos para derivar a matriz de atenção final. Dessa forma, podemos ter mais confiança em nossa matriz de atenção.

Passando para o próximo conceito importante,

Codificação Posicional

Nos modelos seq-to-seq, a frase de entrada é alimentada palavra por palavra para a rede que permite ao modelo rastrear as posições das palavras em relação a outras palavras.

Mas em modelos de transformadores, seguimos uma abordagem diferente. Em vez de fornecer entradas palavra por palavra, eles são alimentados paralelamente, o que ajuda a reduzir o tempo de treinamento e a aprender a dependência de longo prazo. Mas com essa abordagem, a ordem das palavras é perdida. No entanto, para entender o significado de uma frase corretamente, a ordem das palavras é extremamente importante. Para superar este problema, uma nova matriz chamada “ codificação posicional ” (P) é introduzida.

Essa matriz P é enviada junto com a matriz de entrada X para incluir as informações relacionadas à ordem das palavras. Por razões óbvias, as dimensões das matrizes X e P são as mesmas.

Para calcular a codificação posicional, a fórmula fornecida abaixo é usada.

Fig. Fórmula para calcular a codificação posicional (Fonte: Autor)

Na fórmula acima,

  • pos = posição da palavra na frase
  • d = dimensão da incorporação de palavra/token
  • i = representa cada dimensão na incorporação

Este vídeo cobre a codificação posicional em profundidade se você quiser saber mais sobre isso.

Guia visual para redes neurais de transformadores — (Parte 1) Incorporações de posição

Estou usando alguns recursos visuais do vídeo acima para explicar esse conceito com minhas palavras.

Fig. Representação Vetorial de Codificação Posicional (Fonte: Autor)

A figura acima mostra um exemplo de um vetor de codificação posicional junto com diferentes valores de variáveis.

Fig. Vetores de Codificação Posicional com constantes i e d (Fonte: Autor)
Fig. Vetores de Codificação Posicional com constantes i e d (Fonte: Autor)

A figura acima mostra como os valores de PE(pos, 2i) irão variar se i for constante e apenas pos variar . Como sabemos a onda senoidal é uma função periódica que tende a se repetir após um intervalo fixo. Podemos ver que os vetores de codificação para pos = 0 e pos = 6 são idênticos. Isso não é desejável, pois desejaríamos diferentes vetores de codificação posicional para diferentes valores de pos .

Isso pode ser obtido variando a frequência da onda senoidal.

Fig. Vetores de Codificação Posicional com variação de pos e i (Fonte: Autor)

À medida que o valor de i varia, a frequência das ondas senoidais também varia, resultando em ondas diferentes e, portanto, em valores diferentes para cada vetor de codificação posicional. Isso é exatamente o que queríamos alcançar.

A matriz de codificação posicional (P) é adicionada à matriz de entrada (X) e alimentada ao codificador.

Fig. Adicionando codificação posicional à incorporação de entrada (Fonte: Autor)

O próximo componente do codificador é a rede feedforward .

Rede de feedforward

Essa subcamada no bloco codificador é a rede neural clássica com duas camadas densas e ativações ReLU. Ele aceita a entrada da camada de atenção multicabeça, executa algumas transformações não lineares na mesma e, finalmente, gera vetores contextualizados. A camada totalmente conectada é responsável por considerar cada cabeça de atenção e aprender informações relevantes a partir delas. Como os vetores de atenção são independentes entre si, eles podem ser passados ​​para a rede transformadora de forma paralelizada.

O último e último componente do bloco Encoder é o componente Add & Norm .

Componente Adicionar & Norma

Esta é uma camada residual seguida pela normalização da camada . A camada residual garante que nenhuma informação importante relacionada à entrada de subcamadas seja perdida no processamento. Enquanto a camada de normalização promove um treinamento de modelo mais rápido e evita que os valores mudem fortemente.

Fig. Componentes do codificador com camadas Add & Norm incluídas (Fonte: Autor)

Dentro do codificador, existem duas camadas add & norm:

  • conecta a entrada da subcamada de atenção multi-head à sua saída
  • conecta a entrada da subcamada da rede feedforward à sua saída
  • Gere incorporações ou representações tokenizadas da frase de entrada. Esta será nossa matriz de entrada X.
  • Gere as incorporações posicionais para preservar as informações relacionadas à ordem das palavras da sentença de entrada e adicione-as à matriz de entrada X.
  • Inicializa aleatoriamente três matrizes: Wq, Wk e Wv, ou seja, pesos da consulta, chave e valor. Esses pesos serão atualizados durante o treinamento do modelo do transformador.
  • Multiplique a matriz de entrada X com cada um de Wq, Wk e Wv para gerar as matrizes Q (consulta), K (chave) e V (valor).
  • Calcule o produto escalar de Q e K-transpose, dimensione o produto dividindo-o pela raiz quadrada de dk ou dimensão de incorporação e, finalmente, normalize-o usando a função softmax.
  • Calcule a matriz de atenção Z multiplicando o V ou matriz de valor com a saída da função softmax.
  • Passe esta matriz de atenção para a rede feedforward para realizar transformações não lineares e gerar embeddings contextualizados.

Isso seria tudo para este artigo. Eu espero que você tenha achado isso útil. Se sim, não se esqueça de bater palmas e compartilhar com seus amigos.