65 lines
2.6 KiB
Python
65 lines
2.6 KiB
Python
from __future__ import absolute_import
|
|
from __future__ import print_function
|
|
import numpy as np
|
|
np.random.seed(1337) # for reproducibility
|
|
|
|
from keras.preprocessing import sequence
|
|
from keras.utils.np_utils import accuracy
|
|
from keras.models import Graph
|
|
from keras.layers.core import Dense, Dropout
|
|
from keras.layers.embeddings import Embedding
|
|
from keras.layers.recurrent import LSTM
|
|
from keras.datasets import imdb
|
|
|
|
'''
|
|
Train a Bidirectional LSTM on the IMDB sentiment classification task.
|
|
The dataset is actually too small for bidirectional LSTM to be of any advantage
|
|
compared to simpler, much faster methods such as TF-IDF+LogReg.
|
|
Bidirectional LSTM may be not suited for a simple text classification task.
|
|
Notes:
|
|
- RNNs are tricky. And in particular Bidirectional RNNs you may experiment
|
|
with different Recurrent layers and different parameters to find the best configuration
|
|
for your task.
|
|
|
|
GPU command:
|
|
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python imdb_bidirectional_lstm.py
|
|
|
|
Output after 4 epochs on CPU: ~0.8146
|
|
'''
|
|
|
|
max_features = 20000
|
|
maxlen = 100 # cut texts after this number of words (among top max_features most common words)
|
|
batch_size = 32
|
|
|
|
print("Loading data...")
|
|
(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features, test_split=0.2)
|
|
print(len(X_train), 'train sequences')
|
|
print(len(X_test), 'test sequences')
|
|
|
|
print("Pad sequences (samples x time)")
|
|
X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
|
|
X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
|
|
print('X_train shape:', X_train.shape)
|
|
print('X_test shape:', X_test.shape)
|
|
y_train = np.array(y_train)
|
|
y_test = np.array(y_test)
|
|
|
|
print('Build model...')
|
|
model = Graph()
|
|
model.add_input(name='input', input_shape=(1,), dtype=int)
|
|
model.add_node(Embedding(max_features, 128, input_length=maxlen), name='embedding', input='input')
|
|
model.add_node(LSTM(64), name='forward', input='embedding' ) # You can change these two layers with GRU
|
|
model.add_node(LSTM(64, go_backwards=True), name='backward', input='embedding' )
|
|
model.add_node(Dropout(0.5), name='dropout', inputs=['forward', 'backward'])
|
|
model.add_node(Dense(1, activation='sigmoid'), name='sigmoid', input='dropout')
|
|
model.add_output(name='output', input='sigmoid')
|
|
|
|
# try using different optimizers and different optimizer configs
|
|
model.compile('adam', {'output':'binary_crossentropy'})
|
|
|
|
print("Train...")
|
|
model.fit({'input':X_train, 'output':y_train}, batch_size=batch_size, nb_epoch=4)
|
|
acc = accuracy(y_test, np.round(np.array(model.predict({'input':X_test}, batch_size=batch_size)['output'])))
|
|
print('Test accuracy:', acc)
|
|
|