<jupyter_start><jupyter_text>Mounting Google Drive<jupyter_code>from google.colab import drive
drive.mount('/gdrive')<jupyter_output>Mounted at /gdrive<jupyter_text>Imports<jupyter_code>from tensorflow.keras.datasets import mnist
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import SGD
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from imutils import build_montages
import matplotlib.pyplot as plt
import numpy as np
import argparse
import cv2
import os
from google.colab.patches import cv2_imshow
from collections import OrderedDict<jupyter_output><empty_output><jupyter_text>Downloading Dataset**This Data contain samples of A-Z,a-z and 0-9**<jupyter_code>!wget http://www.ee.surrey.ac.uk/CVSSP/demos/chars74k/EnglishImg.tgz<jupyter_output>--2021-06-10 15:46:08--  http://www.ee.surrey.ac.uk/CVSSP/demos/chars74k/EnglishImg.tgz
Resolving www.ee.surrey.ac.uk (www.ee.surrey.ac.uk)... 172.16.58.3
Connecting to www.ee.surrey.ac.uk (www.ee.surrey.ac.uk)|172.16.58.3|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 133975105 (128M) [application/x-gzip]
Saving to: ‘EnglishImg.tgz.2’

EnglishImg.tgz.2    100%[===================>] 127.77M  11.1MB/s    in 13s     

2021-06-10 15:46:22 (9.56 MB/s) - ‘EnglishImg.tgz.2’ saved [133975105/133975105]<jupyter_text>Untar the data file<jupyter_code>!tar -zxf '/content/EnglishImg.tgz.2' -C '/gdrive/MyDrive/Colab Notebooks/OCR/Data'
path='/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp'<jupyter_output><empty_output><jupyter_text>Data Preprocessing<jupyter_code>folders=[]
for root, dirnames, filenames in os.walk(path):
    for j in dirnames:
      folders.append(j)
    #print("filenames",filenames)
  #print('root   ',root,',  dirnames: - ',dirnames,'   filenames',filenames)
len(folders)
files={}
for i in folders:
  files[i]=os.listdir("/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/"+i)
  #files.add(os.listdir("/content/English/Img/BadImag/Bmp/"+i))
# sorting files according to their names in accending order
dict1 = OrderedDict(sorted(files.items()))
dict1.keys()
dict1['Sample001']
f = open("labels.txt", "a")
for i in dict1.keys():
  for j in dict1[i]:
    f.write("English/Img/GoodImg"+i+"/"+j+"\n")
f.close()
l="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"<jupyter_output><empty_output><jupyter_text>**Creating labels and data**<jupyter_code>data=[]
labels=[]
tmp=0
img=cv2.imread('/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/Sample041/img041-00190.png')
img.shape
img = cv2.cvtColor(cv2.imread('/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/Sample041/img041-00190.png'), cv2.COLOR_BGR2GRAY)   

cv2_imshow(cv2.imread('/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/Sample041/img041-00190.png'))
cv2_imshow(img)<jupyter_output><empty_output><jupyter_text>Convert image to 28x28<jupyter_code>def conTO28x28(path):
  #img = cv2.cvtColor(cv2.imread('/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/Sample041/img041-00190.png'), cv2.COLOR_BGR2GRAY)   
  img = cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2GRAY)   

  # convert each image of shape (32, 28, 1)
  w, h = img.shape
  if h > 28 or w > 28:
    (tH, tW) = img.shape
    dX = int(max(0, 28 - tW) / 2.0)
    dY = int(max(0, 28 - tH) / 2.0)

    img = cv2.copyMakeBorder(img, top=dY, bottom=dY,
          left=dX, right=dX, borderType=cv2.BORDER_CONSTANT,
          value=(0, 0, 0))
    img = cv2.resize(img, (28, 28))

  w, h = img.shape

  if w < 28:
      add_zeros = np.ones((28-w, h))*255
      img = np.concatenate((img, add_zeros))

  if h < 28:
      add_zeros = np.ones((28, 28-h))*255
      img = np.concatenate((img, add_zeros), axis=1)
  #img = np.expand_dims(img, axis=2)
  # Normalize each image
  return img
