Kann das bitte jemand erklären? Ich weiß, dass bidirektionale LSTMs einen Vorwärts- und einen Rückwärtsdurchlauf haben, aber was ist der Vorteil davon gegenüber einem unidirektionalen LSTM?
Wofür ist jeder von ihnen besser geeignet?
LSTM speichert in seinem Kern Informationen von Eingaben, die bereits im verborgenen Zustand durchlaufen wurden.
Unidirektionales LSTM bewahrt nur die Informationen von past, da die einzigen Eingaben, die es gesehen hat, aus der Vergangenheit stammen.
Wenn Sie bidirektional verwenden, werden Ihre Eingaben auf zwei Arten ausgeführt: eine von Vergangenheit zu Zukunft und eine von Zukunft zu Vergangenheit. Dieser Ansatz unterscheidet sich von der unidirektionalen Methode dadurch, dass in LSTM, das rückwärts ausgeführt wird, Informationen aus Zukunft und aufbewahrt werden Mit den beiden verborgenen Zuständen zusammen können Sie zu jedem Zeitpunkt Informationen aus Vergangenheit und Zukunft aufbewahren.
Wofür sie geeignet sind, ist eine sehr komplizierte Frage, aber BiLSTMs zeigen sehr gute Ergebnisse, da sie den Kontext besser verstehen können. Ich werde versuchen, dies anhand eines Beispiels zu erklären.
Nehmen wir an, wir versuchen, das nächste Wort in einem Satz vorherzusagen, auf einer hohen Ebene, was ein unidirektionaler LSTM sehen wird
Die Jungs gingen zu ...
Und Sie werden versuchen, das nächste Wort nur in diesem Kontext vorherzusagen. Mit bidirektionalem LSTM können Sie beispielsweise Informationen später anzeigen
LSTM weiterleiten:
Die Jungs gingen zu ...
Rückwärts-LSTM:
... und dann stiegen sie aus dem Pool
Anhand der Informationen aus der Zukunft können Sie erkennen, dass das Netzwerk möglicherweise leichter verstehen kann, was das nächste Wort ist.
Als Ergänzung zu Bluesummers Antwort sehen Sie hier, wie Sie bidirektionales LSTM von Grund auf implementieren, ohne das Modul BiLSTM
aufzurufen. Dies könnte den Unterschied zwischen unidirektionalen und bidirektionalen LSTMs besser kontrastieren. Wie Sie sehen, führen wir zwei LSTMs zusammen, um einen bidirektionalen LSTM zu erstellen.
Sie können die Ausgaben der vorwärts und rückwärts gerichteten LSTMs zusammenführen, indem Sie entweder {'sum', 'mul', 'concat', 'ave'}
.
left = Sequential()
left.add(LSTM(output_dim=hidden_units, init='uniform', inner_init='uniform',
forget_bias_init='one', return_sequences=True, activation='tanh',
inner_activation='sigmoid', input_shape=(99, 13)))
right = Sequential()
right.add(LSTM(output_dim=hidden_units, init='uniform', inner_init='uniform',
forget_bias_init='one', return_sequences=True, activation='tanh',
inner_activation='sigmoid', input_shape=(99, 13), go_backwards=True))
model = Sequential()
model.add(Merge([left, right], mode='sum'))
model.add(TimeDistributedDense(nb_classes))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-5, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)
print("Train...")
model.fit([X_train, X_train], Y_train, batch_size=1, nb_Epoch=nb_epoches, validation_data=([X_test, X_test], Y_test), verbose=1, show_accuracy=True)
Im Vergleich zu LSTM
hat BLSTM
oder BiLSTM
zwei Netzwerke, ein Zugriff past
Information in forward
Richtung und ein weiterer Zugriff future
in der reverse
Richtung. wiki
Eine neue Klasse Bidirectional
wird gemäß dem offiziellen Dokument hier hinzugefügt: https://www.tensorflow.org/api_docs/python/tf/keras/layers/Bidirectional
model = Sequential()
model.add(Bidirectional(LSTM(10, return_sequences=True), input_shape=(5,
10)))
und Aktivierungsfunktion können wie folgt hinzugefügt werden:
model = Sequential()
model.add(Bidirectional(LSTM(num_channels,
implementation = 2, recurrent_activation = 'sigmoid'),
input_shape=(input_length, input_dim)))
Das vollständige Beispiel mit IMDB-Daten sieht so aus. Das Ergebnis nach 4 Epochen.
Downloading data from https://s3.amazonaws.com/text-datasets/imdb.npz
17465344/17464789 [==============================] - 4s 0us/step
Train...
Train on 25000 samples, validate on 25000 samples
Epoch 1/4
25000/25000 [==============================] - 78s 3ms/step - loss: 0.4219 - acc: 0.8033 - val_loss: 0.2992 - val_acc: 0.8732
Epoch 2/4
25000/25000 [==============================] - 82s 3ms/step - loss: 0.2315 - acc: 0.9106 - val_loss: 0.3183 - val_acc: 0.8664
Epoch 3/4
25000/25000 [==============================] - 91s 4ms/step - loss: 0.1802 - acc: 0.9338 - val_loss: 0.3645 - val_acc: 0.8568
Epoch 4/4
25000/25000 [==============================] - 92s 4ms/step - loss: 0.1398 - acc: 0.9509 - val_loss: 0.3562 - val_acc: 0.8606
BiLSTM oder [~ # ~] blstm [~ # ~]
import numpy as np
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Dropout, Embedding, LSTM, Bidirectional
from keras.datasets import imdb
n_unique_words = 10000 # cut texts after this number of words
maxlen = 200
batch_size = 128
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=n_unique_words)
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
y_train = np.array(y_train)
y_test = np.array(y_test)
model = Sequential()
model.add(Embedding(n_unique_words, 128, input_length=maxlen))
model.add(Bidirectional(LSTM(64)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print('Train...')
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=4,
validation_data=[x_test, y_test])
Ein weiterer Anwendungsfall für bidirektionales LSTM ist möglicherweise die Wortklassifizierung im Text. Sie können den vergangenen und zukünftigen Kontext des Wortes sehen und sind viel besser geeignet, das Wort zu klassifizieren.