0% found this document useful (0 votes)
2 views

vertopal.com_HandWritten

Uploaded by

Suseela Devi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

vertopal.com_HandWritten

Uploaded by

Suseela Devi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

import numpy as np

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D,
Flatten, Dropout
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical

# Load MNIST dataset


(x_train_mnist, y_train_mnist), (x_test_mnist, y_test_mnist) =
mnist.load_data()

# Preprocess MNIST data


x_train_mnist = x_train_mnist.reshape(x_train_mnist.shape[0], 28, 28,
1).astype('float32') / 255
x_test_mnist = x_test_mnist.reshape(x_test_mnist.shape[0], 28, 28,
1).astype('float32') / 255
y_train_mnist = to_categorical(y_train_mnist, 10)
y_test_mnist = to_categorical(y_test_mnist, 10)

# Load A-Z dataset (assuming it's saved as a CSV file)


az_dataset = pd.read_csv('A_Z Handwritten Data.csv', header=None) #
Assuming no header in CSV file

# Separate features and labels


X_az = az_dataset.drop(0, axis=1).values.astype('float32') / 255 #
Drop column '0' as label
y_az = az_dataset[0].values # Use column '0' as label

# Convert labels to categorical one-hot encoding


label_bin = LabelBinarizer()
y_az = label_bin.fit_transform(y_az)

# Split the data into training and testing sets


x_train_az, x_test_az, y_train_az, y_test_az = train_test_split(X_az,
y_az, test_size=0.2, random_state=42)

# Define the first CNN model for MNIST digits recognition


def mnistModel1():
model = Sequential()
model.add(Conv2D(30, (5, 5), input_shape=(28, 28, 1),
activation="relu"))
model.add(MaxPooling2D())
model.add(Conv2D(15, (3, 3), activation="relu"))
model.add(MaxPooling2D())
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dense(50, activation="relu"))
model.add(Dense(10, activation="softmax"))

# Compilation
model.compile(loss="categorical_crossentropy", optimizer="adam",
metrics=["accuracy"])
return model

# Define the second CNN model for MNIST digits recognition


def mnistModel2():
model = Sequential()
model.add(Conv2D(30, (5, 5), input_shape=(28, 28, 1),
activation="relu"))
model.add(MaxPooling2D())
model.add(Conv2D(15, (3, 3), activation="relu"))
model.add(MaxPooling2D())
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dense(50, activation="relu"))
model.add(Dense(10, activation="softmax"))

# Compilation
model.compile(loss="categorical_crossentropy", optimizer="adam",
metrics=["accuracy"])
return model

# Instantiate and compile the first MNIST model


mnist_model1 = mnistModel1()

# Train the first MNIST model


mnist_model1_history = mnist_model1.fit(x_train_mnist, y_train_mnist,
epochs=5, batch_size=32, validation_data=(x_test_mnist, y_test_mnist))

# Save the first MNIST model


mnist_model1.save('mnist_model1.h5')

# # Evaluate the first MNIST model


# mnist1_loss, mnist1_acc = mnist_model1.evaluate(x_test_mnist,
y_test_mnist)
# print(f"MNIST Model 1 Accuracy: {mnist1_acc*100:.2f}%")

# Instantiate and compile the second MNIST model


mnist_model2 = mnistModel2()

# Train the second MNIST model


mnist_model2_history = mnist_model2.fit(x_train_mnist, y_train_mnist,
epochs=10, batch_size=200, validation_data=(x_test_mnist,
y_test_mnist))
# Save the second MNIST model
mnist_model2.save('mnist_model2.h5')

# # Evaluate the second MNIST model


# mnist2_loss, mnist2_acc = mnist_model2.evaluate(x_test_mnist,
y_test_mnist)
# print(f"MNIST Model 2 Accuracy: {mnist2_acc*100:.2f}%")

# Define a Dense Neural Network model for A-Z alphabet recognition


az_model = Sequential([
Dense(256, activation='relu', input_shape=(784,)),
Dense(128, activation='relu'),
Dense(26, activation='softmax') # 26 classes for A-Z
])

az_model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])

# Train the A-Z model


az_model_history = az_model.fit(x_train_az, y_train_az, epochs=10,
batch_size=32, validation_data=(x_test_az, y_test_az))

# Save the A-Z mode


az_model.save('az_model.h5')

# Evaluate the A-Z model