cv2_imshow(cv2.imread('/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/Sample001/img001-00001.png'))
image = conTO32x32('/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/Sample001/img001-00001.png')
image.shape
cv2_imshow(image)<jupyter_output><empty_output><jupyter_text>**Giving Labels to images**<jupyter_code>for i in dict1.keys():
  for j in dict1[i]:
    # labels list contains labels of images 
    labels.append(tmp)
    #image=cv2.imread('/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/'+i+"/"+j)
    image = conTO32x32('/gdrive/MyDrive/Colab Notebooks/OCR/Data/English/Img/GoodImg/Bmp/'+i+"/"+j)
    # Data list containing images in the form of numpy array 
    data.append(image)
  tmp+=1
from numpy import save
len(labels)
labels = np.array(labels, dtype="int")
data = np.array(data, dtype='float32')
tmp
labels
save('data.npy', data)
save('labels.npy', labels)
tmp_data = np.load('data.npy')
tmp_data.shape<jupyter_output><empty_output><jupyter_text>Combining Mnist and A-Z datasets from kaggle<jupyter_code>from tensorflow.keras.datasets import mnist
import numpy as np
def load_az_dataset(datasetPath):
  data = []
  labels = []
  for row in open(datasetPath):
    row = row.split(",")
    label = int(row[0])
    image = np.array([int(x) for x in row[1:]], dtype="uint8")
    image = image.reshape((28, 28))
    data.append(image)
    labels.append(label)
  data = np.array(data, dtype='float32')
  labels = np.array(labels, dtype="int")
  return (data, labels)
((trainData, trainLabels), (testData, testLabels)) = mnist.load_data()
(azData, azLabels) = load_az_dataset('/gdrive/MyDrive/Colab Notebooks/OCR/Data/A_Z Handwritten Data.csv')
azData.shape<jupyter_output><empty_output><jupyter_text>**Stacking up the training set and test set of mnist**<jupyter_code>mnist_data = np.vstack([trainData, testData])
mnist_labels = np.hstack([trainLabels, testLabels])
trainData.shape
mnist_data[0].shape
"""4799==0
label[4799]=0
a-z[4809]=a
label[4809]=37"""
labels.shape
azLabels+=10<jupyter_output><empty_output><jupyter_text>**Stacking up all the three datasets**<jupyter_code>labels1=np.hstack([mnist_labels,labels,azLabels])
data1=np.vstack([mnist_data,data,azData])
labels1.shape
data1.shape<jupyter_output><empty_output><jupyter_text>**Save combined dataset into .npy file for future use.**<jupyter_code>save('/gdrive/MyDrive/Colab Notebooks/OCR/Data/combined_data.npy', data1)
save('/gdrive/MyDrive/Colab Notebooks/OCR/Data/combine_labels.npy', labels1)
loaded_data = np.load('/gdrive/MyDrive/Colab Notebooks/OCR/Data/combined_data.npy')
loaded_labels = np.load('/gdrive/MyDrive/Colab Notebooks/OCR/Data/combine_labels.npy')
loaded_data.shape
loaded_labels.shape
cv2_imshow(loaded_data[-50000])
tmp_image = cv2.resize(loaded_data[0], (32, 32))
tmp_image.shape
data = [cv2.resize(image, (32, 32)) for image in loaded_data]
data = np.array(data, dtype="float32")
data.shape
data2 = np.expand_dims(data, axis=-1)
data2.shape
le = LabelBinarizer()
labels = le.fit_transform(loaded_labels)
counts = labels.sum(axis=0)
labels[0]<jupyter_output><empty_output><jupyter_text>**Calculating class weight in dataset**<jupyter_code>classTotals = labels.sum(axis=0)
classWeight = {}
# loop over all classes and calculate the class weight
for i in range(0, len(classTotals)):
	classWeight[i] = classTotals.max() / classTotals[i]
