ChatBotで機械学習

内容

LineのChatBotを使用して手書き数字を認識する機械学習アプリです。機械学習の初心者が試すmnistという数字認識のモデルを使用しています

利用メリット

LineのChatBotを使って機械学習にアスセスすることで、利用のハードルを大きく下げることができます。※ちなみにこのアプリの精度はあまりよくありませんでした。同じ数字とはいえ学習に使った画像とカメラの画像とでは違いが大きいようです

主な利用ツール
  • Python
  • flask
  • ngrok
  • keras
  • PIL
  • Line Messaging Api
Code

from __future__ import unicode_literals

import os
import sys
from PIL import Image
from io import BytesIO
import requests
import json
from argparse import ArgumentParser
from flask import (Flask,
                   request,
                   abort)
from linebot import (LineBotApi,
                     WebhookParser)
from linebot.exceptions import InvalidSignatureError
from linebot.models import  (MessageEvent,
                             TextMessage,
                             TextSendMessage,
                             ImageSendMessage)
from tet import mnistpred

app = Flask(__name__)

channel_secret = "********" 
channel_access_token = "********"

parser = WebhookParser(channel_secret)
line_bot_api = LineBotApi(channel_access_token)
headers = {"Authorization" : "Bearer {}".format(channel_access_token)}
                    
@app.route("/callback", methods=['POST'])
def callback():
    try:
        signature = request.headers['X-Line-Signature']
    except:
        abort(400)
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(400)

    for event in events:
        if event.message.type == "image":
            messageId = event.message.id
            raw_image = requests.get('https://api.line.me/v2/bot/message/{}/content'.format(messageId),headers=headers)
            PIL_image = Image.open(BytesIO(raw_image.content))
            predicted_number = mnistpred(PIL_image)
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text="あなたの送った数字は{}ですか?".format(str(predicted_number)))
            )
        else:
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text=event.message.text)
            )
    return 'OK'


if __name__ == "__main__":
    arg_parser = ArgumentParser(
        usage='Usage: python ' + __file__ + ' [--port ] [--help]'
    )
    arg_parser.add_argument('-p', '--port', type=int, default=8000, help='port')
    arg_parser.add_argument('-d', '--debug', default=False, help='debug')
    options = arg_parser.parse_args()
    app.run(debug=options.debug, port=options.port)

####### other file #######

from PIL import Image,ImageOps
import numpy as np
import keras
from keras.models import load_model

def mnistpred(photo):
  new_model = load_model("mnistmodel2.h5")
  im_invert = ImageOps.invert(photo)
  image = im_invert.convert('L')
  image = image.resize((28, 28), Image.ANTIALIAS)
  data = np.asarray(image, dtype=float)
  data = data.reshape(1, 28, 28, 1)
  data = data.astype('float32')
  data /= 255
  answer = new_model.predict(data).argmax()

  return answer

お仕事のご依頼はcontactからどうぞ