# Finding the appropriate CNN Model Architecture and Parameters

I am currently creating a CNN model that classifies whether the font is Arial, Verdana, Times New Roman and Georgia. All in all there are 16 classes since I considered also detecting whether the font is regular, bold, italics or bold italics. So 4 fonts * 4 styles = 16 classes.

The data that I have used in my training are the following:

 Training data set : 800 image patches of 256 * 256 dimension (50 for each class)
Validation data set : 320 image patches of 256 * 256 dimension (20 for each class)
Testing data set : 160 image patches of 256 * 256 dimension (10 for each class)


Below is the sample screenshot of my data:

Below is my initial code:

import numpy as np
import keras
from keras import backend as K
from keras.models import Sequential
from keras.layers import Activation
from keras.layers.core import Dense, Flatten
from keras.optimizers import Adam
from keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import *
from matplotlib import pyplot as plt
import itertools
import matplotlib.pyplot as plt
import pickle

image_width = 256
image_height = 256

train_path = 'font_model_data/train'
valid_path =  'font_model_data/valid'
test_path = 'font_model_data/test'

train_batches = ImageDataGenerator().flow_from_directory(train_path, target_size=(image_width, image_height), classes=['1','2','3','4', '5', '6', '7', '8', '9', '10', '11', '12','13', '14', '15', '16'], batch_size = 16)
valid_batches = ImageDataGenerator().flow_from_directory(valid_path, target_size=(image_width, image_height), classes=['1','2','3','4', '5', '6', '7', '8', '9', '10', '11', '12','13', '14', '15', '16'], batch_size = 16)
test_batches = ImageDataGenerator().flow_from_directory(test_path, target_size=(image_width, image_height), classes=['1','2','3','4', '5', '6', '7', '8', '9', '10', '11', '12','13', '14', '15', '16'], batch_size = 160)

imgs, labels = next(train_batches)

#CNN model
model = Sequential([
Conv2D(32, (3,3), activation='relu', input_shape=(image_width, image_height, 3)),
Flatten(),
Dense(16, activation='softmax'),
])

print(model.summary())

model.compile(Adam(lr=.0001),loss='categorical_crossentropy', metrics=['accuracy'])
model.fit_generator(train_batches, steps_per_epoch = 50, validation_data= valid_batches, validation_steps = 20, epochs = 1, verbose = 2)

model_pickle = open('cnn_font_model.pickle', 'wb')
pickle.dump(model, model_pickle)
model_pickle.close()
print('Training Done.')

test_imgs, test_labels = next(test_batches)

predictions = model.predict_generator(test_batches, steps = 160, verbose = 2)
print(predictions)


Can anyone suggest how will I know the right network architecture and parameters to get the optimal accuracy? How should I start tweaking my network?

## 1 Answer

In many cases in deep learning it works well to start off with a model which has a very high capacity and potentially overfits. From thereon you can reduce the model capacity to narrow the gap between train and validation error. In this chapter of the Deep Learning Book by Goodwell you find a good description of manual hyperparameter selection and how they influence model capacity.

Moreover, for many tasks well engineered solutions already exist. So check what worked for similar tasks and try out these architectures. For example, MNIST handwriting recognition is somewhat similar to your task. Wikipedia gives several architectures which work well on MNIST.

The article "Handwritten Digit Recognition using Convolutional Neural Networks in Python with Keras" contains architectures for MNIST, too. Again, this might be close enough to your tasks so I suggest to give these a try. The article includes an architecture very similar to yours but also a more complex one.

In other cases you could also check out pre-trained models. But here it might not even be required here.

• Thanks for the idea. – alyssaeliyah Feb 16 '20 at 17:08