<jupyter_start><jupyter_text>IntroductionIn this example we create a classifier to recognize handwritten digits from the famous mnist dataset, using a convolutional neural network. Typically the training data is referred to as **X**, the training lables as **y**, and the test data and labesl as **X_test** and **y_test** respectively. Let's load the train/test data, and show one of the images with the help of the excellent matplotlib library:<jupyter_code>import keras.datasets as datasets

(X, y),  (X_test, y_test) = datasets.mnist.load_data()
digit = X[2]
plt.imshow(digit, cmap=plt.cm.binary)<jupyter_output>Using TensorFlow backend.<jupyter_text>Let's now define the network using convolutional layers. In this instance we used 3 convolutional layers with max pooling layers in between:<jupyter_code>from keras import models
from keras import layers


net = models.Sequential()
net.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
net.add(layers.MaxPool2D(2, 2))
net.add(layers.Conv2D(64, (3, 3), activation='relu'))
net.add(layers.MaxPool2D(2, 2))
net.add(layers.Conv2D(64, (3, 3), activation='relu'))<jupyter_output><empty_output><jupyter_text>In order to predict the number each image represents we use a couple of dense layers, but before we need to flatten the matrix coming from the last convolutional layer into a vector:<jupyter_code>net.add(layers.Flatten())
net.add(layers.Dense(64, activation='relu'))
net.add(layers.Dense(10, activation='softmax'))<jupyter_output><empty_output><jupyter_text>Finally let's compile the network with an appropriate optimizer, loss and performance metric:<jupyter_code>net.compile(optimizer='rmsprop',
            loss='categorical_crossentropy',
            metrics=['accuracy'])<jupyter_output><empty_output><jupyter_text>And we are ready to train a model, but before we need to reshape and normalize the images, and apply **one-hot-encoding** to the labels.<jupyter_code>from keras.utils import to_categorical

# Reshape and normalize the images
X = X.reshape((len(X), 28, 28, 1)).astype('float32') / 255
X_test = X_test.reshape((len(X_test), 28, 28, 1)).astype('float32') / 255

# on-hot-encode the labels
y = to_categorical(y)
y_test = to_categorical(y_test)
net.fit(X, y, epochs=5, batch_size=64)<jupyter_output>Epoch 1/5
60000/60000 [==============================] - 29s 484us/step - loss: 0.1769 - acc: 0.9445
Epoch 2/5
60000/60000 [==============================] - 29s 483us/step - loss: 0.0497 - acc: 0.9847
Epoch 3/5
60000/60000 [==============================] - 29s 481us/step - loss: 0.0337 - acc: 0.9894
Epoch 4/5
60000/60000 [==============================] - 29s 483us/step - loss: 0.0260 - acc: 0.9919
Epoch 5/5
60000/60000 [==============================] - 29s 484us/step - loss: 0.0210 - acc: 0.9934<jupyter_text>Let's see how our model performs on the test dataset.<jupyter_code>net.evaluate(X_test, y_test)<jupyter_output>10000/10000 [==============================] - 2s 173us/step