Edited at

Flaskで画像分類Webアプリを作成する(Mobile Net)


概要

WebアプリケーションフレームワークであるFlaskを使い、ブラウザからサーバーに画像を渡し、Mobile Netでクラス分類を行うAPIを作成しました。

今回はファインチューニングをせずに、ImageNetの学習パラメータを使用します。

Mobile Netの論文


ツリー構造

MobileNetApi

├── mobile_net_model.h5

├── save_model_mobile_net.ipynb

├── server.py

└── templates

    ├── flask_api_index.html

    ├── layout.html

    └── result.html


Mobile Netのモデルを保存する

以下のコードを実行したらmobile_net_model.h5というファイルが作成されます。


save_model.py

import numpy as np

from keras.models import load_model
from keras.applications.mobilenet import MobileNet

# Mobile Net
model = MobileNet(weights="imagenet")

# モデルの保存、モデルをロードした後予測しかしないため、include_optimizer=Falseとする
model.save('mobile_net_model.h5', include_optimizer=False)



Severの作成


server.py

from flask import Flask, render_template, request, redirect, url_for, send_from_directory

import numpy as np
from keras.models import load_model
from keras.applications.mobilenet import MobileNet, preprocess_input, decode_predictions
from keras.preprocessing.image import img_to_array, load_img

app = Flask(__name__)

def img_pred(image):
# 保存したモデルをロード
model = load_model('mobile_net_model.h5')

# 読み込んだ画像を行列に変換
img_array = img_to_array(image)

# 3次元を4次元に変換、入力画像は1枚なのでsamples=1
img_dims = np.expand_dims(img_array, axis=0)

# Top2のクラスの予測
preds = model.predict(preprocess_input(img_dims))
results = decode_predictions(preds, top=2)[0]

# resultsを整形
result = [result[1] + str(result[2]) for result in results]
return result

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

@app.route('/result', methods=['POST'])
def result():
# submitした画像が存在したら処理する
if request.files['image']:
# 画像の読み込み
image_load = load_img(request.files['image'], target_size=(224,224))

# クラスの予測をする関数の実行
predict_Confidence = img_pred(image_load)

# render_template('./result.html')
return render_template('./result.html', title='予想クラス', predict_Confidence=predict_Confidence)

if __name__ == '__main__':
app.debug = True
app.run(host='localhost', port=5000)



HTMLの作成

layout.htmlを元にflask_api_index.htmlresult.htmlを作成していきます。


layout.html

<!DOCTYPE html>

<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>API Sample</title>
</head>
<body>
{% block content %}
<!-- ここに内容 -->
{% endblock %}
</body>
</html>

flask_api_index.htmllocalhost:5000にアクセスした時に表示するHTMLです。


flask_api_index.html

{% extends "layout.html" %}

{% block content %}

<form action="/result" method="post" enctype="multipart/form-data">
<input type="file" name="image" accept="image/png, image/jpeg, image/jpg">
<button type="submit">Submit</button>
</form>

{% endblock %}


result.htmlは、localhost:5000で画像を選択し、Submitを押した後に結果を表示するHTMLです。


result.html

{% extends "layout.html" %}

{% block content %}

<h3>予想クラス</h3>
{{ predict_Confidence }}

{% endblock %}



Serverを立てて実行

ここまでできたら、以下のコードを実行しlocalhost:5000にアクセスしてください。

$ python3 server.py

このように表示されて入れば大丈夫です。

スクリーンショット 2019-03-29 17.10.53.png

ペットボトルなどのモノの画像を選択し、submitを押してみます。

http://localhost:5000/resultに遷移し、予想クラスのTop2つが表示されていればOKです。

スクリーンショット 2019-03-29 17.12.20.png


その他記事

Flaskで機械学習APIを作ってみた

VGG16をFine Tuningして2018年上半期ブレイク女優・俳優・芸人に分類してみた

HerokuでPythonアプリをデプロイしてみた