redes recurrent neural network español machine-learning neural-network keras lstm recurrent-neural-network

machine learning - recurrent - ¿Cuál es la diferencia entre un LSTM bidireccional y un LSTM?



recurrent neural network (4)

¿Puede alguien por favor explicar esto? Sé que los LSTM bidireccionales tienen un pase hacia adelante y hacia atrás, pero ¿cuál es la ventaja de esto sobre un LSTM unidireccional?

¿Para qué es mejor cada uno de ellos?


En comparación con LSTM , BLSTM o BiLSTM tiene dos redes, una que accede past información past en la dirección de forward y otra a la que accede en el future . wiki

Se agrega una nueva clase Bidirectional 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 de esta manera:

model = Sequential() model.add(Bidirectional(LSTM(num_channels, implementation = 2, recurrent_activation = ''sigmoid''), input_shape=(input_length, input_dim)))

El ejemplo completo utilizando datos de 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])


LSTM en su núcleo, conserva la información de las entradas que ya han pasado a través de ella utilizando el estado oculto.

El LSTM unidireccional solo conserva la información del pasado porque las únicas entradas que ha visto son las 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 difiere de este enfoque de unidireccional es que en el LSTM que corre hacia atrás conserva la información del futuro y el uso de los dos estados ocultos que lo combinamos pueden en cualquier momento preservar la información tanto del pasado como del 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, trataré de explicarlo con un ejemplo.

Digamos que tratamos de predecir la siguiente palabra en una oración, en un nivel alto lo que verá un LSTM unidireccional

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.

LSTM hacia adelante:

Los chicos fueron a ...

LSTM hacia atrás:

... y luego salieron de la piscina

Puede ver que usar la información del futuro podría ser más fácil para la red entender cuál es la siguiente palabra.


Otro caso de uso de LSTM bidireccional podría ser la clasificación de palabras en el texto. Pueden ver el contexto pasado y futuro de la palabra y son mucho más adecuados para clasificar la palabra.


Agregando a la respuesta de Bluesummer, aquí es cómo implementaría Bidirectional LSTM desde cero sin llamar BiLSTM módulo BiLSTM . Esto podría contrastar mejor la diferencia entre un LSTM unidireccional y bidireccional. Como ve, fusionamos dos LSTM para crear un LSTM bidireccional.

Puede combinar las salidas de los LSTM hacia adelante y hacia atrás utilizando {''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)