双向 LSTM 和 LSTM 有什么区别?
What's the difference between a bidirectional LSTM and an LSTM?
有人可以解释一下吗?我知道双向 LSTM 有前向和后向传递,但它比单向 LSTM 有什么优势?
他们每个人更适合做什么?
LSTM 在其核心中使用隐藏状态保留来自已经通过它的输入的信息。
单向 LSTM 仅保留过去的信息,因为它看到的唯一输入来自过去。
使用双向将 运行 您以两种方式输入,一种是从过去到未来,一种是从未来到过去,这种方法与单向的不同之处在于,在 LSTM 中 运行 是倒退的您保留来自 未来 的信息,并结合使用两个隐藏状态,您可以在任何时间点保留来自 过去和未来 的信息。
它们适合的是一个非常复杂的问题,但是 BiLSTM 显示出非常好的结果,因为它们可以更好地理解上下文,我将尝试通过一个例子来解释。
假设我们尝试预测句子中的下一个词,在较高层次上,单向 LSTM 将看到的是
The boys went to ....
并且将尝试仅根据此上下文预测下一个单词,例如,使用双向 LSTM,您将能够看到更远的信息
正向 LSTM:
The boys went to ...
向后 LSTM:
... and then they got out of the pool
你可以看到,使用来自未来的信息,网络可以更容易地理解下一个词是什么。
双向 LSTM 的另一个用例可能是文本中的单词分类。他们可以看到单词的过去和未来上下文,更适合对单词进行分类。
添加到 Bluesummer 的答案中,这里是您如何在不调用 BiLSTM
模块的情况下从头开始实现双向 LSTM。这可能会更好地对比单向和双向 LSTM 之间的差异。如您所见,我们合并两个 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
有两个网络,一个访问past
forward
方向的信息,另一个访问[=19] =] 在 reverse
方向。 wiki
根据此处的官方文档添加了一个新的 class 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 数据的完整示例将类似于 this.The 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,但双向 LSTM 也会做得更好。
有人可以解释一下吗?我知道双向 LSTM 有前向和后向传递,但它比单向 LSTM 有什么优势?
他们每个人更适合做什么?
LSTM 在其核心中使用隐藏状态保留来自已经通过它的输入的信息。
单向 LSTM 仅保留过去的信息,因为它看到的唯一输入来自过去。
使用双向将 运行 您以两种方式输入,一种是从过去到未来,一种是从未来到过去,这种方法与单向的不同之处在于,在 LSTM 中 运行 是倒退的您保留来自 未来 的信息,并结合使用两个隐藏状态,您可以在任何时间点保留来自 过去和未来 的信息。
它们适合的是一个非常复杂的问题,但是 BiLSTM 显示出非常好的结果,因为它们可以更好地理解上下文,我将尝试通过一个例子来解释。
假设我们尝试预测句子中的下一个词,在较高层次上,单向 LSTM 将看到的是
The boys went to ....
并且将尝试仅根据此上下文预测下一个单词,例如,使用双向 LSTM,您将能够看到更远的信息
正向 LSTM:
The boys went to ...
向后 LSTM:
... and then they got out of the pool
你可以看到,使用来自未来的信息,网络可以更容易地理解下一个词是什么。
双向 LSTM 的另一个用例可能是文本中的单词分类。他们可以看到单词的过去和未来上下文,更适合对单词进行分类。
添加到 Bluesummer 的答案中,这里是您如何在不调用 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
相比,BLSTM
或BiLSTM
有两个网络,一个访问past
forward
方向的信息,另一个访问[=19] =] 在 reverse
方向。 wiki
根据此处的官方文档添加了一个新的 class 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 数据的完整示例将类似于 this.The 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,但双向 LSTM 也会做得更好。