Deep Learning Project – Handwritten Digit Recognition using Python

Free Machine Learning courses with 130+ real-time projects Start Now!!

Python Deep Learning Project

To make machines more intelligent, the developers are diving into machine learning and deep learning techniques. A human learns to perform a task by practicing and repeating it again and again so that it memorizes how to perform the tasks. Then the neurons in his brain automatically trigger and they can quickly perform the task they have learned. Deep learning is also very similar to this. It uses different types of neural network architectures for different types of problems. For example – object recognition, image and sound classification, object detection, image segmentation, etc.

This is the 11th project in the DataFlair’s series of 20 Python projects. I suggest you to bookmark the previous projects:

  1. Fake News Detection Python Project 
  2. Parkinson’s Disease Detection Python Project 
  3. Color Detection Python Project
  4. Speech Emotion Recognition Python Project 
  5. Breast Cancer Classification Python Project
  6. Age and Gender Detection Python Project 
  7. Handwritten Digit Recognition Python Project
  8. Chatbot Python Project
  9. Driver Drowsiness Detection Python Project
  10. Traffic Signs Recognition Python Project
  11. Image Caption Generator Python Project

What is Handwritten Digit Recognition?

The handwritten digit recognition is the ability of computers to recognize human handwritten digits. It is a hard task for the machine because handwritten digits are not perfect and can be made with many different flavors. The handwritten digit recognition is the solution to this problem which uses the image of a digit and recognizes the digit present in the image.

About the Python Deep Learning Project

python deep learning project - handwritten digit recognition

In this article, we are going to implement a handwritten digit recognition app using the MNIST dataset. We will be using a special type of deep neural network that is Convolutional Neural Networks. In the end, we are going to build a GUI in which you can draw the digit and recognize it straight away.

Prerequisites

The interesting Python project requires you to have basic knowledge of Python programming, deep learning with Keras library and the Tkinter library for building GUI.

Install the necessary libraries for this project using this command:

pip install numpy, tensorflow, keras, pillow,

The MNIST dataset

This is probably one of the most popular datasets among machine learning and deep learning enthusiasts. The MNIST dataset contains 60,000 training images of handwritten digits from zero to nine and 10,000 images for testing. So, the MNIST dataset has 10 different classes. The handwritten digits images are represented as a 28×28 matrix where each cell contains grayscale pixel value.

Download the full source code for the project

Building Python Deep Learning Project on Handwritten Digit Recognition

Below are the steps to implement the handwritten digit recognition project:

1. Import the libraries and load the dataset

First, we are going to import all the modules that we are going to need for training our model. The Keras library already contains some datasets and MNIST is one of them. So we can easily import the dataset and start working with it. The mnist.load_data() method returns us the training data, its labels and also the testing data and its labels.

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

print(x_train.shape, y_train.shape)

2. Preprocess the data

The image data cannot be fed directly into the model so we need to perform some operations and process the data to make it ready for our neural network. The dimension of the training data is (60000,28,28). The CNN model will require one more dimension so we reshape the matrix to shape (60000,28,28,1).

x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

3. Create the model

Now we will create our CNN model in Python data science project. A CNN model generally consists of convolutional and pooling layers. It works better for data that are represented as grid structures, this is the reason why CNN works well for image classification problems. The dropout layer is used to deactivate some of the neurons and while training, it reduces offer fitting of the model. We will then compile the model with the Adadelta optimizer.

batch_size = 128
num_classes = 10
epochs = 10

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.Adadelta(),metrics=['accuracy'])

4. Train the model

The model.fit() function of Keras will start the training of the model. It takes the training data, validation data, epochs, and batch size.

It takes some time to train the model. After training, we save the weights and model definition in the ‘mnist.h5’ file.

hist = model.fit(x_train, y_train,batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(x_test, y_test))
print("The model has successfully trained")

model.save('mnist.h5')
print("Saving the model as mnist.h5")

5. Evaluate the model

We have 10,000 images in our dataset which will be used to evaluate how good our model works. The testing data was not involved in the training of the data therefore, it is new data for our model. The MNIST dataset is well balanced so we can get around 99% accuracy.

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

6. Create GUI to predict digits

Now for the GUI, we have created a new file in which we build an interactive window to draw digits on canvas and with a button, we can recognize the digit. The Tkinter library comes in the Python standard library. We have created a function predict_digit() that takes the image as input and then uses the trained model to predict the digit.

Then we create the App class which is responsible for building the GUI for our app. We create a canvas where we can draw by capturing the mouse event and with a button, we trigger the predict_digit() function and display the results.

Here’s the full code for our gui_digit_recognizer.py file:

from keras.models import load_model
from tkinter import *
import tkinter as tk
import win32gui
from PIL import ImageGrab, Image
import numpy as np

