Primeiramente, vamos considerar o caso sem Multi-headed attention. Assim, queremos computar os vetores contextualizados
Assim, como comentado anteriormente, usamos as palavras presentes na sequência de três maneiras distintas, associadas à três matrizes de pesos. Portanto, usaremos a seguinte notação:
$$Q_{(n \times d)} = X^Q_{(n \times d)} W^Q_{(d \times d)}$$ $$K_{(n \times d)} = X^K_{(n \times d)} W^K_{(d \times d)}$$ $$V_{(n \times d)} = X^V_{(n \times d)} W^V_{(d \times d)}$$
onde
Assim, primeiro relacionamos as palavras via dot product para obter os scores. Então, podemos representar esses scores como:
Para entender melhor essa operação, usaremos a notação de colunas e linhas do Python, usando slicing. Então, se temos uma matriz
Então, voltando à matriz
Então, se $$Q[i, :]{(1 \times d)}$$ é uma palavra (vetor), $$\text{Scores}[i, :]{(1 \times n)}$$ é importância contextual dessa palavra para todas as palavras da sequência.
Desse modo, perceba que $$\text{Scores}[i, :] = \begin{Bmatrix} Q[i, :] \cdot K^T[:, 1] & Q[i, :] \cdot K^T[:, 2] & \cdots & Q[i, :] \cdot K^T[:, n] \ \end{Bmatrix}$$
Onde $$ A[i, :] \cdot K^T[:, j] = v_i \cdot v_j = s_{ij} $$
No paper Attention is All you Need, há um fator de escala (que é um escalar) para essa multiplicação de matrizes. Esse fator não é tão importante para o entendimento conceitual desse mecanismo. Então, vamos ignorá-lo.
Depois disso, devemos aplicar a função softmax para normalizar esses scores. Então, temos:
$$\text{Scores} = QK^T$$ -
$$\text{softmax}\left( \text{Scores}\right)$$ Os elementos dessa matriz são$$w_{i,j}, i = 1, \ldots, n ; j = 1, \ldots, n$$
Agora que já temos os scores normalizados que indicam a importância contextual (normalizada) de cada palavra relacionada entre si, entramos em um próximo estágio do processo:
O vetor contextualizado (
Então para obter essa soma, usamos a matriz de palavras
Seja o vetor contextualizado $${\bf y}i = \begin{Bmatrix} y{i,1} & y_{i,2} & \cdots & y_{i,d} \end{Bmatrix}$$
onde
Perceba que isso é equivalente à multiplicar a linha
$$ \text{Scores}{(n \times n)}V{(n \times d)} = C_{(n \times d)} $$
Onde o
Portanto, temos que:
Como já comentado, multihead attention é usado ao fazer a entrada (no caso a matriz
Onde:
Observe a concatenação dos diversos resultados de self-attention e a passagem desse vetor concatenado por uma matriz de pesos:
$$ \text{Concat}(\text{head}1, \text{head}2, \ldots, \text{head}h){(n \times hd)}W^O{(hd \times d)} = M{(n \times d)} $$
No artigo Attention is All you Need, o mecanismo de Attention é definido como se segue: $$ \text{Attention}\left(Q, K , V\right) = \text{softmax}\left(\dfrac{QK^T}{\sqrt{d_k}}\right)V $$
O fator de escala $$ \dfrac{1}{\sqrt{d_k}} $$
Onde
A justificativa para a presença desse fator de escala na operação é para lidar com o problema de desaparecimento de gradiente relacionado ao dot product utilizado para computar attention. Perceba que essa escala é uma operação element wise na matriz
Sabendo que
Onde
Em que
Então, assumindo que os componentes de
$$
\text{E} \left(q^{(i)} \cdot k^{(j)}\right) = \text{E} \left( \sum_{p=1}^{d_k} q^{(i)}_p k^{(j)}p \right) = \sum{p=1}^{d_k} \text{E} \left( q^{(i)}_p k^{(j)}p \right) = \sum{p=1}^{d_k} \text{E} \left( q^{(i)}_p \right) \text{E} \left( k^{(j)}_p \right) = 0
$$
e
Disso,
$$ \text{E} \left(\left(q^{(i)} \cdot k^{(j)} \right)^2\right) = \text{E} \left( \sum_{p=1}^{d_k} q^{(i)}_p k^{(j)}p \sum{r=1}^{d_k} q^{(i)}_r k^{(j)}r \right) = \text{E} \left( \sum{\substack{p=1 \ r=1}}^{d_k} q^{(i)}_p k^{(j)}_p q^{(i)}_r k^{(j)}r \right) = \sum{\substack{p=1 \ r=1}}^{d_k} \text{E} \left( q^{(i)}_p k^{(j)}_p q^{(i)}_r k^{(j)}_r \right) $$
Quando
Pois os elementos de
Então: $$ \text{E} \left( q^{(i)^2}_p k^{(j)^2}_p\right) = \left( \text{E} \left( q^{(i)}_p \right) - \text{E} \left( q^{(i)^2}_p \right) \right) \left( \text{E} \left(k^{(j)}_p\right) - \text{E} \left(k^{(j)^2}_p\right) \right) = \text{Var} \left( q^{(i)}_p \right) \text{Var} \left( k^{(j)}_p \right) = 1 \cdot 1 = 1 $$
Assim, $$ \text{Var} \left(q^{(i)} \cdot k^{(j)}\right) = \sum_{\substack{p=1 \ r=1}}^{d_k} \text{E} \left( q^{(i)}_p k^{(j)}_p q^{(i)}_r k^{(j)}r \right) = \sum{p=1}^{d_k} \text{E} \left( q^{(i)^2}_p k^{(j)^2}p \right) = \sum{p=1}^{d_k} 1 = d_k $$
Com esse valor tão alto de variância a função Softmax pode nos devolver valores baixos demais, o que causa desaparecimento de gradiente. Ao usarmos o fator de escala, recuperamos uma variância de 1, o que melhora essa questão do desaparecimento do gradiente.
Quando falamos de deep learning, o método de otimização mais utilizado é Mini-Batch Gradient Descent. Então, como incorporar batches à esse processo de treinamento?
A resposta para essa pergunta não é tão complicada. Na prática, basta incorporar mais uma dimensão à matriz de entrada
É interessante comentar sobre batches pois essa técnica, juntamente com Positional encoding (que será abordado mais adiante) implica em uma conhecida limitação da arquitetura Transformer. Perceba que, em um batch de 32 sequências, a matriz de entrada é tal que temos um valor constante (para cada sequência) de
Para
Agora, para
Desse modo, introduzimos à noção de um tamanho máximo de sequência na arquitetura Transformer, mas qual é o maior tamanho de sequência que essa arquitetura é capaz de lidar.
Se observarmos as matrizes de pesos treináveis
Contudo, isso não é nenhum impeditivo. Porém, além desse custo elevado de processamento, um problema a se considerar ao lidar com sequências longas é o da memória. Perceba que no caso de uma sequência (de comprimento
Desse modo, temos complexidade
Além dessas questões, sequências muito longas podem fazer com que o Positional-Encoding empregado no modelo não funcione bem. Já que geralmente esse encoding é composto de uma combinação de ondas senoidais, é possível que para sequências muito longas, o período dessas ondas não seja longo o suficiente, o que pode fazer com que uma palavra no final da sequência seja interpretada como uma palavra no início da sequência.