az_loss, az_acc = az_model.evaluate(x_test_az, y_test_az)
print(f"Accuracy: {az_acc*100:.2f}%")

# Plotting function
def plot_history(history, model_name):
plt.figure(figsize=(12, 6))

# Plot training & validation accuracy values


plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title(f'{model_name} Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(['Train', 'Test'], loc='upper left')

# Plot training & validation loss values


plt.subplot(1, 2, 2)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title(f'{model_name} Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(['Train', 'Test'], loc='upper left')

plt.tight_layout()
plt.show()

# # Plot for first MNIST model


# plot_history(mnist_model1_history, 'MNIST Model 1')

# # Plot for second MNIST model


# plot_history(mnist_model2_history, 'MNIST Model 2')

# Plot
plot_history(az_model_history, 'HCR')

C:\Users\Roopa\anaconda3\Lib\site-packages\keras\src\layers\
convolutional\base_conv.py:107: UserWarning: Do not pass an
`input_shape`/`input_dim` argument to a layer. When using Sequential
models, prefer using an `Input(shape)` object as the first layer in
the model instead.
super().__init__(activity_regularizer=activity_regularizer,
**kwargs)

Epoch 1/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 26s 10ms/step - accuracy: 0.8518 -
loss: 0.4439 - val_accuracy: 0.9828 - val_loss: 0.0553
Epoch 2/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 18s 10ms/step - accuracy: 0.9771 -
loss: 0.0748 - val_accuracy: 0.9853 - val_loss: 0.0463
Epoch 3/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 18s 10ms/step - accuracy: 0.9829 -
loss: 0.0531 - val_accuracy: 0.9891 - val_loss: 0.0353
Epoch 4/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 18s 10ms/step - accuracy: 0.9858 -
loss: 0.0444 - val_accuracy: 0.9897 - val_loss: 0.0296
Epoch 5/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 18s 10ms/step - accuracy: 0.9878 -
loss: 0.0374 - val_accuracy: 0.9916 - val_loss: 0.0272

WARNING:absl:You are saving your model as an HDF5 file via


`model.save()` or `keras.saving.save_model(model)`. This file format
is considered legacy. We recommend using instead the native Keras
format, e.g. `model.save('my_model.keras')` or
`keras.saving.save_model(model, 'my_model.keras')`.

Epoch 1/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 17s 32ms/step - accuracy: 0.7226 - loss:
0.8589 - val_accuracy: 0.9760 - val_loss: 0.0830
Epoch 2/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 9s 30ms/step - accuracy: 0.9659 - loss:
0.1101 - val_accuracy: 0.9814 - val_loss: 0.0573
Epoch 3/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 9s 30ms/step - accuracy: 0.9758 - loss:
0.0741 - val_accuracy: 0.9867 - val_loss: 0.0410
Epoch 4/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 9s 31ms/step - accuracy: 0.9824 - loss:
0.0575 - val_accuracy: 0.9870 - val_loss: 0.0410
Epoch 5/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 9s 30ms/step - accuracy: 0.9828 - loss:
0.0525 - val_accuracy: 0.9891 - val_loss: 0.0310
Epoch 6/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 10s 32ms/step - accuracy: 0.9873 - loss:
0.0418 - val_accuracy: 0.9900 - val_loss: 0.0293
Epoch 7/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 10s 32ms/step - accuracy: 0.9874 - loss:
0.0393 - val_accuracy: 0.9902 - val_loss: 0.0288
Epoch 8/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 9s 31ms/step - accuracy: 0.9889 - loss:
0.0351 - val_accuracy: 0.9907 - val_loss: 0.0273
Epoch 9/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 9s 30ms/step - accuracy: 0.9898 - loss:
0.0324 - val_accuracy: 0.9911 - val_loss: 0.0264
Epoch 10/10
300/300 ━━━━━━━━━━━━━━━━━━━━ 9s 30ms/step - accuracy: 0.9908 - loss:
0.0290 - val_accuracy: 0.9917 - val_loss: 0.0261

WARNING:absl:You are saving your model as an HDF5 file via


`model.save()` or `keras.saving.save_model(model)`. This file format
is considered legacy. We recommend using instead the native Keras
format, e.g. `model.save('my_model.keras')` or
`keras.saving.save_model(model, 'my_model.keras')`.
C:\Users\Roopa\anaconda3\Lib\site-packages\keras\src\layers\core\
dense.py:87: UserWarning: Do not pass an `input_shape`/`input_dim`
argument to a layer. When using Sequential models, prefer using an
`Input(shape)` object as the first layer in the model instead.
super().__init__(activity_regularizer=activity_regularizer,
**kwargs)

Epoch 1/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 61s 6ms/step - accuracy: 0.8952 - loss:
0.3744 - val_accuracy: 0.9686 - val_loss: 0.1093
Epoch 2/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 53s 6ms/step - accuracy: 0.9712 - loss:
0.0971 - val_accuracy: 0.9731 - val_loss: 0.0918
Epoch 3/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 48s 5ms/step - accuracy: 0.9794 - loss:
0.0687 - val_accuracy: 0.9764 - val_loss: 0.0804
Epoch 4/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 48s 5ms/step - accuracy: 0.9829 - loss:
0.0545 - val_accuracy: 0.9817 - val_loss: 0.0668
Epoch 5/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 49s 5ms/step - accuracy: 0.9861 - loss:
0.0441 - val_accuracy: 0.9807 - val_loss: 0.0723
Epoch 6/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 44s 5ms/step - accuracy: 0.9877 - loss:
0.0390 - val_accuracy: 0.9835 - val_loss: 0.0656
Epoch 7/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 39s 4ms/step - accuracy: 0.9892 - loss:
0.0339 - val_accuracy: 0.9828 - val_loss: 0.0698
Epoch 8/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 39s 4ms/step - accuracy: 0.9902 - loss:
0.0324 - val_accuracy: 0.9840 - val_loss: 0.0684
Epoch 9/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 39s 4ms/step - accuracy: 0.9903 - loss:
0.0307 - val_accuracy: 0.9847 - val_loss: 0.0733
Epoch 10/10
9312/9312 ━━━━━━━━━━━━━━━━━━━━ 39s 4ms/step - accuracy: 0.9919 - loss:
0.0272 - val_accuracy: 0.9865 - val_loss: 0.0701

WARNING:absl:You are saving your model as an HDF5 file via


`model.save()` or `keras.saving.save_model(model)`. This file format
is considered legacy. We recommend using instead the native Keras
format, e.g. `model.save('my_model.keras')` or
`keras.saving.save_model(model, 'my_model.keras')`.

2328/2328 ━━━━━━━━━━━━━━━━━━━━ 5s 2ms/step - accuracy: 0.9852 - loss:


0.0769
Accuracy: 98.65%

import tkinter as tk
from tkinter import Button, Canvas, Toplevel, Label
from tkinter.font import Font
from PIL import Image, ImageDraw, ImageOps
import numpy as np
from tensorflow.keras.models import load_model

# Load the models and compile them to remove the warning


mnist_model1 = load_model('mnist_model1.h5')
mnist_model2 = load_model('mnist_model2.h5')
az_model = load_model('az_model.h5')

# Explicitly compile the models with dummy optimizer and loss to avoid
warnings
mnist_model1.compile(optimizer='adam',
loss='sparse_categorical_crossentropy', metrics=['accuracy'])
mnist_model2.compile(optimizer='adam',
loss='sparse_categorical_crossentropy', metrics=['accuracy'])
az_model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy', metrics=['accuracy'])

class DrawingApp:
def __init__(self, root):
self.root = root
self.root.title("Handwritten Alphanumeric Character
Recognition")
self.root.configure(bg='#008080') # Set background color to
purple

# Set up font
self.font = Font(family="Oswald", size=12, weight="bold")

# Create and pack label for title with white text color
self.title_label = Label(root, text="HANDWRITTEN\nALPHANUMERIC
CHARACTER\nRECOGNITION", font=("Oswald", 16, "bold"), bg='#008080',
fg='#FFFFFF')
self.title_label.pack(pady=20)

# Create and pack buttons for digit and character recognition


self.about_button = Button(root, text="About",
command=self.open_about_window, width=30, height=2, bg='white',
font=self.font, borderwidth=5, relief="raised")
self.about_button.pack(pady=10)

self.digit_button = Button(root, text="Try Your Number (Single


Digit)", command=lambda: self.open_input_window(1), width=30,
height=2, bg='white', font=self.font, borderwidth=5, relief="raised")
self.digit_button.pack(pady=10)

self.multi_digit_button = Button(root, text="Try Your Number


(Multi Digits)", command=self.open_multi_digit_input_window, width=40,
height=2, bg='white', font=self.font, borderwidth=5, relief="raised")
self.multi_digit_button.pack(pady=10)

self.az_button = Button(root, text="Try Your Character",


command=lambda: self.open_input_window(2), width=30, height=2,
bg='white', font=self.font, borderwidth=5, relief="raised")
self.az_button.pack(pady=10)

self.multi_character_button = Button(root, text="Try Your


Alphabet (Multi Characters)",
command=self.open_multi_character_input_window, width=40, height=2,
bg='white', font=self.font, borderwidth=5, relief="raised")
self.multi_character_button.pack(pady=10)

def open_input_window(self, model_id):


input_window = tk.Toplevel(self.root)
input_window.title("Input Window")
input_window.configure(bg='#008080') # Set background color
to purple

# Initialize canvas for drawing


self.canvas_width = 280
self.canvas_height = 280
self.white = 255 # for grayscale

self.image1 = Image.new("L", (self.canvas_width,


self.canvas_height), self.white)
self.draw = ImageDraw.Draw(self.image1)

self.canvas = Canvas(input_window, bg="white",


width=self.canvas_width, height=self.canvas_height)
self.canvas.pack()

self.canvas.bind("<B1-Motion>", self.paint)

# Add predict button


self.predict_button = Button(input_window, text="Predict",
command=lambda: self.predict(model_id), bg='white', font=self.font,
borderwidth=5, relief="raised")
self.predict_button.pack(pady=10)

# Add reset button


self.reset_button = Button(input_window, text="Reset",
command=self.reset_canvas, bg='white', font=self.font, borderwidth=5,
relief="raised")
self.reset_button.pack()

if model_id == 1:
self.label = Label(input_window, text="Draw a digit and
click Predict", bg='#008080', font=self.font)
elif model_id == 2:
self.label = Label(input_window, text="Draw a character
and click Predict", bg='#008080', font=self.font)
self.label.pack()

def open_multi_digit_input_window(self):
input_window = tk.Toplevel(self.root)
input_window.title("Input Window - Multi Digit")
input_window.configure(bg='#008080') # Set background color
to purple

# Initialize canvases for drawing three digits


self.canvas_width = 120 # Increase canvas size
self.canvas_height = 120 # Increase canvas size
self.white = 255 # for grayscale

self.images = [Image.new("L", (self.canvas_width,


self.canvas_height), self.white) for _ in range(3)]
self.draws = [ImageDraw.Draw(image) for image in self.images]

self.canvases = []
canvas_frame = tk.Frame(input_window, bg="#008080")
canvas_frame.pack(pady=2)

for i in range(3):
canvas = Canvas(canvas_frame, bg="white",
width=self.canvas_width, height=self.canvas_height)
canvas.grid(row=0, column=i, padx=0, pady=0,
sticky="nsew") # Remove padding and stick to edges
canvas.bind("<B1-Motion>", lambda event, index=i:
self.paint(event, index))
self.canvases.append(canvas)

# Add predict button


self.predict_button = Button(input_window, text="Predict",
command=self.predict_multi_digit, bg='white', font=self.font,
borderwidth=5, relief="raised")
self.predict_button.pack(pady=10)

# Add reset button


self.reset_button = Button(input_window, text="Reset",
command=self.reset_canvases, bg='white', font=self.font,
borderwidth=5, relief="raised")
self.reset_button.pack(pady=10)

self.output_label = Label(input_window, text="Draw three


digits and click Predict", bg='#008080', font=self.font)
self.output_label.pack(pady=10)

def open_multi_character_input_window(self):
input_window = tk.Toplevel(self.root)
input_window.title("Input Window - Multi Character")
input_window.configure(bg='#008080') # Set background color
to purple

# Initialize canvases for drawing up to five characters


self.canvas_width = 120 # Increase canvas size
self.canvas_height = 120 # Increase canvas size
self.white = 255 # for grayscale

self.images = [Image.new("L", (self.canvas_width,


self.canvas_height), self.white) for _ in range(5)]
self.draws = [ImageDraw.Draw(image) for image in self.images]

self.canvases = []
canvas_frame = tk.Frame(input_window, bg="#008080")
canvas_frame.pack(pady=2)

for i in range(5):
canvas = Canvas(canvas_frame, bg="white",
width=self.canvas_width, height=self.canvas_height)
canvas.grid(row=0, column=i, padx=0, pady=0,
sticky="nsew") # Remove padding and stick to edges
canvas.bind("<B1-Motion>", lambda event, index=i:
self.paint(event, index))
self.canvases.append(canvas)

# Add predict button


self.predict_button = Button(input_window, text="Predict",
command=self.predict_multi_character, bg='white', font=self.font,
borderwidth=5, relief="raised")
self.predict_button.pack(pady=10)

# Add reset button


self.reset_button = Button(input_window, text="Reset",
command=self.reset_canvases, bg='white', font=self.font,
borderwidth=5, relief="raised")
self.reset_button.pack(pady=10)

self.output_label = Label(input_window, text="Draw up to five


characters and click Predict", bg='#008080', font=self.font)
self.output_label.pack(pady=10)

def paint(self, event, index=None):


if index is None:
x1, y1 = (event.x - 1), (event.y - 1)
x2, y2 = (event.x + 1), (event.y + 1)
self.canvas.create_oval(x1, y1, x2, y2, fill="black",
width=10)
self.draw.line([x1, y1, x2, y2], fill=0, width=10) # 0
for black in grayscale
else:
x1, y1 = (event.x - 1), (event.y - 1)
x2, y2 = (event.x + 1), (event.y + 1)
self.canvases[index].create_oval(x1, y1, x2, y2,
fill="black", width=10)
self.draws[index].line([x1, y1, x2, y2], fill=0, width=10)
# 0 for black in grayscale

def predict(self, model_id):


if model_id == 1:
# Convert drawing to image
image = self.image1.resize((28, 28), Image.LANCZOS)
image = ImageOps.invert(image)
img = np.array(image)

img = img.reshape(1, 28, 28, 1).astype('float32') / 255


prediction = np.argmax(mnist_model1.predict(img), axis=-1)
prediction = str(prediction[0])

elif model_id == 2:
# Convert drawing to image
image = self.image1.resize((28, 28), Image.LANCZOS)
image = ImageOps.invert(image)
img = np.array(image)

img = img.reshape(1, 784).astype('float32') / 255


prediction = np.argmax(az_model.predict(img), axis=-1)
prediction = chr(prediction[0] + 65) # Convert to
corresponding A-Z character

self.label.config(text=f"Prediction: {prediction[0]}")

def predict_multi_digit(self):
predictions = []
for i in range(3):
# Convert drawing to image
image = self.images[i].resize((28, 28), Image.LANCZOS)
image = ImageOps.invert(image)
img = np.array(image)

img = img.reshape(1, 28, 28, 1).astype('float32') / 255


prediction = np.argmax(mnist_model2.predict(img), axis=-1)
predictions.append(prediction[0])

# Output predictions
self.output_label.config(text=f"Predictions: {predictions[0]}
{predictions[1]}{predictions[2]}")

def predict_multi_character(self):
predictions = []
for i in range(5):
# Convert drawing to image
image = self.images[i].resize((28, 28), Image.LANCZOS)
image = ImageOps.invert(image)
img = np.array(image)

img = img.reshape(1, 784).astype('float32') / 255


prediction = np.argmax(az_model.predict(img), axis=-1)
predictions.append(chr(prediction[0] + 65)) # Convert to
corresponding A-Z character

# Output predictions
self.output_label.config(text=f"Predictions:
{''.join(predictions)}")

def reset_canvas(self):
if hasattr(self, 'canvas'):
self.canvas.delete("all")
self.image1 = Image.new("L", (self.canvas_width,
self.canvas_height), self.white)
self.draw = ImageDraw.Draw(self.image1)
self.label.config(text="Draw a digit/character and click
Predict")

def reset_canvases(self):
for i in range(5):
self.canvases[i].delete("all")
self.images[i] = Image.new("L", (self.canvas_width,
self.canvas_height), self.white)
self.draws[i] = ImageDraw.Draw(self.images[i])
self.output_label.config(text="Draw up to five characters and
click Predict")

def open_about_window(self):
about_window = Toplevel(self.root)
about_window.title("About")
about_window.configure(bg='#008080')

about_label = Label(about_window, text="""


This fun application lets you draw digits or characters and
predicts what you've drawn!
Test your artistic skills by drawing on the canvas, then click
'Predict' to see the magic happen!

Explore the magic of handwritten character recognition!!!


Simply choose a model from the Home tab and click 'Input' to
get started with drawing and predicting.
""",
justify='left', padx=20, pady=20, bg='#008080',
font=self.font)
about_label.pack()

if __name__ == "__main__":
root = tk.Tk()
app = DrawingApp(root)
root.mainloop()

You might also like