model = load_model('mnist.h5')

def predict_digit(img):
    #resize image to 28x28 pixels
    img = img.resize((28,28))
    #convert rgb to grayscale
    img = img.convert('L')
    img = np.array(img)
    #reshaping to support our model input and normalizing
    img = img.reshape(1,28,28,1)
    img = img/255.0
    #predicting the class
    res = model.predict([img])[0]
    return np.argmax(res), max(res)

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)

        self.x = self.y = 0

        # Creating elements
        self.canvas = tk.Canvas(self, width=300, height=300, bg = "white", cursor="cross")
        self.label = tk.Label(self, text="Thinking..", font=("Helvetica", 48))
        self.classify_btn = tk.Button(self, text = "Recognise", command =         self.classify_handwriting) 
        self.button_clear = tk.Button(self, text = "Clear", command = self.clear_all)

        # Grid structure
        self.canvas.grid(row=0, column=0, pady=2, sticky=W, )
        self.label.grid(row=0, column=1,pady=2, padx=2)
        self.classify_btn.grid(row=1, column=1, pady=2, padx=2)
        self.button_clear.grid(row=1, column=0, pady=2)

        #self.canvas.bind("<Motion>", self.start_pos)
        self.canvas.bind("<B1-Motion>", self.draw_lines)

    def clear_all(self):
        self.canvas.delete("all")

    def classify_handwriting(self):
        HWND = self.canvas.winfo_id() # get the handle of the canvas
        rect = win32gui.GetWindowRect(HWND) # get the coordinate of the canvas
        im = ImageGrab.grab(rect)

        digit, acc = predict_digit(im)
        self.label.configure(text= str(digit)+', '+ str(int(acc*100))+'%')

    def draw_lines(self, event):
        self.x = event.x
        self.y = event.y
        r=8
        self.canvas.create_oval(self.x-r, self.y-r, self.x + r, self.y + r, fill='black')

app = App()
mainloop()

Screenshots:

python machine learning project output as number 2

python machine learning project output as number 5

python project output as number 6

Summary

In this article, we have successfully built a Python deep learning project on handwritten digit recognition app. We have built and trained the Convolutional neural network which is very effective for image classification purposes. Later on, we build the GUI where we draw a digit on the canvas then we classify the digit and show the results.

Want to get hired as a Python expert? Practice the 150+ Python Interview Questions by DataFlair

Do share your views regarding the intermediate Python project in the comment section.

If you are Happy with DataFlair, do not forget to make us happy with your positive feedback on Google

follow dataflair on YouTube

163 Responses

  1. uzmah says:

    ModuleNotFoundError: No module named ‘keras’
    how to link that .h5 file in python

  2. kn187 says:

    Hi! Recently I downloaded your Handwritten Digit Recognition python project, but when I run it, it never recognizes digit correctly (f.e., when I draw a 6, it says that it’s a 2 with ~70% accuracy). I was wondering if anyone else had this problem, as I’m trying something similar for a college project, and if you know where the problem might be.

    Thanks in advance!

    • arjun says:

      same problem with me also
      go and search in GitHub for this project, I got it and it’s working fine for me

    • aslam says:

      try scaling your training data

    • Justin says:

      For anyone else, please read this!
      To put it simply, the image thats hand drawn (by you), is inverted, the training data has BG of black, and drawing of white, your drawing has BG of white and writing of black,

      Change import on line 5 to: from PIL import ImageGrab, ImageOps
      and function predict digit to:
      def predict_digit(img):
      #resize image to 28×28 pixels
      img = img.resize((28,28))
      #convert rgb to grayscale
      img = img.convert(‘L’)
      img = ImageOps.invert(img)
      img = np.array(img)
      #reshaping to support our model input and normalizing
      img = img.reshape(1,28,28,1)
      img = img/255.0
      #predicting the class
      res = model.predict([img])[0]
      return np.argmax(res), max(res)

      Basically adding 1 line of code on line 14/15, img = ImageOps.invert(img) this inverts the image

      Hope this helps!

  3. Bui Le Ngoc Min says:

    I have run this model, I very disapointed, this model can’t recognition exactly my handwrite :((((

  4. Bui Le Ngoc Min says:

    I find the problem, I add this line before predict: img = 1 – img
    It work very well

  5. Uzmah says:

    For every hand drawn digit it is showing zero no other digit.
    Plzz help to resolve tbis issue its important.

  6. Carina says:

    I have the seem issue with you, look forward the answer. If you have found the solution, could you please share with me?

  7. kn187 says:

    @Bui Le Ngoe Min hi, can you send me your solution. It still doesn’t work for me with “img = 1 – img”

  8. Allwyn Vincent says:

    Hello, I tried the source code, but when I ran the GUI part it gives an error saying “ModuleNotFoundError: No module named ‘win32gui’ “

    • Yogesh says:

      just use pip install pywin32

    • DataFlair says:

      You can install the pywin32 module to solve this issue. For this, you ca sue the command ‘pip install pywin32’. Hope this helps!

      • nugie says:

        Hello, I’m using Ubuntu 18.04, when I tried the “pip install pywin32” command I got the following error:

        ERROR: Could not find a version that satisfies the requirement pywin32 (from versions: none)
        ERROR: No matching distribution found for pywin32

        Any solution for this? Thanks a lot for a great tutorial!

  9. Vamsi Krishna says:

    it is always showing 2 with different accuracy values

  10. uzmah says:

    same issue

  11. uzmah says:

    please check like this we add this line …. it’s really urgent!!!!
    before this???

    img=1-img
    def predict_digit(img):
    #resize image to 28×28 pixels
    img = img.resize((28,28))
    #convert rgb to grayscale
    img = img.convert(‘L’)
    img = np.array(img)
    #reshaping to support our model input and normalizing
    img = img.reshape(1,28,28,1)
    img = img/255.0
    #predicting the class
    res = model.predict([img])[0]
    return np.argmax(res), max(res)

  12. Mamta says:

    Very good information.

  13. Ritika Budhiraja says:

    ModuleNotFoundError: No module named ‘keras’
    how to link that .h5 file in python
    Please tell me how to import the module, I am unable to run the code!!

    • Justin says:

      from tensorflow import keras
      from keras.datasets import mnist
      from keras.models import Sequential
      from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D

      all needed imports for training.py

  14. SHAFIN JUNAYED says:

    I am facing this error ” module ‘keras.utils.generic_utils’ has no attribute “. will anyone help me out?

  15. Nguyen Tuan Dat says:

    Why???
    “C:\Users\DAT_PC\anaconda3\envs\Handwritten digit recognizer\python.exe” “D:/Cong viec/Hoc tap/Hoc SPKTHY/Thay Hoan/4 Image Processing/Bai tap/Handwritten digit recognizer/train_digit_recognizer.py”
    (60000, 28, 28) (60000,)
    x_train shape: (60000, 28, 28, 1)
    60000 train samples
    10000 test samples
    2021-08-09 16:32:45.919014: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2
    To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
    2021-08-09 16:32:45.921326: I tensorflow/core/common_runtime/process_util.cc:146] Creating new thread pool with default inter op setting: 2. Tune using inter_op_parallelism_threads for best performance.
    2021-08-09 16:32:46.138644: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
    Epoch 1/10
    469/469 [==============================] – 28s 56ms/step – loss: 2.3054 – accuracy: 0.1000 – val_loss: 2.2957 – val_accuracy: 0.1011
    Epoch 2/10
    469/469 [==============================] – 26s 56ms/step – loss: 2.2952 – accuracy: 0.1102 – val_loss: 2.2854 – val_accuracy: 0.1017
    Epoch 3/10
    469/469 [==============================] – 31s 66ms/step – loss: 2.2861 – accuracy: 0.1230 – val_loss: 2.2750 – val_accuracy: 0.1052
    Epoch 4/10
    469/469 [==============================] – 30s 63ms/step – loss: 2.2764 – accuracy: 0.1369 – val_loss: 2.2639 – val_accuracy: 0.1136
    Epoch 5/10
    469/469 [==============================] – 27s 57ms/step – loss: 2.2667 – accuracy: 0.1486 – val_loss: 2.2518 – val_accuracy: 0.1296
    Epoch 6/10
    469/469 [==============================] – 27s 58ms/step – loss: 2.2557 – accuracy: 0.1612 – val_loss: 2.2382 – val_accuracy: 0.1483
    Epoch 7/10
    469/469 [==============================] – 26s 56ms/step – loss: 2.2435 – accuracy: 0.1764 – val_loss: 2.2231 – val_accuracy: 0.1685
    Epoch 8/10
    469/469 [==============================] – 27s 57ms/step – loss: 2.2302 – accuracy: 0.1907 – val_loss: 2.2059 – val_accuracy: 0.1919
    Epoch 9/10
    469/469 [==============================] – 26s 55ms/step – loss: 2.2156 – accuracy: 0.2042 – val_loss: 2.1867 – val_accuracy: 0.2298
    Epoch 10/10
    469/469 [==============================] – 26s 55ms/step – loss: 2.1998 – accuracy: 0.2178 – val_loss: 2.1653 – val_accuracy: 0.2797
    The model has successfully trained
    Test loss: 2.165282964706421
    Test accuracy: 0.27970001101493835
    Saving the model as mnist.h5

    Process finished with exit code 0

  16. Lukas says:

    AttributeError Traceback (most recent call last)
    in
    18
    19 # convert class vectors to binary class matrices
    —> 20 y_train = keras.utils.to_categorical(y_train, num_classes)
    21 y_test = keras.utils.to_categorical(y_test, num_classes)
    22

    AttributeError: module ‘keras.utils’ has no attribute ‘to_categorical’

    I am getting this error message, not sure how to fix. Can anyone help

    • DataFlair says:

      This problem might occurs in latest versions of Keras. To solve this problem, you can import using the line from keras.utils import np_utils or from keras import utils as np_utils. And then replace keras.utils.to_categorical with keras.utils.np_utils.to_categorical.

  17. Justin says:

    The code for opening the model is wrong!!!!

    def predict_digit(img):
    #resize image to 28×28 pixels
    img = img.resize((28,28))
    #convert rgb to grayscale
    img = img.convert(‘L’)
    img = ImageOps.invert(img)
    img = np.array(img)
    #reshaping to support our model input and normalizing
    img = img.reshape(1,28,28,1)
    img = img/255.0
    #predicting the class
    res = model.predict([img])[0]
    return np.argmax(res), max(res)

    Use this instead!!

    (Import statement) from PIL import ImageGrab, ImageOps

    Reason: The image is inverted, the black is white and the white is black, in the training data the writing is white, but in actual testing with real hand writing, the writing is black, which is confusing the neural network!

  18. Jens Nordmark says:

    Apart from the issue with inverting the image, the learning parameters differ significantly between the code in the Google drive repository and the text on this webpage. Check that out in order to get better results.

  19. tho says:

    should change the classify_handwriting method:
    def classify_handwriting(self):
    HWND = self.canvas.winfo_id() # get the handle of the canvas
    rect = win32gui.GetWindowRect(HWND) # get the coordinate of the canvas
    a,b,c,d = rect
    rect=(a+4,b+4,c+100,d+100)
    im = ImageGrab.grab(rect)

    digit, acc = predict_digit(im)
    self.label.configure(text= str(digit)+’, ‘+ str(int(acc*100))+’%’)

  20. nugie says:

    Hello, I’m using Ubuntu 18.04, when I tried the “pip install pywin32” command I got the following error:

    ERROR: Could not find a version that satisfies the requirement pywin32 (from versions: none)
    ERROR: No matching distribution found for pywin32

    Any solution for this? Thanks a lot for a great tutorial!

  21. Pankaj Sharma says:

    Could not find “from keras.optimizers import Adadelta” what should i do for this ?

  22. Prajanya Sahu says:

    what should i do

    AttributeError Traceback (most recent call last)
    d:\COSING VSC C\gp1.ipynb Cell 2′ in ()
    3 input_shape = (28, 28, 1)
    5 # convert class vectors to binary class matrices
    —-> 6 y_train = keras.utils.to_categorical(y_train, num_classes)
    7 y_test = keras.utils.to_categorical(y_test, num_classes)
    9 x_train = x_train.astype(‘float32’)

    AttributeError: module ‘keras.utils’ has no attribute ‘to_categorical’

  23. Owais Imtiyaz Mirajkar says:

    This should work put this at the start in train_digit
    ” import tensorflow as tf
    from tensorflow import keras “

  24. vijay says:

    I am getting just display…with clear and recognize command. not even space for drawing…Just tk diaply is opening .

    I have no errors, but still not getting output.

    shows msg like this in the end:
    2022-05-01 16:12:57.705049: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX AVX2
    To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.

    Pls someone help in solving this.

    tried on Visual studio code.

  25. vishwajeet says:

    error showing win32gui is not run

  26. SIROJIDDIN says:

    GUI PACKAGE IS NOT INSTALLED
    PLEASE HELP
    HOW TO INSTALL

  27. dineshgupta says:

    Hi All,

    I am running the provided sample on the Oracle Linux8 server & I am getting the below issue

    `(.venv) [dinesh@localhost handwritten-digit-recognition]$ /home/dinesh/pythonp/.venv/bin/python /home/dinesh/pythonp/handwritten-digit-recognition/gui-digit-recognizer.py
    2022-05-28 21:08:26.460381: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘libcudart.so.11.0’; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory
    2022-05-28 21:08:26.460414: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
    Traceback (most recent call last):
    File “/home/dinesh/pythonp/handwritten-digit-recognition/gui-digit-recognizer.py”, line 2, in
    from tkinter import *
    ModuleNotFoundError: No module named ‘tkinter’`

    Please help me on this

  28. Mohan das says:

    I’m getting this NameError on line no 6 of Preprocess the data;
    num_classes is not defined

    could someone help me over this please

  29. adarsh srivastava says:

    No file or directory found at mnist.h5

    how to fix this problem?

  30. Smriti Upadhyay says:

    hey which algorithm is used here?

Leave a Reply

Your email address will not be published. Required fields are marked *