<jupyter_start><jupyter_text>Deploying a Deep Learning Model to Heroku Using Flask<jupyter_code>import cv2
import matplotlib.pyplot as plt
from keras.applications.vgg16 import preprocess_input

# Importing the necessary modules
from tensorflow.keras.applications.mobilenet_v2 import decode_predictions, preprocess_input, MobileNetV2

# example image of a tiger
img_path = 'tiger.jpg'
img = cv2.imread(img_path) # read image


plt.axis(False)
plt.imshow(img) # Display the image.
print('Image Dimensions: {} \nMaximum: {} \nMinimum: {}'.format(img.shape, img.max(), img.min()))<jupyter_output>Image Dimensions: (174, 290, 3) 
Maximum: 255 
Minimum: 0<jupyter_text>Resize the image to dimensions acceptable by MobileNetV2.<jupyter_code>img_resized = cv2.resize(img, (224, 224))
print('Image Dimensions: {} \nMaximum: {} \nMinimum: {}'.format(img_resized.shape,img_resized.max(), img_resized.min()))<jupyter_output>Image Dimensions: (224, 224, 3) 
Maximum: 255 
Minimum: 0<jupyter_text>Preprocess the image to have pixels in the range of [-1, 1]<jupyter_code>img_preprocessed = preprocess_input(img_resized)
print('Image Dimensions: {} \nMaximum: {} \nMinimum: {}'.format(img_preprocessed.shape, img_preprocessed.max(), img_preprocessed.min()))<jupyter_output>Image Dimensions: (224, 224, 3) 
Maximum: 1.0 
Minimum: -1.0<jupyter_text>Keras models expect inputs in batches, i.e., multiple images at once. To make prediction using a single image, we add a batch dimension of 1<jupyter_code>img_reshaped = img_preprocessed.reshape((1, 224, 224, 3))
print('Batch shape: {}'.format(img_reshaped.shape))
# creating the model
model = MobileNetV2(input_shape=(224,224,3), weights='imagenet')<jupyter_output>Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/mobilenet_v2/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224.h5
14540800/14536120 [==============================] - 0s 0us/step<jupyter_text>Make predictions<jupyter_code>prediction = model.predict(img_reshaped)
print('Predictions shape: {} \nMaximum: {} \nMinimum: {}'.format(prediction.shape, prediction.max(), prediction.min()))
decoded = decode_predictions(prediction)
decoded<jupyter_output>Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/imagenet_class_index.json
40960/35363 [==================================] - 0s 0us/step<jupyter_text>Test New Image<jupyter_code># example image of a tiger
img_path = 'lion.jpg'
img = cv2.imread(img_path) # read image


plt.axis(False)
plt.imshow(img) # Display the image.
img_resized = cv2.resize(img, (224, 224))
img_preprocessed = preprocess_input(img_resized)

img_reshaped = img_preprocessed.reshape((1, 224, 224, 3))
print('Batch shape: {}'.format(img_reshaped.shape))
prediction = model.predict(img_reshaped)
print('Predictions shape: {} \nMaximum: {} \nMinimum: {}'.format(prediction.shape, prediction.max(), prediction.min()))
decoded = decode_predictions(prediction)
decoded<jupyter_output><empty_output><jupyter_text>Creating a simple Flask application<jupyter_code>pip install flask_wtf<jupyter_output>Collecting flask_wtf
  Downloading https://files.pythonhosted.org/packages/16/df/ba01a1d9a8b9d933c0e746c7ca015bfeee2b1e4e32f0527de3bbe6ac65a7/Flask_WTF-0.15.1-py2.py3-none-any.whl
Collecting WTForms
[?25l  Downloading https://files.pythonhosted.org/packages/e0/31/614fc7dc7d76005b0acb8c0c8920d962b83d7422b4ba912886dfb63f86ff/WTForms-2.3.3-py2.py3-none-any.whl (169kB)
[K     |████████████████████████████████| 174kB 7.0MB/s 
[?25hRequirement already satisfied: Flask in /usr/local/lib/python3.7/dist-packages (from flask_wtf) (1.1.4)
Requirement already satisfied: itsdangerous in /usr/local/lib/python3.7/dist-packages (from flask_wtf) (1.1.0)
Requirement already satisfied: MarkupSafe in /usr/local/lib/python3.7/dist-packages (from WTForms->flask_wtf) (2.0.1)
Requirement already satisfied: click<8.0,>=5.1 in /usr/local/lib/python3.7/dist-packages (from Flask->flask_wtf) (7.1.2)
Requirement already satisfied: Werkzeug<2.0,>=0.15 in /usr/local/lib/python3.7/dist-packages (from Flask->flask_w[...]<jupyter_text>The flask_wtf module facilitates making simple forms in Flask which renders well in html pages. The form above takes an image with the extensions listed and contains a submit button which only works if an image is selected.<jupyter_code>pip install flask_bootstrap
model.save_weights('model.h5')
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileRequired, FileAllowed
from wtforms import SubmitField
import os
from werkzeug.utils import secure_filename
from flask import Flask, render_template
from flask import Flask,request,jsonify
import PIL

from array import array
from keras.models import model_from_json
from tensorflow import keras
from keras.preprocessing import image
import numpy as np
import cv2



app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
bootstrap = Bootstrap(app)
model = MobileNetV2(input_shape=(300,300,3), weights=None)
model.load_weights('model.h5')


class UploadForm(FlaskForm):
    upload = FileField('Select an image:', validators=[
        FileRequired(),
        FileAllowed(['jpg', 'png', 'jpeg', 'JPEG', 'PNG', 'JPG'], 'Images only!')
    ])
    submit = SubmitField('Classify')


def get_prediction(img_path):
    img = cv2.imread(img_path)
    img_resized = cv2.resize(img, (300, 300))
    img_preprocessed = preprocess_input(img_resized)
    img_reshaped = img_preprocessed.reshape((1, 300, 300, 3))
    prediction = model.predict(img_reshaped)
    decoded = decode_predictions(prediction)

    top_3 = [(cat.capitalize(), round(prob*100, 2)) for (code, cat, prob) in decoded[0]][:3]
    return top_3


@app.route('/', methods=['GET', 'POST'])
def home():
    form = UploadForm()
    if form.validate_on_submit():
        f = form.upload.data
        filename = secure_filename(f.filename)
        file_url = os.path.join('static', filename
        )
        f.save(file_url)
        form = None
        prediction = get_prediction(file_url)
    else:
        file_url = None
        prediction = None
    return render_template("index.html", form=form, file_url=file_url, prediction=prediction)


if __name__ == "__main__":
    app.run(debug=True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1368437647800725, 'fraction_numerical': 0.04477376635661359, 'mean_word_length': 5.741764080765144, 'pattern_counts': {'":': 1, '<': 29, '<?xml version=': 0, '>': 32, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '650526', 'license': 'MIT', 'n_tokens_mistral': 2429, 'n_tokens_neox': 2202, 'n_words': 470, 'path': 'Deploying_a_Deep_Learning_Model_to_Heroku_Using_Flask.ipynb', 'repo_name': 'Paul-mwaura/Deploying-a-Deep-Learning-Model-to-Heroku-Using-Flask', 'size': '6343'}