classWeight
print("Data shape: -",data2.shape)
print("labels shape: -",labels.shape)<jupyter_output>Data shape: - (450156, 32, 32, 1)
labels shape: - (450156, 62)<jupyter_text>Spliting data into 75% training and 25% test set<jupyter_code>(trainX, testX, trainY, testY) = train_test_split(data2,
	labels, test_size=0.25, stratify=labels, random_state=42)
trainX.shape<jupyter_output><empty_output><jupyter_text>Performing data augmentation<jupyter_code>aug = ImageDataGenerator(
	rotation_range=10,
	zoom_range=0.05,
	width_shift_range=0.1,
	height_shift_range=0.1,
	shear_range=0.15,
	horizontal_flip=False,
	fill_mode="nearest")<jupyter_output><empty_output><jupyter_text>Building Resnet Model<jupyter_code>from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import AveragePooling2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.convolutional import ZeroPadding2D
from keras.layers.core import Activation
from keras.layers.core import Dense
from keras.layers import Flatten
from keras.layers import Input
from keras.models import Model
from keras.layers import add
from keras.regularizers import l2
from keras import backend as K

class ResNet:
	@staticmethod
	def residual_module(data, K, stride, chanDim, red=False,
		reg=0.0001, bnEps=2e-5, bnMom=0.9):
		# the shortcut branch of the ResNet module should be
		# initialize as the input (identity) data
		shortcut = data

		# the first block of the ResNet module are the 1x1 CONVs
		bn1 = BatchNormalization(axis=chanDim, epsilon=bnEps,
			momentum=bnMom)(data)
		act1 = Activation("relu")(bn1)
		conv1 = Conv2D(int(K * 0.25), (1, 1), use_bias=False,
			kernel_regularizer=l2(reg))(act1)

		# the second block of the ResNet module are the 3x3 CONVs
		bn2 = BatchNormalization(axis=chanDim, epsilon=bnEps,
			momentum=bnMom)(conv1)
		act2 = Activation("relu")(bn2)
		conv2 = Conv2D(int(K * 0.25), (3, 3), strides=stride,
			padding="same", use_bias=False,
			kernel_regularizer=l2(reg))(act2)

		# the third block of the ResNet module is another set of 1x1
		# CONVs
		bn3 = BatchNormalization(axis=chanDim, epsilon=bnEps,
			momentum=bnMom)(conv2)
		act3 = Activation("relu")(bn3)
		conv3 = Conv2D(K, (1, 1), use_bias=False,
			kernel_regularizer=l2(reg))(act3)

		# if we are to reduce the spatial size, apply a CONV layer to
		# the shortcut
		if red:
			shortcut = Conv2D(K, (1, 1), strides=stride,
				use_bias=False, kernel_regularizer=l2(reg))(act1)

		# add together the shortcut and the final CONV
		x = add([conv3, shortcut])

		# return the addition as the output of the ResNet module
		return x

	@staticmethod
	def build(width, height, depth, classes, stages, filters,
		reg=0.0001, bnEps=2e-5, bnMom=0.9, dataset="cifar"):
		# initialize the input shape to be "channels last" and the
		# channels dimension itself
		inputShape = (height, width, depth)
		chanDim = -1

		# if we are using "channels first", update the input shape
		# and channels dimension
		if K.image_data_format() == "channels_first":
			inputShape = (depth, height, width)
			chanDim = 1

		# set the input and apply BN
		inputs = Input(shape=inputShape)
		x = BatchNormalization(axis=chanDim, epsilon=bnEps,
			momentum=bnMom)(inputs)

		# check if we are utilizing the CIFAR dataset
		if dataset == "cifar":
			# apply a single CONV layer
			x = Conv2D(filters[0], (3, 3), use_bias=False,
				padding="same", kernel_regularizer=l2(reg))(x)

		# check to see if we are using the Tiny ImageNet dataset
		elif dataset == "tiny_imagenet":
			# apply CONV => BN => ACT => POOL to reduce spatial size
			x = Conv2D(filters[0], (5, 5), use_bias=False,
				padding="same", kernel_regularizer=l2(reg))(x)
			x = BatchNormalization(axis=chanDim, epsilon=bnEps,
				momentum=bnMom)(x)
			x = Activation("relu")(x)
			x = ZeroPadding2D((1, 1))(x)
			x = MaxPooling2D((3, 3), strides=(2, 2))(x)

		# loop over the number of stages
		for i in range(0, len(stages)):
			# initialize the stride, then apply a residual module
			# used to reduce the spatial size of the input volume
			stride = (1, 1) if i == 0 else (2, 2)
			x = ResNet.residual_module(x, filters[i + 1], stride,
				chanDim, red=True, bnEps=bnEps, bnMom=bnMom)

			# loop over the number of layers in the stage
			for j in range(0, stages[i] - 1):
				# apply a ResNet module
				x = ResNet.residual_module(x, filters[i + 1],
					(1, 1), chanDim, bnEps=bnEps, bnMom=bnMom)

		# apply BN => ACT => POOL
		x = BatchNormalization(axis=chanDim, epsilon=bnEps,
			momentum=bnMom)(x)
		x = Activation("relu")(x)
		x = AveragePooling2D((8, 8))(x)

		# softmax classifier
		x = Flatten()(x)
		x = Dense(classes, kernel_regularizer=l2(reg))(x)
		x = Activation("softmax")(x)

		# create the model
		model = Model(inputs, x, name="resnet")

		# return the constructed network architecture
		return model
