Deploy Your First Machine Learning Model Easily
Here We're going to build an image classifier model using Keras API with the help of the TensorFlow library.

Full stack software engineer turned CTO From Cochin. Having experience with Javascript and typescript frameworks on both frontend and backend, With a keen interest in efficient scalable architecture.
๐ ๐ tadaaa !!! So this is my first personal blog post, I've been planning this for a looooong time And yes it's a start.
Disclaimer
In this post, I'm not adding any machine learning theories or concepts behind the model we're building as I'm on my path to learning more about the Theory behind the Machine learning algorithms. This article is based on my researches for completing a challenge to participate in the AI Bootcamp by the Tinkerhub Foundation. I'm the kind of person who wants to see an initial output to get motivated to learn more. So whenever I start to learn something I'd build and deploy a real-world application initially and then start learning how things work behind the scene, and this is one of such adventures.
Prerequisites
Some experience in building softwares of any kind is recommended, although we're using python as the programming language, deep knowledge in python is not required as you can easily follow if you have any other programming experience.
Let's get started
We're gonna use the Keras API to build and train the image classifier model using the tensorflow library and the dataset used is the popular cifar-10 dataset. As I told you that I've almost zero experience with Machine Learning stuffs I've referred this article for building the model.
Training the model
The code below is used to train the model.
import tensorflow as tf
# Display the version
print(tf.__version__)
# other imports
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.layers import Input, Conv2D, Dense, Flatten, Dropout
from tensorflow.keras.layers import GlobalMaxPooling2D, MaxPooling2D
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.models import Model
from tensorflow.keras.models import load_model
# Load in the data
cifar10 = tf.keras.datasets.cifar10
# Distribute it to train and test set
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)
# Reduce pixel values
x_train, x_test = x_train / 255.0, x_test / 255.0
# flatten the label values
y_train, y_test = y_train.flatten(), y_test.flatten()
# visualize data by plotting images
fig, ax = plt.subplots(5, 5)
k = 0
for i in range(5):
for j in range(5):
ax[i][j].imshow(x_train[k], aspect='auto')
k += 1
plt.show()
# number of classes
K = len(set(y_train))
# calculate total numer of classes
# for output layer
print("number of classes:", K)
# Build the model using the functional API
# input layer
i = Input(shape=x_train[0].shape)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(i)
x = BatchNormalization()(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)
x = Flatten()(x)
x = Dropout(0.2)(x)
# Hidden layer
x = Dense(1024, activation='relu')(x)
x = Dropout(0.2)(x)
# last hidden layer i.e.. output layer
x = Dense(K, activation='softmax')(x)
model = Model(i, x)
# model description
model.summary()
# Compile
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
_epochs = 10
# Fit
r = model.fit(
x_train, y_train, validation_data=(x_test, y_test), epochs=_epochs)
# Fit with data augmentation
# Note: if you run this AFTER calling
# the previous model.fit()
# it will CONTINUE training where it left off
batch_size = 32
data_generator = tf.keras.preprocessing.image.ImageDataGenerator(
width_shift_range=0.1, height_shift_range=0.1, horizontal_flip=True)
train_generator = data_generator.flow(x_train, y_train, batch_size)
steps_per_epoch = x_train.shape[0] // batch_size
r = model.fit(train_generator, validation_data=(x_test, y_test),
steps_per_epoch=steps_per_epoch, epochs=_epochs)
# Plot accuracy per iteration
plt.plot(r.history['accuracy'], label='acc', color='red')
plt.plot(r.history['val_accuracy'], label='val_acc', color='green')
plt.legend()
# label mapping
labels = '''airplane automobile bird cat deer dog frog horse ship truck'''.split()
# select the image from our test dataset
image_number = 0
# display the image
plt.imshow(x_test[image_number])
# load the image in an array
n = np.array(x_test[image_number])
# reshape it
p = n.reshape(1, 32, 32, 3)
# pass in the network for prediction and
# save the predicted label
predicted_label = labels[model.predict(p).argmax()]
# load the original label
original_label = labels[y_test[image_number]]
# display the result
print("Original label is {} and predicted label is {}".format(
original_label, predicted_label))
# save the model
model.save('cifar-10.model.h5')
I would prefer using the google colab for the initial experiments, you can easily download the final model (.h5) file from the files section of the colab notebook. the model training may take almost 8 minutes for each iteration. I'm not going for a more detailed explanation of each line of code, you can find them in-depth from the keras/tensorflow documentaions.
Building An API with the trained model
After executing the above code in the google colab notebook, You can download the model from the files section
For creating an API we're using the Flask framework.
First, create a new project folder
mkdir ~/image-classifier-demo
cd image-classifier-demo
Then create a new python virtual environment
python3 -m venv demo-env
Now activate your virtual environment
source demo-env/bin/activate
Installing required packages
pip install --upgrade tensorflow-cpu flask flask-cors opencv-python-headless gunicorn
after installing all the packages let's start coding. First, create a file called predict.py to add the image processing and prediction.
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.models import load_model
import cv2
import numpy as np
names = '''airplane automobile bird cat deer dog frog horse ship truck'''.split()
model = load_model("models/cifar-10.model.h5.h5")
# Process image and predict label
def processImg(IMG_PATH):
# Preprocess image
image = cv2.imread(IMG_PATH)
image = cv2.resize(image, (32, 32))
image = image.astype("float") / 255.0
image = img_to_array(image)
image = np.expand_dims(image, axis=0)
res = model.predict(image)
label = np.argmax(res)
labelName = names[label]
print("The image is of ", labelName)
print("confidence: ", np.max(res))
ret = dict()
ret['label'] = labelName
ret['confidence'] = str(np.max(res))
return ret
this function predicts the label and the confidence of the given image. to test it out add a test image to the folder and invoke the function with the relative path of the image as given below
processImg('./test-image.jpg')
So this is the major part of the API and now we only need to connect it with an API route. For that, we use the Flask web server. create an app.py file
from flask import Flask, render_template, request, jsonify
from flask_cors import CORS
from predict import processImg
# Initializing flask application
app = Flask(__name__)
cors = CORS(app)
@app.route("/predict", methods=["POST"])
def processReq():
data = request.files["img"]
data.save("img.jpg")
resp = processImg("img.jpg")
text = "it is a <b>"+resp['label'] + \
"</b> with confidence <b>"+resp['confidence']+"</b>"
return text
if __name__ == '__main__':
app.run()
The above code creates a web server with a post route /predict. You can test the API by uploading an image to the POST API using any API testing tools like postman or insomnia.
๐ Deploy the API
So we have built the API, now we'll deploy it to the internet with the help of heroku, there are many other platforms to deploy, we are now choosing heroku for simplicity.
create a Procfile with the below command. a proc file is required for heroku to run our code. learn more
web: gunicorn app:app
Now compile all the packages we use to a requirements.txt file
pip freeze > requirements.txt
now we are all set for deployment. create an account on https://www.heroku.com/. then install heroku cli from here
https://devcenter.heroku.com/articles/heroku-cli
login to heroku from command line
heroku login
initialize git
git init
git add .
git commit -m "Initial Commit"
create a new heroku app
heroku create image-classifier-demo
push our code to the heroku git repo
git push heroku master
Hurraaaay we've deployed our very first Machine learning API to the internet. the remote URL for the API will the provided by the heroku cli upon successful deployment or you can visit the heroku dashboard for API URL.
I've updated the basic API with an HTML form and pushed it to a git repo for reference. The link to the repo is given below
https://github.com/faris-mohamed10/tinkerhub-image-clasifier
Conclusion
Thank you for spending your valuable time reading my article. Since it is my first attempt at writing, there may be some mistakes in the article. Feel free to shoot your suggestions below. Happy coding and wish you all the best.


