Python: Introduction to Flask: Creating a number identification app using MNIST

What is Flask

Flask is a lightweight web application framework for Python.

What is a framework? It puts together the functions required when developing application software. A package that allows you to easily build a framework / template.

Rails for the language Ruby For Python, Django and Flask are the mainstream.

You can easily and lightweight develop web applications by fitting them into a template called Flask.

We will create a handwriting recognition application using MNIST. Process with the server using Flask and create the appearance of the application with HTML & CSS.

Run the smallest Flask app

To experience what you can do with Flask, let's first run the smallest Flask web application.

hello.py



from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

Since it cannot be executed on Fastpyter, the following is the work in the local environment.

  1. Create hello.py in your editor and copy and paste the above code

  2. Type python hello.py in the terminal and run

  3. Access http://127.0.0.1:5000/

After confirming, press Ctrl + C to end the process.

Code description

Let's take a closer look at this code.

First, declare that you want to use the Flask class of the flask package.

from flask import Flask

Next, create an instance of the Flask class called app.

app.<Flask class method name>

Allows you to use Flask class methods

app = Flask(__name__)

I get an unfamiliar @ here Lines starting with @ are called decorators Do something with the function or class defined in the next line.

app.route () specified a function defined on the next line We are processing to associate with URL. In the argument of app.route () Specify the URL after [http://127.0.0.1:5000/].

That is, in the code below, when you access http://127.0.0.1:5000/ This means that the hello_world () function will be called and will display Hello World !.

@app.route('/')#http://127.0.0.1:5000/Specify the subsequent path
def hello_world():
    return "Hello World!"

name =='main' is True That is, only when this code is executed directly app.run () is executed and the Flask app is launched.

if __name__ == "__main__":
    app.run()

What is name

By the description of if name =='main': earlier When you run the Python script directly Only (like when running python filename.py on the command line)

if name =='main': You can execute the following processing. And if it is imported from another file, it will not be processed. This description is used, for example, when creating and testing a module by yourself. It is used when you want to prevent unnecessary processing.

Let's take a closer look at this mechanism here. By the way, name is a variable that is automatically defined for each script file. The file name (module name) is automatically stored.

However, when you run the file directly, main is automatically stored in name. Let's check with the following example.

Example) What is output when the following test1.py is executed

test1.py



#Function show()Have been defined
def show():
    return __name__

print(__name__)
#Output result
__main__

Because test1.py is running directly main is automatically stored in name, so main is output.

When the Python script is executed directly like this Because main is stored in a variable called name

name =='main becomes True if name =='main': The following processing is executed.

Creating a number recognition application using MNIST

HTML & CSS side production

By the way, I just created a very simple app that just displays Hello World !. This time, we will reflect HTML & CSS to make it more like a web application.

The contents are explained in Introduction to HTML & CSS.

mnist.py



from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def hello_world():
    return render_template('index.html')

if __name__ == "__main__":
    app.run()

You will be working in a local environment.

1, Create a folder with an appropriate name (for example, mnist_app) on the desktop etc.

2, Create mnist.py in the mnist_app folder and copy and paste the above code

3, Create a templates folder in the mnist_app folder and create index.html in it Copy and paste the code of HTML template explanation 1/5 to index.html

4, Create a static folder inside the mnist_app folder Create a stylesheet.css in it (Flask is supposed to look for the html file in the templates folder and the css file in the static folder) Copy and paste the code of CSS template explanation 1/5 into stylesheet.css

5, cd mnist_app / to move to the mnist_app folder

6, Type python mnist.py in the terminal and run

7, Access http://127.0.0.1:5000/

After confirming, press Ctrl + C to end the process.

Code description

Let's take a closer look at the code. What's different from the code that lets you run the smallest Flask app

return render_template('index.html')only.

-By passing an html format file as an argument to render_template () You can reflect html on the page of the associated URL. The html file passed to this argument must be in the temlpates folder.

