aitech-eks-pub/wyk/15_transformer.ipynb

6.7 KiB

Logo 1

Ekstrakcja informacji

15. Sieci Transformer i ich zastosowanie w ekstrakcji informacji [wykład]

Filip Graliński (2021)

Logo 2

Modele Transformer

Atencja

Atencję w modelach Transformer można interpretować jako rodzaj „miękkiego” odpytywania swego rodzaju bazy danych, w której przechowywane są pary klucz-wartość. Mamy trzy rodzaje wektorów (a właściwie macierzy, bo wektory są od razu upakowane w macierze):

  • $Q$ - macierz zapytań,
  • $K$ - macierz kluczy,
  • $V$ - macierz wartości odpowiadających kluczom $K$.

W atencji modeli Transformer patrzymy jak bardzo zapytania $Q$ pasują do kluczy $K$ i na tej podstawie zwracamy wartości $V$ (im bardziej klucz pasuje do zapytania, tym większy wkład wnosi odpowiednia wartość). Ten rodzaj odpytywania można zrealizować z pomocą mnożenia macierzy i funkcji softmax:

$$\operatorname{Atention}(Q,K,V) = \operatorname{softmax}(QK^T)V$$

Uproszczony przykład

Załóżmy, że rozmiar embeddingu wynosi 4, w macierzach rozpatrywać będziemy po 3 wektory naraz (możemy sobie wyobrazić, że zdanie zawiera 3 wyrazy).

import torch

Q =  torch.tensor([
        [0.3, -2.0, 0.4, 6.0],
        [-1.0, 1.5, 0.2, 3.0],
        [0.3, -1.0, 0.2, 1.0]])

K =  torch.tensor([
        [-0.5, 1.7, 0.3, 4.0],
        [0.4, -1.5, 0.3, 5.5],
        [-1.0, -3.5, 1.0, 4.0]])

M = Q @ torch.transpose(K, 0, 1)
M
tensor([[20.5700, 36.2400, 31.1000],
        [15.1100, 13.9100,  7.9500],
        [ 2.2100,  7.1800,  7.4000]])

Jak widać, najbardziej pierwszy wektor $Q$ pasuje do drugiego wektora $K$. Znormalizujmy te wartości używać funkcji softmax.

import torch

Mn = torch.softmax(M, 1)
Mn
tensor([[1.5562e-07, 9.9418e-01, 5.8236e-03],
        [7.6807e-01, 2.3134e-01, 5.9683e-04],
        [3.0817e-03, 4.4385e-01, 5.5307e-01]])

Drugi wektor zapytania najbardziej pasuje do pierwszego klucza, trochę mniej do drugiego klucza, o wiele mniej do trzeciego klucza. Te wektory to oczywiście wektory atencji (drugie słowo najbardziej „patrzy” na pierwsze słowo).

Teraz będziemy przemnażać przez wektory wartości:

import torch

V =  torch.tensor([
        [0.0, 9.0, 0.0, -5.0, 1.2],
        [4.0, 0.1, 0.1, 0.1, 0.0],
        [-0.3, 0.0, 0.3, 10.0, 0.1]])

Mn @ V
tensor([[ 3.9750e+00,  9.9419e-02,  1.0116e-01,  1.5765e-01,  5.8255e-04],
        [ 9.2517e-01,  6.9357e+00,  2.3313e-02, -3.8112e+00,  9.2174e-01],
        [ 1.6095e+00,  7.2120e-02,  2.1031e-01,  5.5597e+00,  5.9005e-02]])

Dodatkowa normalizacja

W praktyce dobrze jest znormalizować pierwszy iloczyn przez $\sqrt{d_k}$, gdzie $d_k$ to rozmiar wektora klucza.

$$\operatorname{Atention}(Q,K,V) = \operatorname{softmax}(\frac{QK^T}{\sqrt{d^k}})V$$

Skąd się biorą Q, K i V?

Wektory (macierze) $Q$, $K$ i $V$ w pierwszej warstwie pochodzą z embeddingów tokenów $E$ (właściwie jednostek BPE).

  • $Q$ = $EW^Q$
  • $K$ = $EW^K$
  • $V$ = $EW^V$

W kolejnych warstwach zamiast $E$ wykorzystywane jest wyjście z poprzedniej warstwy.

Literatura