TL; DR
- 東京のふ頭でヒアリの女王アリ50匹以上確認され、広範囲に分散すると国内に定着するおそれがあると環境省が言っているらしい[1]が、アリを見て、ヒアリかそうでないかなど一般人にわかるはずもない
- そこで、一般人でもアリを見てヒアリか判断できるように、AutoMLなるナウい機械学習技術を使い、写真からヒアリかどうか判別できるサービス(外部)を作った。
- 本記事では技術的詳細ではなく、ビジネスで大切とされる、そのサービスの作り方を説明することを目的とする
想定している読者層
サービス企画職、サービス開発職、それらの卵である学生の人たち
はじめに
断り書きとして、ヒアリのようなアリをみつけた場合は、下記にある環境省のサイトを御覧ください。
さて、日本は技術大国と言われ久しいですが、技術大国の通り、大量の材料を輸入し、大量の加工品を輸出している国であります。輸入と輸出そのものは国や国民の生活を豊かにしてくれる有効な手段の一つと言えます。しかし、その副作用として、本来運ぶ予定のなかった「招かれざる客」が輸入品にたまに紛れて国に入ってきます。その中には厄介者になる外来生物があります。それらの生物は生態系を脅かすだけではなく、人間にも襲いかかるものとして問題となる種もいます。その代表例がヒアリと呼ばれる、非常に攻撃性と繁殖力の高い外来生物です。
このヒアリがもし国内に定着すると、生態系を破壊するだけではなく、ヒアリから刺されると激しい痛みを被る危険性があります。そして、割と簡単に国内に定着してしまいます。幸い、現在、国内に定着していることは確認されておりません[1]。しかし、政府の発表の通り、輸入の最前線である埠頭でヒアリが発見されることがあります[1]。そこで、このヒアリがやってくる問題を解決するために、以下の3つの方法を考えました。
- あらゆるものを輸入しない
- ヒアリを含めたアリをすべて駆逐する
- どうにかしてヒアリだけを見分けて撃退する
これらの問題点について考えたところ、以下の通りとなりました。
- あらゆるものを輸入しないとなるとそもそも国の経済が破綻するため、ボツ
- アリをすべて駆逐すると生態系そのものが壊れるため、ボツ
というわけで、3.の「どうにかしてヒアリだけを見分けて撃退する」に主眼を置きます。
どうやったらアリの中からヒアリだけを見つけることができるのでしょうか。ヒアリかどうか怪しいアリを一般の方が発見したしても本当にヒアリかどうかは見分けらません。普通に考えると、疑わしいアリの写真を撮って、専門家に確認してもらう方法[2]があります。しかし、そんなにヒアリの専門家がいるわけではありません。みんなで問い合わせたら、専門家が過労で倒れます。
そこで現代の叡智の結集こと、画像認識技術でアリの判別を機械に行ってもらえば良いという話が出てきます(やっと本題だね!)。
画像認識技術は数学の塊でわけわかりませんが、幸いなことにAutoMLという素人にも画像認識技術をかんたんに取り扱うための技術があります。
本記事では、アリの中からヒアリだけを見つける方法とその方法を見つける手段AutoMLをかんたんに説明します。次に、実際にWebサービスとしてデモをして、AutoMLを用いたサービスを体験してもらうことも目的とします。また、そのサービスの作り方も説明し、理解してもらうことも目的とします
問題の具体化
ここでは安全で簡易的な方法として遠くから写真を撮って、専門家という役割の画像認識アルゴリズムに写真を共有して判定することを考えます。このようにアリの中でも、写真といった画像からアリの種類を調べる問題を詳細画像識別[3](Fine-Grained Image Classification[4], Fine-Grained Visual Categorization[3])といいます。
画像認識アルゴリズムそのものでは一般のユーザに使いづらすぎるので、この詳細画像識別をWebサービスという形で提供することを考えましょう。それでは、専門家という役割の画像認識アルゴリズムをどうやったらサービス開発者が使えるのかを説明しましょう。
AutoMLってなんだ
AutoMLとは参考文献[5,6,7]をまとめると
「人間が機械学習モデルを作成する手続きを一部自動化した手法」
という概念のような気がします。特に明確に決められた概念ではないのではないようです。エンジニアではない人が手軽にモデルを構築したり、人間では作れないほど複雑なモデルをエンジニアが構築するために使われるようです。手軽に使えるサービスとしてGoogleのCloud AutoMLがあります。そこで、今回は、入門編として、Cloud AutoMLのAutoML Visionを用います。
AutoML Visionそのものの使い方は公式のチュートリアルやその他に書いてくださった方(その1、その2)がいるので、
そちらをまずご覧になったほうが良いと思います。本記事では、AutoML Visionを使った「サービスの作り方」に主眼をおいていこうと思います。
サービスの作り方
まず、全体のイメージを湧きやすくするためにデモページを作ったので、試してみてください。
さらに全体のイメージを湧きやすくするために全体のブロック図を図?に描いていてみました。
ユーザインタフェースはGitHub Pagesで具体的な処理はCloud FunctionsとAutoML Visionで構築されています。それぞれ、具体的な役割は次節以降のとおりです。
GitHub Pagesでやっていること
GitHub Pagesではユーザが使い方に戸惑わないようにサービスの使い方や例を表示し、AutoML Visionへ画像を投稿するインタフェースを提供しています。ここでは全体のページから関連する場所だけ抜き出します。余談ですが、この記事に記載されているコードはすべてPublic Domainと明記しておきます。勝手に使ってください。
<div class="jumbotron">
<h1>そのアリ、ヒアリですか?</h1>
<p>話題のAutoMLがお調べ致します。</p>
</div>
<form action="https://us-central1-fireantrecognition.cloudfunctions.net/FireAntRecognition" method="POST" enctype = multipart/form-data>
<input type="file" name="image" size="16" value="" accept="image/jpeg"/>
<input type="submit" value="送信"/>
</form>
見ての通り、Cloud FunctionsへHTTPで画像をPOSTしているだけです。ユーザインタフェースをCloud Functionsに組み込めないこともないですが、URLが混沌としすぎていて第一印象がよくないため、やめておきました。
Cloud Functionsでやっていること
Cloud FunctionsではGitHub PagesでPOSTされた画像をリサイズしてAutoMLに画像を渡したり、AutoMLからの結果をHTMLとして見やすい形を整えることをやっています。
ここでは例によって全体のページから関連する場所だけ抜き出します。
def recognize(request):
# リクエストがポストかどうかの判別
if request.method == 'POST':
# ファイルがなかった場合の処理
if 'image' not in request.files:
with open("./htmls/error.html", "r") as f:
resultHTML = f.read()
resultHTML=resultHTML.format(reason="ファイルが取得できないため")
return resultHTML
# データの取り出し
file = request.files['image']
# ファイル名がなかった時の処理
if file.filename == '':
with open("./htmls/error.html", "r") as f:
resultHTML = f.read()
resultHTML = resultHTML.format(reason="ファイル名が取得できないため")
return resultHTML
# ファイルの存在チェック
if file:
import base64
import cv2
import numpy as np
import traceback
import Params
from google.cloud import automl_v1beta1
# ペイロードの作成。 実はBase64にエンコードしておかないといけないらしい
img_array = np.asarray(bytearray(file.stream.read()), dtype=np.uint8)
img = cv2.imdecode(img_array, 1)
img= cv2.resize(img,(640,480))
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 80]
result, encimg = cv2.imencode(".jpeg",img, encode_param)
imageBin = base64.b64encode(bytes(encimg))
imageString=imageBin.decode()
payload = {'image': {'image_bytes': bytes(encimg)}}
client = automl_v1beta1.AutoMlClient.from_service_account_json('projectkey.json')
prediction_client = automl_v1beta1.PredictionServiceClient.from_service_account_json('projectkey.json')
params = {"score_threshold": bytes(b'0.5')}
model_full_id = client.model_path(Params.project_id, Params.compute_region, Params.model_id)
response = prediction_client.predict(model_full_id, payload,params)
response=response.payload[0]
with open("./htmls/result.html", "r") as f:
# 画像を含んだ結果をHTMLに埋め込む
resultHTML = f.read()
resultString="ある" if response.display_name=="fire_ant" else "ない"
resultHTML = resultHTML.format(image_string=imageString, class_name=response.display_name,
score=response.classification.score,result=resultString)
# response.classification.score
return resultHTML
# GETなどの例外処理
with open("./htmls/error.html", "r") as f:
resultHTML = f.read()
resultHTML = resultHTML.format(reason="想定されていないため")
return resultHTML
# 参考URL
# https://flask.palletsprojects.com/en/1.1.x/patterns/fileuploads/
# https://cloud.google.com/vision/automl/docs/base64?hl=ja
# https://cloud.google.com/vision/automl/docs/predict?hl=ja#automl-nl-example-python
# https://qiita.com/iss-f/items/fcc766fca27f3685025d
AutoML Visionでやっていること
今回はREST API経由で受け取った画像を、AutoML Visionで事前に作ったモデルに入力し、その入力に対する認識結果をJSONらしき文字列で返しています。実はAutoML Visionは認識するためのモデルを作る機能とそのモデルを使って画像の中身を予測する機能があります。今回はその後者を使っています。
余談: AutoML Visionで事前に作ったモデルの性能について
一応、AutoML Visionは認識するためのモデルを作った話も説明しておきます。今回は過去に自力で集めたヒアリデータセットを事前に準備しています。ヒアリデータセットにはアリが写っている画像しか含まれておらず、そのアリがアリかヒアリかの情報をフォルダ名で保存しています。アリの画像は2668枚あり、この内ヒアリの画像は714枚、ヒアリでないアリの画像は1954枚で構成されています。これを学習セット2401枚と検証セット267枚に分けて、学習させた結果、平均適合率は0.972(!)となる学習モデルが構築できたようです(図2、図3)。今回はこのモデルをデプロイして、ヒアリ判定サービスに用いています。
サービスのテスト
以上の通り、作ったサービスを実際に試してみます。
テストデータは、一般的なヒアリの画像とヒアリでない画像、
そして、最近公開された東京埠頭で見つけた女王アリ[1]も判定してみましょう。
まず、以下のヒアリの画像認識結果です。
図6 ヒアリの画像を判定させた結果
次に、ヒアリでない画像を判定させてみましょう。
図7 ヒアリではないアリの画像を判定させた結果
次に、最近公開された東京埠頭で見つけた女王アリも判定してみましょう。
図8 東京埠頭で見つかった、ヒアリの女王アリの画像を判定させた結果(写真は[1]より引用)
図6と図7、図8の通り、AutoMLで作ったモデルはヒアリかそうでないアリか正しく判定できていることがわかります。
考察
想定通り、AutoML Visionにより、ヒアリかヒアリでないかを判定させることが現場の画像からでもできました。しかし、現状のAutoML Visionには説明性がかけています。果たして本当にアリを見て判断したのか、はたまた背景を見て判断したのかよくわかりません。その点についても具体的にアリの場所を検出して、アリで判定するように全体のアルゴリズムを修正する必要があるかもしれません。
また、説明可能なAI(Explanable AI; XAI)も開発が進められており、ヒアリを駆逐するなどの意思決定を行う際の材料としてAIを使いたい場合はそちらを利用することも便利でしょう。なお、このXAIの流れに関連してか、Google CloudではAIのモデルを理解しやすくするためにModel Cardsというサービスを提供しています。
まとめ
本記事では、アリの中からヒアリだけを見つける方法とその方法を見つける手段AutoMLを説明し、実際にWebサービスとしてデモをして、AutoMLを用いたサービスを体験してもらうことを目的としました。実際お試しいただけたでしょうか。
また、そのサービスの作り方も説明しました。ご理解していただけたでしょうか。
こういったAutoMLを用いたサービスはエンジニアだけではなくサービス企画者に簡易にシステムの実装手段を提供してくれます。AIの民主化に向けてエンジニアは日々技術を開発していくのです。
ポエム
今回のようにあえてAutoMLそのものではなく、それを使ったサービスを説明したのにはわけがあります。それはAIという真新しい手段に気を取られ、どういった価値をユーザーに提供するのかを忘れがちになってしまうサービス開発やサービス企画の人たちへメッセージを送りたかったからです。機械学習などのアプローチを採用することは良いと思いますが、最終的にどんな価値を提供できるのかを考え、サービス開発や技術開発を行いたいところです。あとはAutoML自体はそう新しいものでもなく、すでに1年前からお試し記事はありましたし、今年の他のアドベンドカレンダーにも出てきているので、単に解説してもしようがないかなというところがあったためです。
参考文献
[1] 環境省, "東京港青海ふ頭におけるヒアリの確認について(令和元年10月10日の続報)", https://www.env.go.jp/press/107355.html
[2] 環境省, "ヒアリ同定マニュアル",2019, https://www.env.go.jp/nature/intro/2outline/attention/file/hiaridoutei_Ver.2.0.pdf
[3] 中山 英樹,"タカとハヤブサはどこが違う?", http://www.nlab.ci.i.u-tokyo.ac.jp/pdf/ssii2014fgvc.pdf
[4] https://paperswithcode.com/task/fine-grained-image-classification
[5] HELLO CYBERNETICS,"AutoMLとは?",https://www.hellocybernetics.tech/entry/2019/02/09/155618
[6] https://www.automl.org/
[7] Barret Zoph, Quoc V. Le, "Neural Architecture Search with Reinforcement Learning", https://arxiv.org/abs/1611.01578