EPOCHS = 10 # Train mode for 10 epochs
INIT_LR = 1e-1 # Take initial learning rate as 0.01
BS = 256 # Taking batch size of 256
le.classes_<jupyter_output><empty_output><jupyter_text>Compling model<jupyter_code>print("[INFO] compiling model...")
opt = SGD(learning_rate=INIT_LR, decay=INIT_LR / EPOCHS) # Using SGD(Schotastic Gradient Descent) as optimizer

model = ResNet.build(32, 32, 1, len(le.classes_), (3, 3, 3),
	(64, 64, 128, 256), reg=0.0005)

model.compile(loss="categorical_crossentropy", optimizer=opt,
	metrics=["accuracy"])<jupyter_output>[INFO] compiling model...<jupyter_text>Fit Model Function<jupyter_code>import numpy as np
import os

checkpoint_path = "/gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# Create a callback that saves the model's weights
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
                                                 save_weights_only=True,
                                                 verbose=1)
EPOCHS=50<jupyter_output><empty_output><jupyter_text>Train Model **Train Model for 50 epochs**<jupyter_code>H = model.fit(
	aug.flow(trainX, trainY, batch_size=BS),
	validation_data=(testX, testY),
	steps_per_epoch=len(trainX) // BS,
	epochs=EPOCHS,
	class_weight=classWeight,
	verbose=1,
  callbacks=[cp_callback])
model.save('/gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/final_model_resnet/Combined_Resnet_50_Epochs',save_format='.h5')<jupyter_output>Epoch 1/50
1318/1318 [==============================] - 188s 143ms/step - loss: 31.2867 - accuracy: 0.1044 - val_loss: 6.8277 - val_accuracy: 0.0747

Epoch 00001: saving model to /gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/training_1/cp.ckpt
Epoch 2/50
1318/1318 [==============================] - 188s 143ms/step - loss: 27.9640 - accuracy: 0.2066 - val_loss: 5.5421 - val_accuracy: 0.2517

Epoch 00002: saving model to /gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/training_1/cp.ckpt
Epoch 3/50
1318/1318 [==============================] - 206s 156ms/step - loss: 26.0784 - accuracy: 0.3042 - val_loss: 5.2493 - val_accuracy: 0.3786

Epoch 00003: saving model to /gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/training_1/cp.ckpt
Epoch 4/50
1318/1318 [==============================] - 206s 156ms/step - loss: 24.4719 - accuracy: 0.4104 - val_loss: 5.0080 - val_accuracy: 0.4063

Epoch 00004: saving model to /gdrive/MyDrive/Colab Notebooks/OCR[...]<jupyter_text>**Save model**<jupyter_code>model.save('/gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/final_model_resnet/Combined_Resnet_50_Epochs.h5',save_format='.h5')<jupyter_output>/usr/local/lib/python3.7/dist-packages/keras/utils/generic_utils.py:497: CustomMaskWarning: Custom mask layers require a config and must override get_config. When loading, the custom mask layer must be passed to the custom_objects argument.
  category=CustomMaskWarning)<jupyter_text>**Evaluate model on test set**<jupyter_code>labelNames = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
