はじめに
本記事は、以下の手順をまとめた記事です。
- ABEJA Platform + Google Cloud Functions + LINE Botでサーバーレスな機械学習アプリをつくる
システム構成
- LINE Botに画像を送信する
- LINE Messaging API からの HTTPリクエスト(webhook)をCloud Functionsで受ける
- Cloud Functionsから、ABEJA Platform上にデプロイされた画像分類の機械学習APIにHTTPリクエストを送り、画像のクラスの予測結果を取得する
- 予測結果をLINEに返す
事前準備
機械学習モデルの学習・デプロイ
ABEJA Platform上に機械学習モデルをデプロイします。ABEJA Platformのテンプレートの機能を使うことで、ノンプログラミングで機械学習モデルを学習・デプロイすることができます。
今回は、以下の記事の手順に沿って作成した、花の画像の分類モデルをサンプルとして使用します。
(参考)
ABEJA Platformのテンプレートを使用して、ノンプログラミングで機械学習モデルを学習する
https://qiita.com/yushin_n/items/6852ad042913617d8892
ABEJA Platformのテンプレートを使用して、ノンプログラミングで機械学習モデルをデプロイする
https://qiita.com/yushin_n/items/fb338ca9bd3c685ad691
デプロイメントの画面から、デプロイしたモデルのエンドポイントを控えておきます。
LINE Developersのチャネル作成
LINE Messaging APIを使ってボットを作成するため、まずLINE Developersコンソールでチャネルを作成します。
(参考)
Messaging APIを利用するには
https://developers.line.biz/ja/docs/messaging-api/getting-started/
チャネルを作成した後、「チャネル基本設定」に記載されているChannel Secret
とアクセストークン
を控えておきます。
Google Cloud Functionsのファンクションの作成
Google Cloud Functionsのコンソールからプロジェクトとファンクションを作成します。
Inline editorを選択して、RuntimeにはPython 3.7を指定します。
その後、main.py
にソースコードを書きます。
ソースコードは、line-bot-sdk-pythonのサンプルを参考にしました。
import os
import io
import sys
import requests
import flask
import linebot
import linebot.exceptions
import linebot.models
import googletrans
# set API endpoint
endpoint = os.getenv('ABEJA_PLATFORM_API_ENDPOINT', None)
# set ABEJA Platform credential
user_id = os.getenv('ABEJA_PLATFORM_USER_ID', None)
personal_access_token = os.getenv('ABEJA_PLATFORM_USER_TOKEN', None)
credential = {
'user_id': user_id,
'personal_access_token': personal_access_token
}
# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
print('Specify LINE_CHANNEL_SECRET as environment variable.')
sys.exit(1)
if channel_access_token is None:
print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
sys.exit(1)
line_bot_api = linebot.LineBotApi(channel_access_token)
parser = linebot.WebhookParser(channel_secret)
def main(request):
# get X-Line-Signature header value
signature = request.headers['X-Line-Signature']
# get request body as text
body = request.get_data(as_text=True)
try:
# parse webhook body
events = parser.parse(body, signature)
for event in events:
# initialize reply message
text = ''
# if message is TextMessage, then ask for image
if event.message.type == 'text':
text = u'画像を送ってください!'
# if message is ImageMessage, then predict
if event.message.type == 'image':
message_id = event.message.id
message_content = line_bot_api.get_message_content(message_id)
img_io = io.BytesIO(message_content.content)
content_type = 'image/jpeg'
# post image to api endpoint for prediction
res = requests.post(endpoint, data=img_io, headers={'Content-Type': content_type},
auth=(user_id, personal_access_token))
result = res.json()
# translate english label to japanese
label_en = result['result'][0]['label']
translator = googletrans.Translator()
label_ja = translator.translate(label_en.lower(), dest='ja')
prob = result['result'][0]['probability']
# set reply message
text = u'{}%の確率で、{}です!'.format(int(prob*100), label_ja.text)
line_bot_api.reply_message(
event.reply_token,
linebot.models.TextSendMessage(text=text))
except linebot.exceptions.InvalidSignatureError:
flask.abort(400)
return 'OK'
requirements.txtにline-bot-sdk
とgoogletrans
を追加します。
# Function dependencies, for example:
# package>=version
line-bot-sdk
googletrans
環境変数に、以下を指定します。
-
LINE_CHANNEL_SECRET
(LINEのChannel Secret) -
LINE_CHANNEL_ACCESS_TOKEN
(LINEのアクセストークン) -
ABEJA_PLATFORM_USER_ID
(ABEJA PlatformのユーザーID) -
ABEJA_PLATFORM_USER_TOKEN
(ABEJA Platformのアクセストークン) -
ABEJA_PLATFORM_API_ENDPOINT
(デプロイしたモデルのエンドポイント)
ファンクションをデプロイした後、TriggerのURLをLINE DevelopersのチャネルのWebhook URL
に登録します。これで準備完了です。
*接続確認
をクリックすると「Webhookが無効なHTTPステータスコードを返しました(期待されるステータスコードは200です)」と出てしまいましたが、実際は接続できていました。
LINEでの画像の送信
設定したとおり、チャネルにテキストを送信すると「画像を送ってください!」というメッセージが返ってきます。
また、画像を送信すると、画像のクラスの予測結果とクラス所属確率が返ってきました!
まとめ
本記事では、ABEJA Platform + Google Cloud Functions + LINE Botでサーバーレスな機械学習アプリをつくる手順をまとめました。今回は、5種類の花(デイジー、ローズ、タンポポ、ヒマワリ、チューリップ)を分類する機械学習モデルを使いましたが、HTTPリクエストを送る機械学習APIを変えることで、色々なアプリケーションをつくることができますね
参考
ABEJA Platform + AWS Lambda(Node.js) + LINE Botの事例もあります。
https://qiita.com/peisuke/items/f46e46a98692c3490f15
ABEJA Platformは、トライアルも提供しています。気になられた方は、是非、お気軽にお問い合わせください。また、フォーラムもありますので、是非、ご活用ください。
ABEJA Platformに関するお問い合わせ
https://abejainc.com/platform/ja/contact/
ABEJA Platform Forum
https://forums.abeja.io/