Может кто-нибудь объяснить это? Я знаю, что двунаправленные LSTM имеют передний и задний проход, но каково преимущество этого в однонаправленном LSTM?
Для каждого из них лучше подходит?
Может кто-нибудь объяснить это? Я знаю, что двунаправленные LSTM имеют передний и задний проход, но каково преимущество этого в однонаправленном LSTM?
Для каждого из них лучше подходит?
LSTM в своем ядре сохраняет информацию от входов, которые уже прошли через него, используя скрытое состояние.
Однонаправленный LSTM сохраняет информацию только прошлой, потому что единственные входы, которые он видел, из прошлого.
Использование двунаправленного будет запускать ваши входы двумя способами: от прошлого к будущему и от будущего к прошлому, а другой - от однонаправленного - это то, что в LSTM, который работает в обратном направлении, вы сохраняете информацию из будущего и используя два скрытых состояния, вы можете в любой момент сохранить информацию из как прошлой, так и будущей.
Для них очень сложный вопрос, но BiLSTM показывают очень хорошие результаты, поскольку они лучше понимают контекст, я попытаюсь объяснить на примере.
Предположим, что мы пытаемся предсказать следующее слово в предложении, на высоком уровне, что увидит однонаправленный LSTM,
Мальчики пошли....
И попытается предсказать следующее слово только в этом контексте, с двунаправленным LSTM вы сможете увидеть информацию дальше по дороге, например
Переслать LSTM:
Мальчики пошли...
Назад LSTM:
... и затем они вышли из пула
Вы можете видеть, что использование информации из будущего может быть проще для сети понять, что такое следующее слово.
Добавляя к ответу Bluesummer, вот как вы могли бы реализовать двунаправленный LSTM с нуля без вызова модуля BiLSTM
. Это может лучше противопоставить различие между однонаправленными и двунаправленными LSTM. Как вы видите, мы объединяем два LSTM для создания двунаправленного LSTM.
Вы можете объединять выходные данные LSTM в прямом и обратном направлении, используя {'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)
Другой вариант использования двунаправленного LSTM может быть для классификации слов в тексте. Они могут видеть прошлый и будущий контекст этого слова и гораздо лучше подходят для классификации слова.
По сравнению с LSTM
, BLSTM
или BiLSTM
имеет две сети: один доступ к past
информации в forward
направлении и другое future
доступа в reverse
направлении. вики
Новый класс Bidirectional
добавляется в соответствии с официальным документом здесь: https://www.tensorflow.org/api_docs/python/tf/keras/layers/Bipirectional
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])