Czym dokładnie są mechanizmy uwagi?

23

Mechanizmy uwagi były wykorzystywane w różnych artykułach Deep Learning w ciągu ostatnich kilku lat. Ilya Sutskever, kierownik badań w Open AI, entuzjastycznie je chwali: https://towardsdatascience.com/the-fall-of-rnn-lstm-2d1594c74ce0

Eugenio Culurciello z Purdue University stwierdził, że RNN i LSTM należy porzucić na rzecz sieci neuronowych opartych wyłącznie na uwadze:

https://towardsdatascience.com/the-fall-of-rnn-lstm-2d1594c74ce0

Wydaje się to przesadą, ale nie można zaprzeczyć, że modele oparte wyłącznie na uwadze poradziły sobie całkiem dobrze w zadaniach modelowania sekwencyjnego: wszyscy wiemy o trafnie nazwanym papierze od Google, Uwaga jest wszystkim, czego potrzebujesz

Jednak to, co dokładnie są modele oparte uwaga? Muszę jeszcze znaleźć jasne wyjaśnienie takich modeli. Załóżmy, że chcę prognozować nowe wartości wielowymiarowego szeregu czasowego, biorąc pod uwagę jego wartości historyczne. Jest całkiem jasne, jak to zrobić z RNN z komórkami LSTM. Jak zrobiłbym to samo z modelem opartym na uwadze?

DeltaIV
źródło

Odpowiedzi:

20

Uwaga jest metodą agregacji zbioru wektorów vi w jeden wektor, często za pośrednictwem wektora odnośnika u . Zwykle vi jest albo danymi wejściowymi do modelu, albo stanami ukrytymi poprzednich kroków czasowych, albo stanami ukrytymi jeden poziom niżej (w przypadku skumulowanych LSTM).

Wynik jest często nazywany wektorem kontekstu c , ponieważ zawiera kontekst odpowiedni dla bieżącego kroku czasowego.

Ten dodatkowy wektor kontekstu c jest następnie podawany również do RNN / LSTM (można go po prostu połączyć z oryginalnym wejściem). Dlatego kontekst może służyć do przewidywania.

Najprostszym sposobem osiągnięcia tego jest, aby obliczyć prawdopodobieństwo wektora p=softmax(VTu) i c=ipivi , gdzie V jest połączeniem wszystkich poprzednichvi . Typowym wyszukiwanie wektorau jest obecny stan ukrytyht .

Jest na to wiele odmian i możesz sprawić, że wszystko będzie tak skomplikowane, jak tylko chcesz. Na przykład, zamiast używania viTu jako logów, można zamiast tego wybrać f(vi,u) , gdzie f jest dowolną siecią neuronową.

Mechanizm wspólnej uwagi dla modeli sekwencyjno-sekwencyjnych wykorzystuje p=softmax(qTtanh(W1vi+W2ht)) , gdzie v są stanami ukrytymi enkodera, a ht jest bieżącym stanem ukrytym dekodera. q i oba W s są parametrami.

Niektóre artykuły prezentujące różne warianty pomysłu uwagi:

Pointer Networks zwraca uwagę na dane wejściowe w celu rozwiązania problemów optymalizacji kombinatorycznej.

Sieci jednostek cyklicznych utrzymują oddzielne stany pamięci dla różnych bytów (ludzi / obiektów) podczas czytania tekstu i aktualizują poprawny stan pamięci, zwracając uwagę.

Modele transformatorowe również szeroko wykorzystują uwagę. Ich formuła uwagi jest nieco bardziej ogólnie, a także wiąże się kluczowymi wektory ki : the ciężary uwaga p faktycznie obliczane między klawiszami oraz odnośnika, a kontekst jest wówczas zbudowany z vi .


Oto szybkie wdrożenie jednej formy uwagi, chociaż nie mogę zagwarantować poprawności poza tym, że przeszedł kilka prostych testów.

Podstawowy RNN:

def rnn(inputs_split):
    bias = tf.get_variable('bias', shape = [hidden_dim, 1])
    weight_hidden = tf.tile(tf.get_variable('hidden', shape = [1, hidden_dim, hidden_dim]), [batch, 1, 1])
    weight_input = tf.tile(tf.get_variable('input', shape = [1, hidden_dim, in_dim]), [batch, 1, 1])

    hidden_states = [tf.zeros((batch, hidden_dim, 1), tf.float32)]
    for i, input in enumerate(inputs_split):
        input = tf.reshape(input, (batch, in_dim, 1))
        last_state = hidden_states[-1]
        hidden = tf.nn.tanh( tf.matmul(weight_input, input) + tf.matmul(weight_hidden, last_state) + bias )
        hidden_states.append(hidden)
    return hidden_states[-1]

Z uwagą dodajemy tylko kilka wierszy przed obliczeniem nowego stanu ukrytego:

        if len(hidden_states) > 1:
            logits = tf.transpose(tf.reduce_mean(last_state * hidden_states[:-1], axis = [2, 3]))
            probs = tf.nn.softmax(logits)
            probs = tf.reshape(probs, (batch, -1, 1, 1))
            context = tf.add_n([v * prob for (v, prob) in zip(hidden_states[:-1], tf.unstack(probs, axis = 1))])
        else:
            context = tf.zeros_like(last_state)

        last_state = tf.concat([last_state, context], axis = 1)

        hidden = tf.nn.tanh( tf.matmul(weight_input, input) + tf.matmul(weight_hidden, last_state) + bias )

pełny kod

shimao
źródło
p=softmax(VTu)ic=ipivipiVTvVTv seems to be the current hidden state. Is this correct?
DeltaIV
1
another way to write it is zi=viTu and then p=softmax(z) or pi=eizjejz
shimao
hmmm, so p is a vector and pi are its components, right?
DeltaIV
1
yes, that's what i meant
shimao
@shimao I created a chat room, let me know if you'd be interested to talk (not about this question)
DeltaIV