In this example, we are going to see how to recognize handwritten digits using Keras. The mnist_keras_training.py script creates the model using a four-layer neural network, as demonstrated in the following code snippet:
def create_model():
"""Create the model using Sequencial model"""
# Create a sequential model (a simple NN is created) adding a softmax activation at the end with 10 units:
model = Sequential()
model.add(Dense(units=128, activation="relu", input_shape=(784,)))
model.add(Dense(units=128, activation="relu"))
model.add(Dense(units=128, activation="relu"))
model.add(Dense(units=10, activation="softmax"))
# Compile the model using the loss function "categorical_crossentropy" and Stocastic Gradient Descent optimizer:
model.compile(optimizer=SGD(0.001), loss="categorical_crossentropy", metrics=["accuracy"])
# Return the created model
return model
In this case, we have compiled the model using the categorical_crossentropy loss function, which is a loss function well-suited for comparing two probability distributions and using the stochastic gradient descent (GSD) optimizer.
To load the MNIST data, we have to use the following code:
(train_x, train_y), (test_x, test_y) = mnist.load_data()
Additionally, we have to reshape the loaded data to have the proper shape as follows:
train_x = train_x.reshape(60000, 784)
test_x = test_x.reshape(10000, 784)
train_y = keras.utils.to_categorical(train_y, 10)
test_y = keras.utils.to_categorical(test_y, 10)
At this point, we can create the model, train the model, save the created model, and also get the accuracy obtained when evaluating the testing data as follows:
# Create the model:
model = create_model()
# Use the created model for training:
model.fit(train_x, train_y, batch_size=32, epochs=10, verbose=1)
# Save the created model:
model.save("mnist-model.h5")
# Get the accuracy when testing:
accuracy = model.evaluate(x=test_x, y=test_y, batch_size=32)
# Show the accuracy:
print("Accuracy: ", accuracy[1])
At this point, we are ready to use the pre-trained model for predicting new handwritten digits in images. This is performed in the mnist_keras_predicting.py script as follows:
# Note: Images should have black background:
def load_digit(image_name):
"""Loads a digit and pre-process in order to have the proper format"""
gray = cv2.imread(image_name, cv2.IMREAD_GRAYSCALE)
gray = cv2.resize(gray, (28, 28))
gray = gray.reshape((1, 784))
return gray
# Create the model:
model = create_model()
# Load parameters of the model from the saved mode file:
model.load_weights("mnist-model.h5")
# Load some test images:
test_digit_0 = load_digit("digit_0.png")
test_digit_1 = load_digit("digit_1.png")
test_digit_2 = load_digit("digit_2.png")
test_digit_3 = load_digit("digit_3.png")
imgs = np.array([test_digit_0, test_digit_1, test_digit_2, test_digit_3])
imgs = imgs.reshape(4, 784)
# Predict the class of the loaded images
prediction_class = model.predict_classes(imgs)
# Print the predicted classes:
print("Class: ", prediction_class)
As you can see, we have loaded four images and we have used the trained model to predict the class of these images. The output obtained is the following:
Class: [0 1 2 3]