In [0]:
# Based on
# https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/6.2-understanding-recurrent-neural-networks.ipynb

In [0]:
import warnings
warnings.filterwarnings('ignore')

In [3]:
%matplotlib inline
%pylab inline


Populating the interactive namespace from numpy and matplotlib

In [5]:
import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)
print(tf.__version__)


1.11.0-rc2

In [6]:
# let's see what compute devices we have available, hopefully a GPU 
sess = tf.Session()
devices = sess.list_devices()
for d in devices:
    print(d.name)


/job:localhost/replica:0/task:0/device:CPU:0
/job:localhost/replica:0/task:0/device:GPU:0

In [7]:
# a small sanity check, does tf seem to work ok?
hello = tf.constant('Hello TF!')
print(sess.run(hello))


b'Hello TF!'

In [8]:
from tensorflow import keras
print(keras.__version__)


2.1.6-tf

In [9]:
# https://keras.io/datasets/#imdb-movie-reviews-sentiment-classification
max_features = 10000  # number of words to consider as features
maxlen = 500  # cut texts after this number of words (among top max_features most common words)

# each review is encoded as a sequence of word indexes
# indexed by overall frequency in the dataset
# output is 0 (negative) or 1 (positive) 
imdb = tf.keras.datasets.imdb.load_data(num_words=max_features)
(raw_input_train, y_train), (raw_input_test, y_test) = imdb


Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb.npz
17465344/17464789 [==============================] - 0s 0us/step

In [0]:
# https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/sequence/pad_sequences

input_train = tf.keras.preprocessing.sequence.pad_sequences(raw_input_train, maxlen=maxlen)
input_test = tf.keras.preprocessing.sequence.pad_sequences(raw_input_test, maxlen=maxlen)

In [11]:
input_train.shape, input_test.shape, y_train.shape, y_test.shape


Out[11]:
((25000, 500), (25000, 500), (25000,), (25000,))

In [0]:
# tf.keras.layers.SimpleRNN?
# tf.keras.layers.Embedding?

In [13]:
embedding_dim = 32

model = tf.keras.Sequential()
# Parameters: max_features (10000) * 8 = 80000 
model.add(tf.keras.layers.Embedding(name='embedding', input_dim=max_features, output_dim=embedding_dim, input_length=maxlen))

# model.add(tf.keras.layers.Embedding(max_features, 32, input_length=maxlen))
# model.add(tf.keras.layers.SimpleRNN(32, return_sequences=True))
# model.add(tf.keras.layers.SimpleRNN(32, return_sequences=True))

# https://arxiv.org/ftp/arxiv/papers/1701/1701.05923.pdf
# n = output dimension
# m = input dimension
# Total number of parameters for 
# RNN = n**2 + nm (like fc) + n (bias)

# n = 1, m =32: 1 + 32 + 1 = 34
# model.add(tf.keras.layers.SimpleRNN(name='rnn', units=1))

# n = 32, m =32: 1024 + 1024 + 32 = 2080
model.add(tf.keras.layers.SimpleRNN(name='rnn1', units=32, return_sequences=True))
model.add(tf.keras.layers.SimpleRNN(name='rnn2', units=32))

# Input format: maxlen (500) * dimension of embedding (8)
# Output: 4000
# model.add(tf.keras.layers.Flatten())

# binary classifier
model.add(tf.keras.layers.Dense(name='fc', units=32, activation='relu'))
model.add(tf.keras.layers.Dense(name='classifier', units=1, activation='sigmoid'))

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

model.summary()


_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, 500, 32)           320000    
_________________________________________________________________
rnn1 (SimpleRNN)             (None, 500, 32)           2080      
_________________________________________________________________
rnn2 (SimpleRNN)             (None, 32)                2080      
_________________________________________________________________
fc (Dense)                   (None, 32)                1056      
_________________________________________________________________
classifier (Dense)           (None, 1)                 33        
=================================================================
Total params: 325,249
Trainable params: 325,249
Non-trainable params: 0
_________________________________________________________________

In [14]:
batch_size = 1000

%time history = model.fit(input_train, y_train, epochs=10, batch_size=batch_size, validation_split=0.2)