labelNames = [l for l in labelNames]
print("[INFO] evaluating network ")
predictions = model.predict(testX, batch_size=BS)
print(classification_report(testY.argmax(axis=1),
  predictions.argmax(axis=1), target_names=labelNames,zero_division=0))<jupyter_output>[INFO] evaluating network 
              precision    recall  f1-score   support

           0       0.19      0.68      0.30      1752
           1       0.95      0.94      0.95      1989
           2       0.82      0.73      0.77      1765
           3       0.82      0.93      0.87      1798
           4       0.75      0.82      0.78      1718
           5       0.37      0.70      0.48      1594
           6       0.79      0.88      0.83      1735
           7       0.78      0.91      0.84      1835
           8       0.64      0.86      0.74      1714
           9       0.82      0.90      0.85      1748
           A       0.91      0.86      0.88      3607
           B       0.81      0.86      0.83      2196
           C       0.96      0.91      0.94      5906
           D       0.84      0.79      0.81      2581
           E       0.95      0.87      0.91      2972
           F       0.81      0.94      0.87       310
           G       0.68      0.82      0.74      1476
[...]<jupyter_text>Train model for more 30 epochs<jupyter_code>EPOCHS=30
H = model.fit(
	aug.flow(trainX, trainY, batch_size=BS),
	validation_data=(testX, testY),
	steps_per_epoch=len(trainX) // BS,
	epochs=EPOCHS,
	class_weight=classWeight,
	verbose=1)
model.save('/gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/final_model_resnet/Combined_Resnet_80_Epochs',save_format='.h5')
model.save('/gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/final_model_resnet/Combined_Resnet_80_Epochs',save_format='.h5')<jupyter_output>/usr/local/lib/python3.7/dist-packages/keras/utils/generic_utils.py:497: CustomMaskWarning: Custom mask layers require a config and must override get_config. When loading, the custom mask layer must be passed to the custom_objects argument.
  category=CustomMaskWarning)<jupyter_text>Evaluate for 80 epochs<jupyter_code>labelNames = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
labelNames = [l for l in labelNames]
print("[INFO] evaluating network ")
predictions = model.predict(testX, batch_size=BS)
print(classification_report(testY.argmax(axis=1),
  predictions.argmax(axis=1), target_names=labelNames,zero_division=0))
EPOCHS=20<jupyter_output><empty_output><jupyter_text>Train for more 20 epochs<jupyter_code>H = model.fit(
	aug.flow(trainX, trainY, batch_size=BS),
	validation_data=(testX, testY),
	steps_per_epoch=len(trainX) // BS,
	epochs=EPOCHS,
	class_weight=classWeight,
	verbose=1)
