誰かがこれを説明できますか?双方向LSTMにはフォワードパスとバックワードパスがあることを知っていますが、これは単方向LSTMと比べてどのような利点がありますか?
それぞれに適しているものは何ですか?
LSTMのコアでは、隠された状態を使用して既に通過した入力からの情報を保持します。
単方向LSTMは、pastの情報のみを保持します。これは、過去からの入力のみが表示されるためです。
双方向を使用すると、入力が2つの方法で実行されます。1つは過去から未来へ、もう1つは未来から過去へ、そしてこのアプローチと単方向との違いは、後方に実行されるLSTMではからの情報を保存することですfutureおよび2つの隠された状態を組み合わせて使用することで、過去と未来の両方から情報を保存することができます。
それらが適しているのは非常に複雑な質問ですが、BiLSTMはコンテキストをよりよく理解できるため、非常に良い結果を示します。例を挙げて説明します。
文の次の単語を予測しようとするとしましょう。高レベルで、単方向LSTMに表示されるのは
少年たちは...に行きました.
そして、このコンテキストだけで次の単語を予測しようとします。双方向LSTMを使用すると、たとえば、さらに先の情報を見ることができます
フォワードLSTM:
少年たちはに行きました...
後方LSTM:
...そして彼らはプールから出ました
将来の情報を使用すると、ネットワークが次のWordが何であるかを理解しやすくなることがわかります。
Bluesummerの答えに加えて、ここではBiLSTM
モジュールを呼び出さずにゼロから双方向LSTMを実装する方法を示します。これにより、単方向LSTMと双方向LSTMの違いをより明確に比較できます。ご覧のとおり、2つのLSTMをマージして、双方向LSTMを作成します。
{'sum', 'mul', 'concat', 'ave'}
を使用して、前方および後方LSTMの出力をマージできます。
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)
LSTM
と比較して、BLSTM
またはBiLSTM
には2つのネットワークがあり、1つはpast
方向のforward
informationにアクセスし、もう1つはfuture
方向のreverse
にアクセスします。 wiki
新しいクラスBidirectional
がここの公式ドキュメントに従って追加されます: 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)))
アクティベーション機能は次のように追加できます。
model = Sequential()
model.add(Bidirectional(LSTM(num_channels,
implementation = 2, recurrent_activation = 'sigmoid'),
input_shape=(input_length, input_dim)))
IMDBデータを使用した完全な例は次のようになります。4エポック後の結果。
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または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])
双方向LSTMの別の使用例は、テキスト内のWord分類です。彼らは過去と未来の言葉の文脈を見ることができ、言葉を分類するのにより適しています。