Train on 20000 samples, validate on 5000 samples
Epoch 1/20
20000/20000 [==============================] - 21s 1ms/step - loss: 0.6722 - acc: 0.5729 - val_loss: 0.6013 - val_acc: 0.6834
Epoch 2/20
20000/20000 [==============================] - 20s 995us/step - loss: 0.4886 - acc: 0.7735 - val_loss: 0.4873 - val_acc: 0.7816
Epoch 3/20
20000/20000 [==============================] - 20s 994us/step - loss: 0.3994 - acc: 0.8329 - val_loss: 0.4597 - val_acc: 0.7806
Epoch 4/20
20000/20000 [==============================] - 20s 992us/step - loss: 0.2939 - acc: 0.8848 - val_loss: 0.3613 - val_acc: 0.8458
Epoch 5/20
20000/20000 [==============================] - 20s 993us/step - loss: 0.2562 - acc: 0.9037 - val_loss: 0.4195 - val_acc: 0.8382
Epoch 6/20
20000/20000 [==============================] - 20s 989us/step - loss: 0.2613 - acc: 0.8954 - val_loss: 0.4429 - val_acc: 0.8286
Epoch 7/20
20000/20000 [==============================] - 20s 986us/step - loss: 0.1527 - acc: 0.9459 - val_loss: 0.4025 - val_acc: 0.8492
Epoch 8/20
20000/20000 [==============================] - 20s 1ms/step - loss: 0.0946 - acc: 0.9707 - val_loss: 0.4567 - val_acc: 0.8310
Epoch 9/20
20000/20000 [==============================] - 20s 1ms/step - loss: 0.0539 - acc: 0.9871 - val_loss: 0.5133 - val_acc: 0.8406
Epoch 10/20
20000/20000 [==============================] - 20s 995us/step - loss: 0.0267 - acc: 0.9957 - val_loss: 0.5861 - val_acc: 0.8304
Epoch 11/20
20000/20000 [==============================] - 20s 992us/step - loss: 0.0146 - acc: 0.9979 - val_loss: 0.6382 - val_acc: 0.8358
Epoch 12/20
20000/20000 [==============================] - 20s 989us/step - loss: 0.0090 - acc: 0.9988 - val_loss: 0.6927 - val_acc: 0.8364
Epoch 13/20
20000/20000 [==============================] - 20s 989us/step - loss: 0.0063 - acc: 0.9993 - val_loss: 0.7212 - val_acc: 0.8274
Epoch 14/20
20000/20000 [==============================] - 20s 990us/step - loss: 0.0047 - acc: 0.9995 - val_loss: 0.7581 - val_acc: 0.8298
Epoch 15/20
20000/20000 [==============================] - 20s 986us/step - loss: 0.0037 - acc: 0.9996 - val_loss: 0.7752 - val_acc: 0.8306
Epoch 16/20
20000/20000 [==============================] - 20s 993us/step - loss: 0.0027 - acc: 0.9998 - val_loss: 0.8037 - val_acc: 0.8324
Epoch 17/20
20000/20000 [==============================] - 20s 990us/step - loss: 0.0023 - acc: 0.9998 - val_loss: 0.8221 - val_acc: 0.8306
Epoch 18/20
20000/20000 [==============================] - 20s 986us/step - loss: 0.0020 - acc: 0.9998 - val_loss: 0.8404 - val_acc: 0.8326
Epoch 19/20
20000/20000 [==============================] - 20s 990us/step - loss: 0.0017 - acc: 0.9999 - val_loss: 0.8492 - val_acc: 0.8312
Epoch 20/20
20000/20000 [==============================] - 20s 989us/step - loss: 0.0014 - acc: 0.9999 - val_loss: 0.8663 - val_acc: 0.8324
CPU times: user 9min 12s, sys: 1min 6s, total: 10min 19s
Wall time: 6min 38s

In [15]:
train_loss, train_accuracy = model.evaluate(input_train, y_train, batch_size=batch_size)
train_accuracy


25000/25000 [==============================] - 11s 445us/step
Out[15]:
0.9664000010490418

In [16]:
test_loss, test_accuracy = model.evaluate(input_test, y_test, batch_size=batch_size)
test_accuracy


25000/25000 [==============================] - 11s 447us/step
Out[16]:
0.8283200025558471

In [17]:
# precition
model.predict(input_test[0:5])


Out[17]:
array([[0.99797887],
       [0.9990243 ],
       [0.9998246 ],
       [0.06395195],
       [0.9996427 ]], dtype=float32)

In [18]:
# ground truth
y_test[0:5]


Out[18]:
array([0, 1, 1, 0, 1])

In [0]: