Djangoで人工知能アプリを作ってみた【性別判定アプリ】

Djangoで人工知能アプリを作ってみた【性別判定アプリ】
えびかずき
えびかずき
こんにちは、えびかずきです。

今回はTensorflowを使った人工知能アプリを作ってみました!

ということで、この記事では制作工程をご紹介していきたいと思います。

こんな人におすすめ:
・TensorflowとDjangoでWebアプリを作りたい

ローカル環境

  • OS:MacOS Catalina 10.15
  • Python:3.5.4
  • Django:2.2.2
  • Tensorflow:1.5.0
  • IDE:PyCharm

本番環境

  • OS:Amazon Linux 2(AWS EC2仮想マシン)
  • Webサーバーシステム:Nginx
  • WSGI:Gunicorn
  • Python:3.5.4
  • Django:2.2.2
  • Tensorflow:1.5.0
  • PostgreSQL:10.4
  • ネームサーバー:XSERVER
  • 暗号化:certbot(旧Let’s Encrypt)

ソースコードはこちら(Github)

完成したWebアプリ

Gender Judgement AI

人物写真を解析して、性別を判定するアプリです。

JPEG形式の写真をアップロードして、Judgeボタンを押すとAIが性別を判定してくれます。

図は菅総理の写真を使って実施した例です。

写真の下に解析の結果として『MAN』と表示されています。

実際にWeb上に公開して運用中ですので、是非試してみてください!(2020/11現在)

要件定義

1.ユーザーから画像を受け取って、画像を表示する

2.受け取った画像の性別判定結果を表示する。

制作工程

制作工程は大きく分けて『人工知能プログラムの作成』と、『Djangoプロジェクトの作成』の二つに分かれます。

制作期間はたしか2週間くらいだったと思います。

それでは、それぞれ詳しく説明いきましょう。

人工知能プログラム

今回はvgg16という画像分類向けのディープラーニング学習済みのCNNモデルを活用して人工知能プログラムを作成しました。

具体的にはvgg16に男女のラベル付き人物写真で転移学習を施しています。

既にプログラムの詳細については当ブログにて紹介していますので、そちらをご参照ください↓

Djangoプロジェクト

1.Djangoプロジェクトを作成する

まず、models.pyに画像保存用のモデルを作成します。

#models.py

from django.db import models

class Sample(models.Model):
    img = models.ImageField(verbose_name='img', blank=True, null=True)

続いて、ユーザーからの画像受け取り用にフォームクラスを作成します。

# forms.py

from django import forms
from .models import Sample

class ImgForm(forms.ModelForm):
    class Meta:
        model = Sample
        fields = ('img',)

続いて、urls.pyに、 templateに繋ぐviewクラスのルーティングを記述します。

# urls.py

from django.urls import path
from . import views

app_name = 'works'

urlpatterns = [
    path('genderai/',views.GenderView.as_view(), name='gender'),
]

次に、views.pyにこのプロジェクトの中核となるビュークラスを定義します。

ここではgeneric.FormViewを継承してビュークラスを作成し、postメソッドをオーバーライドして機能を付与しています。

具体的には、フォームから受け取った画像を『sample_img』としてテンプレートに渡し、『gendar』という関数に引数として画像データを渡して性別の判定結果を『result』としてテンプレートに渡しています。

# views.py

from django.shortcuts import render
from django.views import generic
from works.forms import ImgForm
from .models import Sample
from ebikazuki.settings import *
import shutil
import os

class GenderView(generic.FormView):
    template_name = "genderai.html"
    form_class = ImgForm

    # postメソッドをオーバーライドする
    def post(self, request, *args, **kwargs):
        form = ImgForm(request.POST)

        # 前の画像データを消す
        shutil.rmtree(MEDIA_ROOT)
        os.mkdir(MEDIA_ROOT)

     # フォームから受け取った画像データを保存する
        sample = Sample()
        sample.img = request.FILES['img']
        sample.save()
        sample_img = sample.img

        #人工知能プログラムを使って性別を判定する
        from works.gender import gender
        img = request.FILES['img']
        man_value = gender(img)
        if man_value > 0.5 :
            result = "MAN"
        else:
            result = "WOMAN"

        return render(request, self.template_name, {
            'form': self.form_class , 'result': result ,'sample_img': sample_img
        }
                      )