@app.route('/')
def hello_world():
    return render_template('index.html')

Flask side production

So far, we have designed the web page side and created a file uploader. However, you can't actually upload the file without adding code on Flask's side.

Here, we receive the image uploaded from the web page and identify it with the trained model. Let's look at the code that displays the result.

Before running the code with this ipynb file Please prepare the trained model model.h5 in the same directory.

mnist.py

import os
from flask import Flask, request, redirect, url_for, render_template, flash
from werkzeug.utils import secure_filename
from keras.models import Sequential, load_model
from keras.preprocessing import image
import tensorflow as tf
import numpy as np

classes = ["0","1","2","3","4","5","6","7","8","9"]
num_classes = len(classes)
image_size = 28

UPLOAD_FOLDER = "uploads"
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])

app = Flask(__name__)

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

model = load_model('./model.h5')#Load the trained model

graph = tf.get_default_graph()

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    global graph
    with graph.as_default():
        if request.method == 'POST':
            if 'file' not in request.files:
                flash('No file')
                return redirect(request.url)
            file = request.files['file']
            if file.filename == '':
                flash('No file')
                return redirect(request.url)
            if file and allowed_file(file.filename):
                filename = secure_filename(file.filename)
                file.save(os.path.join(UPLOAD_FOLDER, filename))
                filepath = os.path.join(UPLOAD_FOLDER, filename)

                #Read the received image and convert it to np format
                img = image.load_img(filepath, grayscale=True, target_size=(image_size,image_size))
                img = image.img_to_array(img)
                data = np.array([img])
                #Pass the transformed data to the model for prediction
                result = model.predict(data)[0]
                predicted = result.argmax()
                pred_answer = "this is" + classes[predicted] + "is"

                return render_template("index.html",answer=pred_answer)

        return render_template("index.html",answer="")


if __name__ == "__main__":
    app.run()

Since it cannot be executed on Fastpyter, the following is the work in the local environment.

  1. Replace mnist.py with the above code

  2. Create uploads folder in the same hierarchy as mnist.py

  3. Put model.h5 that saved the model trained earlier in the same hierarchy as mnist.py

  4. Keep the file placement the same as before, type python mnist.py in the terminal and run it

  5. Go to http://127.0.0.1:5000/

Now, let's upload an image of numbers.

image.png

After confirming, press Ctrl + C to end the process.

Code description 1/3

Now let's take a closer look at this code.

First, import the required libraries and modules.

import os
from flask import Flask, request, redirect, url_for, render_template, flash
from werkzeug.utils import secure_filename
from keras.models import Sequential, load_model
from keras.preprocessing import image
import tensorflow as tf
import numpy as np

Next, store the class names you want to classify in the classes list. This time, we will classify the numbers, so set them to 0-9. Pass the size of the image used for training to imaze_size. This time, I used the MNIST dataset, so I set it to 28.

classes = ["0","1","2","3","4","5","6","7","8","9","10"]
num_classes = len(classes)
image_size = 28

Pass the name of the folder to save the uploaded image to UPLOAD_FOLDER. For ALLOWED_EXTENSIONS, specify the extensions that allow uploading.

UPLOAD_FOLDER = "uploads"
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])

Create an instance of the Flask class.

app = Flask(__name__)

Defines a function that checks the extension of uploaded files. Returns True if the two conditions before and after and are met.

The first condition'.' In filename is Whether the character. Is present in the variable filename.

The second condition filename.rsplit ('.', 1) [1] .lower () in ALLOWED_EXTENSIONS Whether the string after. In the variable filename corresponds to one of ALLOWED_EXTENSIONS.

rsplit () is basically the same as split (). However, split () was separated from the beginning of the string In rsplit, the order of delimiter is from the end of the character string.

lower () converts the string to lowercase.

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

Load the trained model. graph = tf.get_default_graph () is the code needed for a Keras bug, so don't worry about it.

model = load_model('./model.h5')#Load the trained model

