HerokuとTensorFlowを利用した、顔画像の推論


はじめに

  • Django で作成した TensorFlow のアプリケーションを、Heroku へ移植します。
  • HerokuUbuntu 18.04 のコンテナを利用することで、OpenCV を利用出来るようになります。
  • ソース一式は ここ です。
  • アプリケーションは https://abe-or-ishihara.herokuapp.com/ です。

Herokuのセットアップ

  • アカウントは、事前に作成しています。
  • Mac でのセットアップしています。
  • Heroku でコンテナを利用し、かつ yml ファイルによる Postgres のデプロイには、beta のプラグインが必要です。
$ brew install heroku/brew/heroku

$ heroku login

$ heroku update beta

$ heroku plugins:install @heroku-cli/plugin-manifest
  • Procfile には、gunicornDjango のプロジェクトを起動するように設定します。
  • Heroku でコンテナを使う場合は、不要な設定です。ただし、ローカル環境でデバッグする場合は必要です。
  • なので、デプロイには、必要ありません。
web: gunicorn project.wsgi --log-file -
  • Heroku で利用する Python のバージョンを指定します。特にこだわりがないので、最新にしています。
runtime.txt
python-3.7.5
  • ライブラリをインストールします。Heroku へデプロイするために追加したのは、django-herokugunicorn です。
  • django-heroku は、HerokuDjango を利用するための色々な設定等をしてくれるものです。
requirements.txt
boto3
django
django-heroku
gunicorn
numpy==1.16.5
opencv-python
pillow
tensorflow==1.14.0
  • .envHeroku をローカルでデバッグする時の環境変数を設定します。
AWS_ACCESS_KEY_ID='your-aws-access-key'
AWS_SECRET_ACCESS_KEY='your-aws-secret-access-key'
BUCKET=abe-or-ishihara
  • 設定ファイルの末尾に、Heroku 関連の設定をします。
project/settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
import django_heroku
django_heroku.settings(locals())

Heroku ローカルサーバーの起動

  • .env の環境変数を読み込みローカルサーバを起動します。
  • http://0.0.0.0:5000/http://0.0.0.0:5000/admin/ へのアクセスを確認します。
  • 推論API や S3 へデータが保存されることを確認しました。
$ heroku local web
[OKAY] Loaded ENV .env File as KEY=VALUE Format
22:07:55 web.1   |  [2019-12-21 22:07:55 +0900] [59955] [INFO] Starting gunicorn 20.0.4
22:07:55 web.1   |  [2019-12-21 22:07:55 +0900] [59955] [INFO] Listening at: http://0.0.0.0:5000 (59955)
22:07:55 web.1   |  [2019-12-21 22:07:55 +0900] [59955] [INFO] Using worker: sync
22:07:55 web.1   |  [2019-12-21 22:07:55 +0900] [59973] [INFO] Booting worker with pid: 59973

デバッグモード、許可ホストの修正

  • 設定ファイルを修正します。
project/settings.py
DEBUG = False

ALLOWED_HOSTS = ['abe-or-ishihara.herokuapp.com']

Heroku へデプロイ

  • Heroku のコンテナの設定をします。
  • アドオンで PostgreSQL を設定しています。コンテナではない、通常の Heroku なら設定無しでOKなのですが、コンテナの場合は明示が必要です。
  • AWS S3 の設定をします。これは、Heroku のコンパネに環境変数が設定され、コンテナの起動時に利用される感じです。
  • languagespython を指定します。バージョンは、runtime.txt に記載のバージョンが利用されます。
  • pipopencv-python には、aptlibopencv-dev が必要なので、インストールします。
heroku.yml
setup:
  addons:
    - plan: 'heroku-postgresql:hobby-dev'
      as: DATABASE
  config:
    AWS_ACCESS_KEY_ID: 'your-aws-access-key'
    AWS_SECRET_ACCESS_KEY: 'your-aws-secret-access-key'
    BUCKET: abe-or-ishihara
build:
  languages:
    - python
  packages:
    - libopencv-dev
run:
  web: gunicorn project.wsgi --log-file -
  • Heroku に環境を作ります。上記の heroku.yml 等に基づき環境が作成されます。
$ heroku create abe-or-ishihara --manifest
Reading heroku.yml manifest... done
Creating ⬢ abe-or-ishihara... done, stack is container
Adding heroku-postgresql:hobby-dev... done
Setting config vars... done
https://abe-or-ishihara.herokuapp.com/ | https://git.heroku.com/abe-or-ishihara.git
  • デプロイするフォルダを git init します。
  • フォルダを Heroku のリポジトリと連携します。
$ git init
Initialized empty Git repository in /Users/maeda_mikio/abe_or_ishihara/django/.git/

$ heroku git:remote -a abe-or-ishihara
set git remote heroku to https://git.heroku.com/abe-or-ishihara.git
  • デプロイ対象を git add . します。
$ git add .

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   app/__init__.py
    new file:   app/admin.py
    new file:   app/apps.py
    new file:   app/data/checkpoint
    new file:   app/data/model.data-00000-of-00001
    new file:   app/data/model.index
    new file:   app/data/model.meta
    new file:   app/font.ttf
    new file:   app/haarcascade_frontalface_default.xml
    new file:   app/migrations/0001_initial.py
    new file:   app/migrations/__init__.py
    new file:   app/models.py
    new file:   app/tests.py
    new file:   app/views.py
    new file:   heroku.yml
    new file:   manage.py
    new file:   project/__init__.py
    new file:   project/asgi.py
    new file:   project/settings.py
    new file:   project/urls.py
    new file:   project/wsgi.py
    new file:   requirements.txt
    new file:   runtime.txt
    new file:   static/abe_or_ishihara.png
    new file:   static/index.css
    new file:   static/index.js
    new file:   static/spinner.css
    new file:   static/title.png
    new file:   templates/index.html
  • コミットして、デプロイします。
$ git commit -am "create tensorflow face predict app"

$ git push heroku master
  • Heroku 上でデータベースの確認、マイグレーションと管理ユーザーの作成をします。
$ heroku pg
=== DATABASE_URL
Plan:                  Hobby-dev
Status:                Available
Connections:           0/20
PG Version:            11.6
Created:               2019-12-21 13:39 UTC
Data Size:             7.7 MB
Tables:                0
Rows:                  0/10000 (In compliance)
Fork/Follow:           Unsupported
Rollback:              Unsupported
Continuous Protection: Off
Add-on:                postgresql-tapered-15660
$ heroku run python manage.py migrate
$ heroku run python manage.py createsuperuser
Running python manage.py createsuperuser on ⬢ abe-or-ishihara... up, run.2569 (Free)
ユーザー名 (leave blank to use 'u49624'):
メールアドレス:
Password:
Password (again):
Superuser created successfully.

Heroku へアクセス

おわりに

  • HerokuDjango TensorFlowOpenCV を利用したアプリケーションのデプロイをしました。
  • Heroku は、コンテナで Ubuntu を使えるので、大体の事ができます。今回は、OpenCV を使うため、コンテナを利用しました。
  • CPU は、AVX (Advanced Vector Extensions) に対応しているので、TensorFlow もOKです。今時、AVX対応していない方が、珍しいですけどね。
  • これで、一連のアプリケーション作成が終了しました。次回は、まとめをしたく思っております。