model.save('/gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/final_model_resnet/Combined_Resnet_100_Epochs',save_format='.h5')<jupyter_output>Epoch 1/20
1318/1318 [==============================] - 187s 142ms/step - loss: 10.2421 - accuracy: 0.8457 - val_loss: 3.3809 - val_accuracy: 0.8514
Epoch 2/20
1318/1318 [==============================] - 187s 142ms/step - loss: 10.0791 - accuracy: 0.8454 - val_loss: 3.4074 - val_accuracy: 0.8383
Epoch 3/20
1318/1318 [==============================] - 186s 141ms/step - loss: 10.0754 - accuracy: 0.8476 - val_loss: 3.3890 - val_accuracy: 0.8422
Epoch 4/20
1318/1318 [==============================] - 186s 141ms/step - loss: 10.0091 - accuracy: 0.8467 - val_loss: 3.3967 - val_accuracy: 0.8470
Epoch 5/20
1318/1318 [==============================] - 186s 142ms/step - loss: 9.8191 - accuracy: 0.8471 - val_loss: 3.4068 - val_accuracy: 0.8372
Epoch 6/20
1318/1318 [==============================] - 187s 142ms/step - loss: 9.8357 - accuracy: 0.8473 - val_loss: 3.3891 - val_accuracy: 0.8499
Epoch 7/20
1318/1318 [==============================] - 187s 142ms/step - loss: 9.7272 - accuracy: 0.8485 - [...]<jupyter_text>Evaluate for 100 Epochs<jupyter_code>labelNames = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
labelNames = [l for l in labelNames]
print("[INFO] evaluating network ")
predictions = model.predict(testX, batch_size=BS)
print(classification_report(testY.argmax(axis=1),
  predictions.argmax(axis=1), target_names=labelNames,zero_division=0))<jupyter_output>[INFO] evaluating network 
              precision    recall  f1-score   support

           0       0.17      0.79      0.28      1752
           1       0.92      0.96      0.94      1989
           2       0.84      0.81      0.82      1765
           3       0.91      0.92      0.92      1798
           4       0.70      0.89      0.78      1718
           5       0.47      0.74      0.58      1594
           6       0.83      0.92      0.87      1735
           7       0.82      0.94      0.88      1835
           8       0.71      0.89      0.79      1714
           9       0.83      0.93      0.88      1748
           A       0.93      0.89      0.91      3607
           B       0.93      0.81      0.87      2196
           C       0.97      0.94      0.95      5906
           D       0.88      0.84      0.86      2581
           E       0.98      0.90      0.94      2972
           F       0.79      0.95      0.86       310
           G       0.84      0.78      0.81      1476
[...]<jupyter_text>Train for more 20 epochs<jupyter_code>H = model.fit(
	aug.flow(trainX, trainY, batch_size=BS),
	validation_data=(testX, testY),
	steps_per_epoch=len(trainX) // BS,
	epochs=EPOCHS,
	class_weight=classWeight,
	verbose=1)
model.save('/gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/final_model_resnet/Combined_Resnet_120_Epochs',save_format='.h5')<jupyter_output>Epoch 1/20
1318/1318 [==============================] - 184s 140ms/step - loss: 8.7551 - accuracy: 0.8529 - val_loss: 3.3618 - val_accuracy: 0.8489
Epoch 2/20
1318/1318 [==============================] - 187s 142ms/step - loss: 8.8098 - accuracy: 0.8530 - val_loss: 3.3661 - val_accuracy: 0.8523
Epoch 3/20
1318/1318 [==============================] - 187s 142ms/step - loss: 8.5839 - accuracy: 0.8512 - val_loss: 3.3778 - val_accuracy: 0.8441
Epoch 4/20
1318/1318 [==============================] - 187s 142ms/step - loss: 8.6650 - accuracy: 0.8540 - val_loss: 3.3737 - val_accuracy: 0.8418
Epoch 5/20
1318/1318 [==============================] - 187s 142ms/step - loss: 8.6483 - accuracy: 0.8537 - val_loss: 3.3653 - val_accuracy: 0.8474
Epoch 6/20
1318/1318 [==============================] - 187s 142ms/step - loss: 8.4984 - accuracy: 0.8518 - val_loss: 3.3771 - val_accuracy: 0.8433
Epoch 7/20
1318/1318 [==============================] - 187s 142ms/step - loss: 8.4953 - accuracy: 0.8538 - val_[...]<jupyter_text>**Final evaluation of 120 epochs**<jupyter_code>labelNames = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
labelNames = [l for l in labelNames]
print("[INFO] evaluating network ")
predictions = model.predict(testX, batch_size=BS)
print(classification_report(testY.argmax(axis=1),
  predictions.argmax(axis=1), target_names=labelNames,zero_division=0))
