Let's make an image recognition app using Python, Flask, and PyTorch. By combining these three, you can easily create a demo app at explosive speed.
A web framework for Python. Django is a well-known Python web framework, but Flask sells lightweight. Compared to Django, it has fewer features and extension libraries, but the restrictions make the code simpler and you can easily create applications. It is suitable for making prototypes of web applications because it is easy to build an environment.
It is well known that Python has a wealth of machine learning-related libraries and has become the de facto standard. Python also has a wealth of image processing libraries such as OpenCV and Pillow (PIL), and has a wealth of information on the net. Against this background, using Python x Flask makes it very easy to use the machine learning library and image processing library, and you can easily create applications.
When you upload a handwritten number image from a browser, let's create an application that recognizes the number and displays the result.
This time, I made a handwritten number recognition model of MNIST using PyTorch.
A simple sample that saves a model that has learned MNIST with PyTorch in Google Colaboratory, reads it out, and uses it-Artificial Intelligence Programming Blog Create a learning model by referring to this article. When I moved it, I got 1,725,616 bytes of mnist_cnn.pt.
If you have pip installed, you can build the Flask environment with pip install Flask
.
I'm also using Pillow (PIL) and PyTorch this time, so install them as well.
The directory and file structure are as follows.
├── mnist_cnn.pt… Handwritten number recognition model
├── predict.py… The main script. Upload files and judge images
├── static… Place the uploaded file
│ ├── 20191213210438.png… The file uploaded here is saved
│ ├── 20191213210253.png
│ └── 20191213210341.png
├── templates… html template save destination
├── index.html
The contents of predict.py. Describes the definition and loading of machine learning models and the processing of web applications. If you want to know more about model definition and image preprocessing, please refer to the following articles. Pytorch × MNIST Handwritten number recognition PNG image is predicted as input --Qiita
predict.py
#Load the required module
#Flask related
from flask import Flask, render_template, request, redirect, url_for, abort
#PyTorch related
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from torchvision import datasets, transforms
# Pillow(PIL)、datetime
from PIL import Image, ImageOps
from datetime import datetime
#Model definition
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5, 1)
self.conv2 = nn.Conv2d(20, 50, 5, 1)
self.fc1 = nn.Linear(4 * 4 * 50, 500)
self.fc2 = nn.Linear(500, 10)
def forward(self, x):
x = F.relu(self.conv1(x))
x = F.max_pool2d(x, 2, 2)
x = F.relu(self.conv2(x))
x = F.max_pool2d(x, 2, 2)
x = x.view(-1, 4 * 4 * 50)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return F.log_softmax(x, dim=1)
device = torch.device("cpu")
model = 0
model = Net().to(device)
#Load the learning model
model.load_state_dict(
torch.load("./mnist_cnn.pt", map_location=lambda storage, loc: storage)
)
model = model.eval()
app = Flask(__name__)
@app.route("/", methods=["GET", "POST"])
def upload_file():
if request.method == "GET":
return render_template("index.html")
if request.method == "POST":
#Save the uploaded file once
f = request.files["file"]
filepath = "./static/" + datetime.now().strftime("%Y%m%d%H%M%S") + ".png "
f.save(filepath)
#Load image file
image = Image.open(filepath)
#Converted to be handled by PyTorch(Resize, black and white inversion, normalization, dimension addition)
image = ImageOps.invert(image.convert("L")).resize((28, 28))
transform = transforms.Compose(
[transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]
)
image = transform(image).unsqueeze(0)
#Make predictions
output = model(image)
_, prediction = torch.max(output, 1)
result = prediction[0].item()
return render_template("index.html", filepath=filepath, result=result)
if __name__ == "__main__":
app.run(debug=True)
The contents of index.html. File upload and recognition result display are described in this HTML template.
index.html
<html>
<body>
{% if result %}
<IMG SRC="{{filepath}} " BORDER="1">The recognition result is{{result}}is<BR>
<HR>
{% endif %}
Please select a file and send<BR>
<form action = "./" method = "POST"
enctype = "multipart/form-data">
<input type = "file" name = "file" />
<input type = "submit"/>
</form>
</body>
</html>
Running python predicy.py
will start Flask's web server and the app will start running. By the way, Flask's default port is 5000.
http://localhostかホスト名:5000/でアクセスするとWebアプリケーションが表示されます。
When you upload handwritten numbers
It will display the recognition result. I can recognize it properly as "9".
It seems difficult to create a web application that recognizes images using machine learning, and it seems to be complicated with a lot of code, but Flask makes it really easy. It's not the end of making a machine learning model, but I think it's something that various people will use. However, if it is command-based, non-engineers cannot use it, and it is difficult to try various things. In such a case, it is recommended to use Flask to make a prototype quickly.
Recommended Posts