Luego de de esta prolongada selección de información resolvimos esta aprieto que presentan algunos de nuestros usuarios. Te ofrecemos la solución y esperamos serte de mucha apoyo.
Solución:
LSTM en su núcleo, conserva la información de las entradas que ya ha pasado a través de él utilizando el estado oculto.
LSTM unidireccional solo conserva la información del pasado porque las únicas entradas que ha visto son del pasado.
El uso bidireccional ejecutará sus entradas de dos maneras, una del pasado al futuro y otra del futuro al pasado, y lo que diferencia a este enfoque del unidireccional es que en el LSTM que se ejecuta hacia atrás se conserva la información del futuro y utilizando los dos estados ocultos combinados, puede en cualquier momento preservar la información de tanto pasado como futuro.
Para lo que son adecuados es una pregunta muy complicada, pero los BiLSTM muestran muy buenos resultados ya que pueden entender mejor el contexto, intentaré explicarlo con un ejemplo.
Digamos que intentamos predecir la siguiente palabra en una oración, en un nivel alto, lo que verá un LSTM unidireccional es
Los chicos fueron a …
E intentará predecir la siguiente palabra solo por este contexto, con LSTM bidireccional podrá ver información más adelante, por ejemplo
Adelante LSTM:
Los chicos fueron a …
LSTM hacia atrás:
… y luego salieron de la piscina
Puede ver que utilizando la información del futuro podría ser más fácil para la red entender cuál es la siguiente palabra.
Agregando a la respuesta de Bluesummer, así es como implementaría Bidirectional LSTM desde cero sin llamar BiLSTM
módulo. Esto podría contrastar mejor la diferencia entre un LSTM unidireccional y bidireccional. Como puede ver, fusionamos dos LSTM para crear un LSTM bidireccional.
Puede fusionar las salidas de los LSTM hacia adelante y hacia atrás mediante el uso de '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)
En comparación con LSTM
, BLSTM
o BiLSTM
tiene dos redes, un acceso past
información en forward
dirección y otro acceso future
en el reverse
dirección. wiki
Una nueva clase Bidirectional
se agrega según el documento oficial aquí: 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)))
y la función de activación se puede agregar así:
model = Sequential()
model.add(Bidirectional(LSTM(num_channels,
implementation = 2, recurrent_activation = 'sigmoid'),
input_shape=(input_length, input_dim)))
El ejemplo completo usando datos IMDB será así. El resultado después de 4 épocas.
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 o 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])
Recuerda algo, que tienes la capacidad de añadir una estimación si te fue de ayuda.