model.save('/gdrive/MyDrive/Colab Notebooks/OCR/Models/CombineDatasetModels/final_model_resnet/Combined_Resnet_120_Epochs.h5',save_format='.h5')
# save the model to disk
print("[INFO] serializing network...")
#model.save('first_model', save_format="h5")
# construct a plot that plots and saves the training history
N = np.arange(0, EPOCHS)
plt.style.use("ggplot")
plt.figure()
plt.plot(N, H.history["loss"], label="train_loss")
plt.plot(N, H.history["val_loss"], label="val_loss")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.show()
#plt.savefig('plot')<jupyter_output>[INFO] serializing network...<jupyter_text>Model Depolyment<jupyter_code>from tensorflow.keras.models import load_model
from imutils.contours import sort_contours
import numpy as np
import argparse
import imutils
import cv2
from google.colab.patches import cv2_imshow
model = load_model('/gdrive/MyDrive/internship/OCR/Models/CombineDatasetModels/final_model_resnet/Combined_Resnet_120_Epochs.h5')
def predict_image(img):
  image = cv2.imread(img)
  gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  blurred = cv2.GaussianBlur(gray, (5, 5), 0)
  edged = cv2.Canny(blurred, 30, 150)
  cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)
  cnts = imutils.grab_contours(cnts)
  cnts = sort_contours(cnts, method="left-to-right")[0]
  chars = []


  #cv2_imshow(edged)

  for c in cnts:
    # compute the bounding box of the contour
    (x, y, w, h) = cv2.boundingRect(c)
    # filter out bounding boxes, ensuring they are neither too small
    # nor too large
    if (w >= 5 and w <= 150) and (h >= 15 and h <= 120):
      # extract the character and threshold it to make the character
      # appear as *white* (foreground) on a *black* background, then
      # grab the width and height of the thresholded image
      roi = gray[y:y + h, x:x + w]
      thresh = cv2.threshold(roi, 0, 255,
        cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
      (tH, tW) = thresh.shape
      # if the width is greater than the height, resize along the
      # width dimension
      if tW > tH:
        thresh = imutils.resize(thresh, width=32)
      # otherwise, resize along the height
      else:
        thresh = imutils.resize(thresh, height=32)
      (tH, tW) = thresh.shape
      dX = int(max(0, 32 - tW) / 2.0)
      dY = int(max(0, 32 - tH) / 2.0)
      # pad the image and force 32x32 dimensions
      padded = cv2.copyMakeBorder(thresh, top=dY, bottom=dY,
        left=dX, right=dX, borderType=cv2.BORDER_CONSTANT,
        value=(0, 0, 0))
      padded = cv2.resize(padded, (32, 32))
      padded = padded.astype("float32")
      padded = np.expand_dims(padded, axis=-1)
      chars.append((padded, (x, y, w, h)))
      cv2_imshow(padded)

    #print("Padded: -")
    #cv2_imshow(padded)

  """
  padded = cv2.copyMakeBorder(blurred, top=dY, bottom=dY,
			left=dX, right=dX, borderType=cv2.BORDER_CONSTANT,
			value=(0, 0, 0))
  padded = cv2.resize(padded, (32, 32))
  """
  #final_image=np.expand_dims(padded,axis=2)
  #print(chars)
  boxes = [b[1] for b in chars]
  #cv2_imshow(chars)
  chars = np.array([c[0] for c in chars], dtype="float32")
  # OCR the characters using our handwriting recognition model
  preds = model.predict(chars)
  # define the list of label names
  labelNames = "0123456789"
  labelNames += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  labelNames = [l for l in labelNames]
  output=""
  for (pred, (x, y, w, h)) in zip(preds, boxes):
    i = np.argmax(pred)
    prob = pred[i]
    label = labelNames[i]
    output+=label
  
  return output<jupyter_output><empty_output><jupyter_text>Getting predictions<jupyter_code>predict_image('/content/sony.png')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14390216024688535, 'fraction_numerical': 0.07197012991960985, 'mean_word_length': 3.8329957650524764, 'pattern_counts': {'":': 3, '<': 109, '<?xml version=': 0, '>': 116, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 39, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '29', 'dir': 'jupyter-structured-clean-dedup', 'id': '546916', 'license': 'MIT', 'n_tokens_mistral': 11038, 'n_tokens_neox': 9653, 'n_words': 2043, 'path': 'OCR_Combined.ipynb', 'repo_name': 'RUiNtheExtinct/ocr-tensorflow', 'size': '26251'}