graph = tf.get_default_graph()

Code description 2/3

Next, we will define the function to be executed when the top page is accessed.

GET and POST are a type of HTTP method.

I will omit the detailed explanation GET fetches resources (pops html file when page is accessed) POST means sending data to the server.

global graph、with graph.as_default():Also
Don't worry, it's needed because of a Keras bug.

request is a function for handling data sent from a form on the web request.method contains the request method It is also explained in Introduction to HTML & CSS. And when request.method =='POST', the code that follows will be executed.

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    global graph
    with graph.as_default():
        if request.method == 'POST':

Here, does the POST request contain file data? It also checks if the file has a filename.

redirect () is a function that redirects to the url given as an argument request.url contains the URL of the page on which the request was made.

That is, if there is no uploaded file or no file name, it will return to the original page.

if 'file' not in request.files:
    flash('No file')
    return redirect(request.url)
file = request.files['file']
if file.filename == '':
    flash('No file')
    return redirect(request.url)

Then check the extension of the uploaded file.

Then, secure_filename () disables (sanitizes) any dangerous strings in the filename.

Next, join the path given as an argument by os.path.join () according to os. (Combined with \ on Windows, combined with / on Mac and Linax) Save the uploaded image to that path. Also, the save destination is stored in filepath.

if file and allowed_file(file.filename):
    filename = secure_filename(file.filename)
    file.save(os.path.join(UPLOAD_FOLDER, filename))
    filepath = os.path.join(UPLOAD_FOLDER, filename)

Code description 3/3

Finally, we will determine the number of the uploaded image. Here, we use Keras's image.load_img function that can load and resize images at the same time.

In the argument, specify the URL of the image you want to load and the size you want to resize the image.

Further grayscale=By passing True

It can be read in monochrome. image.img_to_array converts the image given in the argument to a Numpy array.

You also need to pass a list of Numpy arrays to model.predict (). Therefore, img is passed as a list to np.array (). And the prediction result is stored in pred_answer.

 #Read the received image and convert it to np format
img = image.load_img(filepath, grayscale=True, target_size=(image_size,image_size))
img = image.img_to_array(img)
data = np.array([img])
#Pass the transformed data to the model for prediction
result = model.predict(data)[0]
predicted = result.argmax()
pred_answer = "this is" + classes[predicted] + "is"

By passing answer = pred_answer as an argument of ender_template You can assign pred_answer to the answer written in index.html.

return render_template("index.html",answer=pred_answer)

When no POST request is made (simply accessing the URL) Nothing is displayed in the answer of index.html.

return render_template("index.html",answer="")

Finally, app.run () is executed and the server starts up.

if __name__ == "__main__":
    app.run()

Deploy

Publishing Settings

Until recently, I used to run web apps only on my own computer. Here you will learn how to deploy a web app to Heroku and publish it to the world.

When deploying a web app, to make the server available externally

host='0.0.0.0'Specify.
port = int(os.environ.get('PORT', 8080))Then

I get the port number that can be used on Heroku and store it in post.

If not set, 8080 will be stored.

At the end of mnist.py

if __name__ == "__main__":
    app.run()

Part of

if __name__ == "__main__":
    port = int(os.environ.get('PORT', 8080))
    app.run(host ='0.0.0.0',port = port)

Please rewrite it with the above code.

Setting up and deploying Heroku

Set up Heroku.

Before executing the code Located in the mnist_app directory in the same directory as this ipynb file Please prepare Procfile, requirements.txt, runtime.txt

First, register as a member of Heroku and log in. Then install Heroku.

Please install from the Heroku CLI site. Git will be installed at the same time you install Heroku CLI.

Here's how to deploy to Heroku.

1, Move to the directory containing the app file (cd __)

  1. Enter your email address and password as instructed by heroku login

3, move to Heroku, Enter Create New App-> App name Go to the page of the app that registers the country in United States and move to Setteings Click Add build pack to add Python

