Was genau sind Aufmerksamkeitsmechanismen?

23

In den letzten Jahren wurden in verschiedenen Deep-Learning-Artikeln Aufmerksamkeitsmechanismen eingesetzt. Ilya Sutskever, Forschungsleiter bei Open AI, hat sie begeistert gelobt: https://towardsdatascience.com/the-fall-of-rnn-lstm-2d1594c74ce0

Eugenio Culurciello von der Purdue University hat gefordert, dass RNNs und LSTMs zugunsten rein auf Aufmerksamkeit basierender neuronaler Netze aufgegeben werden sollten:

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

Dies scheint übertrieben, aber es ist nicht zu leugnen, dass rein aufmerksamkeitsbasierte Modelle bei Sequenzmodellierungsaufgaben recht gut abschneiden: Wir alle kennen das treffend benannte Papier von Google, Aufmerksamkeit ist alles, was Sie brauchen

Was genau sind aufmerksamkeitsbasierte Modelle? Ich habe noch keine klare Erklärung für solche Modelle gefunden. Angenommen, ich möchte die neuen Werte einer multivariaten Zeitreihe anhand ihrer historischen Werte vorhersagen. Es ist ziemlich klar, wie man das mit einem RNN macht, das LSTM-Zellen hat. Wie würde ich dasselbe mit einem aufmerksamkeitsbasierten Modell machen?

DeltaIV
quelle

Antworten:

20

Aufmerksamkeit ist ein Verfahren zum Ansammeln einer Menge von Vektoren vi in nur einem Vektor, oft über eine Lookup - Vektor u . In der Regel sind vi entweder die Eingaben in das Modell oder die verborgenen Zustände früherer Zeitschritte oder die verborgenen Zustände eine Ebene tiefer (im Fall von gestapelten LSTMs).

Das Ergebnis wird oft als Kontextvektor c , da es den für den aktuellen Zeitschritt relevanten Kontext enthält .

Dieser zusätzliche Kontextvektor c wird dann ebenfalls in das RNN / LSTM eingespeist (er kann einfach mit der ursprünglichen Eingabe verkettet werden). Daher kann der Kontext zur Vorhersage verwendet werden.

Der einfachste Weg, dies zu tun, besteht darin, den Wahrscheinlichkeitsvektor p=softmax(VTu) und c=ipivi zu berechnen, wobei V die Verkettung aller vorherigen vi . Ein üblicher Nachschlagevektor u ist der aktuelle verborgene Zustand ht .

Es gibt viele Variationen, und Sie können die Dinge so kompliziert gestalten, wie Sie möchten. Beispielsweise kann man stattdessen f ( v i , u ) wählen , wobei f ein beliebiges neuronales Netzwerk ist , anstatt viTu als Protokoll zu verwenden .f(vi,u)f

Ein häufige Aufmerksamkeit Mechanismus für sequenz to-Sequenzmodelle Verwendungen p=softmax(qTtanh(W1vi+W2ht)) , wobei v die versteckten Zustände des Codierers und ht ist der aktuelle verborgene Zustand des Decoders. q und beide W s sind Parameter.

Einige Artikel, die verschiedene Variationen der Aufmerksamkeitsidee zeigen:

Zeigernetzwerke verwenden die Aufmerksamkeit auf Referenzeingaben, um kombinatorische Optimierungsprobleme zu lösen.

Wiederkehrende Entitätsnetzwerke verwalten separate Speicherzustände für verschiedene Entitäten (Personen / Objekte), während sie Text lesen, und aktualisieren den korrekten Speicherzustand mit Aufmerksamkeit.

Transformatormodelle machen auch ausgiebig Gebrauch von Aufmerksamkeit. Ihre Aufmerksamkeitsformulierung ist etwas allgemeiner und beinhaltet auch Schlüsselvektoren ki : Die Aufmerksamkeitsgewichte p werden tatsächlich zwischen den Schlüsseln und dem Nachschlagen berechnet, und der Kontext wird dann mit dem vi konstruiert .


Hier ist eine schnelle Implementierung einer Form von Aufmerksamkeit, obwohl ich die Richtigkeit nicht garantieren kann, außer dass sie einige einfache Tests bestanden hat.

Grundlegende 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]

Mit Aufmerksamkeit fügen wir nur ein paar Zeilen hinzu, bevor der neue verborgene Zustand berechnet wird:

        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 )

den vollständigen Code

shimao
quelle
p=softmax(VTu)ic=ipivipiVTvVTv
1
zi=viTup=softmax(z)pi=eizjejz
ppi
1
ja, das habe ich gemeint
shimao
@shimao Ich habe einen Chatraum erstellt. Wenn Sie Interesse haben, mit mir zu sprechen, lassen Sie es mich wissen (nicht über diese Frage)
DeltaIV