最後にテンプレートファイルを作成します。

{% load static %}
{% load widget_tweaks %}

<!DOCTYPE html>
<html lang="ja">
    <head>
        略
    </head>
    <body>
        <header class="masthead2">
            <div class="container h-100">
                <div class="row h-100 align-items-center justify-content-center text-center">
                    <div class="col-lg-10 align-self-end">
                        <h1 class="text-uppercase text-white font-weight-bold">Gender Judgement AI</h1>
                        <hr class="divider my-4" />
                    </div>
                    <div class="col-lg-8 align-self-baseline">
                        <p class="text-white-75 font-weight-light mb-5"> <strong>JPEG画像をアップロードして"JUDGE"ボタンを押してください </strong></p>
                        <form method ="POST" enctype="multipart/form-data">
                          {% csrf_token %}
                          {{ form.img|add_class:'text-white btn-xl' }}
                          <button class="btn btn-primary btn-xl" type="submit">Judge</button>
                        </form>
                        <br>
                        {% if sample_img %}
                        <img src="{{ sample_img.url }}" width=35% class="image-circle"/>
                        {% else %}
                        <img width=35% class="image-circle" src="{% static 'sample/example.jpeg' %}"/>
                        {% endif %}

                        {% if result == None %}
                          <p> </p>
                        {% else %}
                          <br>
                          <p class="text-white-75 font-weight-light mb-5"> <strong> RESULT:{{result}} </strong></p>

                        {% endif %}
                    </div>
                </div>
            </div>
        </header>

        <!-- Footer-->
          略
        </footer>
    </body>
</html>

2.人工知能プログラムを組み込む

学習済みのディープラーニングモデルのファイルを準備し(ここでは『studied_model_lite.h5』というファイル)、jpeg画像を受け取って男性の可能性を示す数値が返される関数を作成しています。

# gender.py

from tensorflow.python.keras.applications.vgg16 import preprocess_input
from works.utils import load_random_imgs, show_test_samples
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator
from tensorflow.python.keras.models import load_model
from tensorflow.python.keras.preprocessing.image import img_to_array, load_img
from ebikazuki.settings_dev import BASE_DIR
import numpy as np

# modelへ保存データを読み込み
model = load_model(BASE_DIR+'/works/studied_model_lite.h5')

def gender(Img):
    # 評価の実施
    img_data = load_img(Img, target_size=(224, 224))
    x_test = np.array([img_to_array(img_data)])
    true_labels = ["None"]
    x_test_preproc = preprocess_input(x_test.copy())/255.
    probs = model.predict(x_test_preproc)

    # 学習画像を取り込むジェネレータを作成。それぞれのパラメータを設定
    img_gen = ImageDataGenerator(
        rescale=1/255.,
        shear_range=0.1,
        zoom_range=0.1,
        horizontal_flip=True,
        preprocessing_function=preprocess_input
    )

    return probs[0][0]

3.本番環境にデプロイする

あとは、作成したDjangoプロジェクトをAWSのEC2にデプロイして、NginxとGunicornをサーバーとして機能させて、XサーバーでElasticIPと独自ドメインを紐づけて完成という流れです。

具体的な手順は気が向いたら記事にします(すいません)。

ちなみに、動かして学ぶ!Python Django開発入門という書籍が、本番環境へのデプロイと公開までしっかりわかりやすく説明してくれていておすすめです。

完成したDjangoプロジェクトはGithubに公開していますので、気になる方は見てみてください(自由に使ってもらって結構です)。

何に苦労したか?

一番苦労したのはアプリの設計のところで、フォームで受け取った画像をうまく処理するにはどういう処理構造にすべきか?ということでした。

いろいろ調べた結果、FormViewのpostメソッドをオーバーライドする方法がスマートだということに気付いて、それからはサクサク作業を進めることができました。

いろんな方法があるとは思いますが、できるだけ手持ちの武器を増やしておいて、適材適所で活用していきたいものですね。

まとめ

今回は、TensorflowとDjangoを組み合わせて、人工知能アプリを作成しました。割愛した部分も多いですが、少しでも同じようなアプリを作っている人の参考になれば幸いです。

Djangoカテゴリの最新記事