Move the three files below to the directory where the app is located (It's in the mnist_app directory, which is in the same directory as this ipynb file.)

Procfile, requirements.txt, runtime.txt

When checking the operation on Heroku, be sure to use the file mnist.py Name it main.py.

Since the Procfile specifies to start a file called main.py, Use main.py this time.

You can start a file with any name by rewriting Procfile.
Also, requirements.txt
In your own app on Heroku by writing the required libraries for
The library will be installed.
runtime.Describe the Python version to be used in txt.

In the directory (folder), main.py, Procfile, requirements.txt, runtime.txt Make sure you have the trained model, templates folder, statics folder, uploads folder,

~ In the hierarchy with the application file of the terminal (command prompt) ~

git init(This is the first time only)
heroku git:remote -a (app name)
git add .
git commit -m “(Write a message about what has changed)”
git push heroku master
Please deploy as.

image.png

The deployed app will have the URL https: // app name.herokuapp.com/. You can also enter the command heroku open to go to the URL where the web app is running. If you can confirm the operation, the deployment is successful.

Recommended Posts

Python: Introduction to Flask: Creating a number identification app using MNIST
Steps from installing Python 3 to creating a Django app
Creating a web application using Flask ②
Creating a simple app with flask
Creating a web application using Flask ①
Creating a learning model using MNIST
Creating a web application using Flask ③
Creating a web application using Flask ④
A super introduction to Python bit operations
[Python] Introduction to CNN with Pytorch MNIST
Launch a Flask app in Python Anywhere
Introduction to Discrete Event Simulation Using Python # 2
I want to make a web application using React and Python flask
[Python] Split a large Flask file using Blueprint
[Introduction to Python3 Day 23] Chapter 12 Become a Paisonista (12.1 to 12.6)
Create a Mac app using py2app and Python3! !!
Create a web app that converts PDF to text using Flask and PyPDF2
[Introduction to Udemy Python 3 + Application] 66. Creating your own exceptions
Try creating a compressed file using Python and zlib
(Python) Try to develop a web application using Django
Introduction to Python language
[Introduction to python] A high-speed introduction to Python for busy C ++ programmers
Introduction to OpenCV (python)-(2)
How to make a Python package using VS Code
[Python] I tried running a local server using flask
Introduction to Linear Algebra in Python: A = LU Decomposition
Write code to Unit Test a Python web app
[Introduction to Python] How to stop the loop using break?
How to execute a command using subprocess in Python
Name identification using python
How to host web app backend processing in Python using a rental server subdomain
[Introduction to Python] How to write repetitive statements using for statements
[Technical book] Introduction to data analysis using Python -1 Chapter Introduction-
How to deploy a web app made with Flask to Heroku
[Introduction to Python] How to write conditional branches using if statements
Sample to put Python Flask web app on Azure App Service (Web App)
How to launch AWS Batch from a python client app
I made a simple book application with python + Flask ~ Introduction ~
How to transpose a 2D array using only python [Note]
A memo when creating a directed graph using Graphviz in Python
To return char * in a callback function using ctypes in Python
I tried to make a stopwatch using tkinter in python
[Python] Introduction to graph creation using coronavirus data [For beginners]
A quick introduction to pytest-mock
A road to intermediate Python
A super introduction to Linux
Post to Twitter using Python
Start to Selenium using python
Introduction to serial communication [Python]
[Introduction to Python] <list> [edit: 2020/02/22]
Introduction to Python (Python version APG4b)
An introduction to Python Programming
Introduction to discord.py (3) Using voice
Introduction to Python For, While
Creating a Tensorflow Sequential model with original images added to MNIST
[Introduction to Python] How to split a character string with the split function
I tried to make a regular expression of "amount" using Python
[Introduction to Python] How to output a character string in a Print statement
Process Splunk execution results using Python and save to a file
I tried to make a regular expression of "time" using Python
I tried to make a regular expression of "date" using Python