diff --git a/keras/6.2-understanding-recurrent-neural-networks.ipynb b/keras/6.2-understanding-recurrent-neural-networks.ipynb new file mode 100644 index 0000000..5b19bf2 --- /dev/null +++ b/keras/6.2-understanding-recurrent-neural-networks.ipynb @@ -0,0 +1,441 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First of all, set environment variables and initialize spark context:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "env: SPARK_DRIVER_MEMORY=16g\n", + "env: PYSPARK_PYTHON=/usr/bin/python3.5\n", + "env: PYSPARK_DRIVER_PYTHON=/usr/bin/python3.5\n", + "Prepending /home/litchy/.local/lib/python3.5/site-packages/bigdl/share/conf/spark-bigdl.conf to sys.path\n" + ] + } + ], + "source": [ + "%env SPARK_DRIVER_MEMORY=16g\n", + "%env PYSPARK_PYTHON=/usr/bin/python3.5\n", + "%env PYSPARK_DRIVER_PYTHON=/usr/bin/python3.5\n", + "\n", + "from zoo.common.nncontext import *\n", + "sc = init_nncontext(init_spark_conf().setMaster(\"local[4]\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Understanding recurrent neural networks\n", + "\n", + "----\n", + "\n", + "In this section we will build recurrent neural networks to finish the same task as we did in chapter 3." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## A first recurrent layer in Keras API of Analytics Zoo\n", + "\n", + "The process we just naively implemented in Numpy corresponds to an actual layer: the `SimpleRNN` layer:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from zoo.pipeline.api.keras.layers import SimpleRNN" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is just one minor difference: `SimpleRNN` processes batches of sequences, like all other Keras API of Analytics Zoo layers, not just a single sequence like \n", + "in our Numpy example. This means that it takes inputs of shape `(batch_size, timesteps, input_features)`, rather than `(timesteps, \n", + "input_features)`.\n", + "\n", + "Like all recurrent layers in Keras API of Analytics Zoo, `SimpleRNN` can be run in two different modes: it can return either the full sequences of successive \n", + "outputs for each timestep (a 3D tensor of shape `(batch_size, timesteps, output_features)`), or it can return only the last output for each \n", + "input sequence (a 2D tensor of shape `(batch_size, output_features)`). These two modes are controlled by the `return_sequences` constructor \n", + "argument. Let's take a look at an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from zoo.pipeline.api.keras.models import Sequential\n", + "from zoo.pipeline.api.keras.layers import Embedding, SimpleRNN" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Following is the preprocessing method. You do not need to care about the detail of its implementation. Basically this `pad_sequences` method fix all the sequences to a same length." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "def pad_sequences(sequences, maxlen=None, dtype='int32',\n", + " padding='pre', truncating='pre', value=0.): \n", + " lengths = [len(s) for s in sequences]\n", + "\n", + " nb_samples = len(sequences)\n", + " if maxlen is None:\n", + " maxlen = np.max(lengths)\n", + "\n", + " # take the sample shape from the first non empty sequence\n", + " # checking for consistency in the main loop below.\n", + " sample_shape = tuple()\n", + " for s in sequences:\n", + " if len(s) > 0:\n", + " sample_shape = np.asarray(s).shape[1:]\n", + " break\n", + "\n", + " x = (np.ones((nb_samples, maxlen) + sample_shape) * value).astype(dtype)\n", + " for idx, s in enumerate(sequences):\n", + " if not len(s):\n", + " continue # empty list/array was found\n", + " if truncating == 'pre':\n", + " trunc = s[-maxlen:]\n", + " elif truncating == 'post':\n", + " trunc = s[:maxlen]\n", + " else:\n", + " raise ValueError('Truncating type \"%s\" not understood' % truncating)\n", + "\n", + " # check `trunc` has expected shape\n", + " trunc = np.asarray(trunc, dtype=dtype)\n", + " if trunc.shape[1:] != sample_shape:\n", + " raise ValueError('Shape of sample %s of sequence at position %s is different from expected shape %s' %\n", + " (trunc.shape[1:], idx, sample_shape))\n", + "\n", + " if padding == 'post':\n", + " x[idx, :len(trunc)] = trunc\n", + " elif padding == 'pre':\n", + " x[idx, -len(trunc):] = trunc\n", + " else:\n", + " raise ValueError('Padding type \"%s\" not understood' % padding)\n", + " return x" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's try to use such a model on the IMDB movie review classification problem. First, let's preprocess the data. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "input_train shape: (25000, 500)\n", + "input_test shape: (25000, 500)\n" + ] + } + ], + "source": [ + "from zoo.pipeline.api.keras.datasets import imdb\n", + "\n", + "max_features = 10000 # number of words to consider as features\n", + "maxlen = 500 # cut texts after this number of words (among top max_features most common words)\n", + "batch_size = 32\n", + "\n", + "(input_train, y_train), (input_test, y_test) = imdb.load_data(nb_words=max_features)\n", + "input_train = pad_sequences(input_train, maxlen=maxlen)\n", + "input_test = pad_sequences(input_test, maxlen=maxlen)\n", + "print('input_train shape:', input_train.shape)\n", + "print('input_test shape:', input_test.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is sometimes useful to stack several recurrent layers one after the other in order to increase the representational power of a network. \n", + "In such a setup, you have to get all intermediate layers to return full sequences:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Specify input shape\n", + "_One could add an embedding layer as our first layer in Keras as following:_\n", + " \n", + " model = Sequential()\n", + " model.add(Embedding(10000, 32))\n", + "_In Keras API of Analytics Zoo, you need to specify the input shape of first layer, in this example, the sequence length is 500, as is shown above, so we could build our model as following:_" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "creating: createZooKerasSequential\n", + "creating: createZooKerasEmbedding\n", + "creating: createZooKerasSimpleRNN\n", + "creating: createZooKerasSimpleRNN\n", + "creating: createZooKerasSimpleRNN\n", + "creating: createZooKerasSimpleRNN\n" + ] + } + ], + "source": [ + "model = Sequential()\n", + "model.add(Embedding(10000, 32, input_shape=(500,)))\n", + "model.add(SimpleRNN(32, return_sequences=True))\n", + "model.add(SimpleRNN(32, return_sequences=True))\n", + "model.add(SimpleRNN(32, return_sequences=True))\n", + "model.add(SimpleRNN(32)) # This last layer only returns the last outputs.\n", + "model.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's train a simple recurrent network using an `Embedding` layer and a `SimpleRNN` layer:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "creating: createZooKerasSequential\n", + "creating: createZooKerasEmbedding\n", + "creating: createZooKerasSimpleRNN\n", + "creating: createZooKerasDense\n", + "creating: createRMSprop\n", + "creating: createZooKerasBinaryCrossEntropy\n", + "creating: createZooKerasBinaryAccuracy\n" + ] + } + ], + "source": [ + "from zoo.pipeline.api.keras.layers import Dense\n", + "\n", + "model = Sequential()\n", + "model.add(Embedding(max_features, 32, input_shape=(500,)))\n", + "model.add(SimpleRNN(32))\n", + "model.add(Dense(1, activation='sigmoid'))\n", + "\n", + "model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])\n", + "\n", + "import time\n", + "dir_name = '6-2 ' + str(time.ctime())\n", + "model.set_tensorboard('./', dir_name)\n", + "model.fit(input_train, y_train,\n", + " nb_epoch=10,\n", + " batch_size=128,\n", + " validation_split=0.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_INFO - Trained 128 records in 0.046239497 seconds. Throughput is 2768.1963 records/second. Loss is 0.16970885.\n", + "\n", + "Top1Accuracy is Accuracy(correct: 4167, count: 5000, accuracy: 0.8334)_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's display the training and validation loss:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "train_loss = np.array(model.get_train_summary('Loss'))\n", + "val_loss = np.array(model.get_validation_summary('Loss'))\n", + "\n", + "import matplotlib.pyplot as plt\n", + "plt.plot(train_loss[:,0],train_loss[:,1],label='train loss')\n", + "plt.plot(val_loss[:,0],val_loss[:,1],label='validation loss',color='green')\n", + "plt.xlabel('Steps')\n", + "plt.ylabel('Loss')\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As a reminder, in chapter 3, our very first naive approach to this very dataset got us to 88% test accuracy. Unfortunately, our small \n", + "recurrent network doesn't perform very well at all compared to this baseline (only up to 85% validation accuracy). Part of the problem is \n", + "that our inputs only consider the first 500 words rather the full sequences -- \n", + "hence our RNN has access to less information than our earlier baseline model. The remainder of the problem is simply that `SimpleRNN` isn't very good at processing long sequences, like text. Other types of recurrent layers perform much better. Let's take a look at some \n", + "more advanced layers." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## A concrete LSTM example in Keras API of Analytics Zoo\n", + "\n", + "Now let's switch to more practical concerns: we will set up a model using a LSTM layer and train it on the IMDB data. Here's the network, \n", + "similar to the one with `SimpleRNN` that we just presented. We only specify the output dimensionality of the LSTM layer, and leave every \n", + "other argument (there are lots) to the Keras API of Analytics Zoo defaults, which has good defaults, and things will almost always \"just work\" without you \n", + "having to spend time tuning parameters by hand." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "creating: createZooKerasSequential\n", + "creating: createZooKerasEmbedding\n", + "creating: createZooKerasLSTM\n", + "creating: createZooKerasDense\n", + "creating: createRMSprop\n", + "creating: createZooKerasBinaryCrossEntropy\n", + "creating: createZooKerasBinaryAccuracy\n" + ] + } + ], + "source": [ + "from zoo.pipeline.api.keras.layers import LSTM\n", + "\n", + "model = Sequential()\n", + "model.add(Embedding(max_features, 32, input_shape=(500,)))\n", + "model.add(LSTM(32))\n", + "model.add(Dense(1, activation='sigmoid'))\n", + "\n", + "model.compile(optimizer='rmsprop',\n", + " loss='binary_crossentropy',\n", + " metrics=['acc'])\n", + "\n", + "dir_name = '6-2 ' + str(time.ctime())\n", + "model.set_tensorboard('./', dir_name)\n", + "model.fit(input_train, y_train,\n", + " nb_epoch=10,\n", + " batch_size=128,\n", + " validation_split=0.2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_INFO - Trained 128 records in 0.335889472 seconds. Throughput is 381.07776 records/second. Loss is 0.14791179.\n", + "\n", + "Top1Accuracy is Accuracy(correct: 4358, count: 5000, accuracy: 0.8716)_" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "train_loss = np.array(model.get_train_summary('Loss'))\n", + "val_loss = np.array(model.get_validation_summary('Loss'))\n", + "\n", + "plt.plot(train_loss[:,0],train_loss[:,1],label='train loss')\n", + "plt.plot(val_loss[:,0],val_loss[:,1],label='validation loss',color='green')\n", + "plt.xlabel('Steps')\n", + "plt.ylabel('Loss')\n", + "plt.legend()\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}