class: middle, center # 画像分類ボットを作った話 .right[2019/07/12] .right[Yuu Ito] [Webナイト宮崎 Vol.5 ~てげ飲みながらLTしたい~ at ATOMica](https://tegehoge.connpass.com/event/133366/) --- # 自己紹介 - 伊藤 雄(いとう ゆう) - twitter ID: [yuu_ito](https://twitter.com/yuu_ito) - GitHub ID: [u110](https://github.com/u110) - 東京でフリーランスなお仕事しています。 - Webアプリ開発 / データ解析 / データ分析基盤構築など -- - 妻もWebエンジニア - 育休から復帰し5月からバリバリ働いてくれています。(ありがとう!) - 家での会話は息子か技術ネタばかり -- - カワイイ息子 - version: 1.0.5 (2019.7.12時点) - {year}.{month}.{day} でバージョンニングする界隈があるとか --- class: middle, center # カワイイ
今日のLTはカワイイ息子が自慢できればOK! (・∀・) --- class: middle, center # よろしくお願いします!
m(\_ \_)m --- class: middle, center # 本題:
常駐先のフリードリンク在庫管理ボットを作りました。 --- # 某オフィスでは、無料でドリンクが飲める冷蔵庫があります。 - ちなみに一番人気は -- 「特茶」! -- - たいてい最後まで残ってのは -- 「コーラ」! コーラ大好きなので、嬉しい限り。。w -- お酒はないです(´・ω・`) --- class: center # さらに
正面にラズパイ+WebCamを置いて在庫状況がSlackで見えるようになっています。 社内のエンジニアさんが管理してくれています。
--- class: middle, center # Slackボットに画像分類させたら面白いかも? --- # 作ってみた。: Slack連携側 - Raspberry Pi - Slackに写真アップロード - Slack - タイムラインに流れるメッセージの取得 - Outgoing Webhooks を Google App Script(GAS) で受け取る - 対象の写真のみを判断処理に流す - GAS <--> Cloud Function - 判定結果の出力 - GAS --> Slack Incoming Webhooks --- # 作ってみた。: 分類モデル - 分類モデルの作成・学習 - Google Colaboratory - Googleの提供するデータ分析実行環境 - 無料!GPUも利用できる! - Google Drive - 画像データの格納 - 分類モデルの配置 - Tensorflow, Keras - NNモデルの実装フレームワーク --- # Cloud Functionのコード: httpエンドポイント ```python def predict_from_http(request): try: request_json = request.get_json() image_url = request_json['image_url'] results, filepath = predict(image_url) if results["pred_class"] == 1: print("Not Empty") upload_file_to_gdrive(filepath, GDRIVE_FOLDER_ID_NOT_EMPTY) return flask.make_response(flask.jsonify({'isEmpty': False}), 200) else: print("Empty") upload_file_to_gdrive(filepath, GDRIVE_FOLDER_ID_EMPTY) return flask.make_response(flask.jsonify({'isEmpty': True}), 200) except Exception as e: return flask.make_response(e, 500) ``` --- # Cloud Functionのコード: 判定処理 ```python def predict(url): image, filepath = get_image(url) x = get_image_input(image) # model = load_model("./u110_v001.h5") pred = MODEL.predict(x , batch_size=1) pred_class = int(np.argmax(pred)) results = { "pred" : pred.tolist(), "pred_class" : pred_class } return results, filepath ``` --- # Google Colaboratoryの画面
--- # 動作例: 在庫ありの場合
--- # 動作例: 空の場合
--- # 社内の反応 -- - 空→入荷されたタイミングだけほしい - 判定結果が流れているだけだと情報は多い。 -- - --> GAS側でState管理を盛り込んだ。 - 前回が空で今回が入荷の場合は @here -- - 何が残っているかもほしい(コーラは残っているよ、特茶は売り切れ、など -- - ラベリングのカテゴリパターンを増やしてみる(今後のアクション --- # まとめ - GAS + Cloud Functionで分類ボットを作った。 - 元々は技術的な興味で遊びのつもりで始めたが、いろんな反応をもらえた - 何も無いときに判断はできないが、動くものに対して「コレジャナイ」は言える。 - 小さく進めて、少しずつ改善するとピボットもしやすい。 - 初期構成のローンチは昼休み5日間くらいの作業。1人日程度で済んだ。 - 分類ロジックもGoogle Colab、Tensorflow(Keras)でさくっとできる良い時代 --- ## ご清聴ありがとうございました。 - さいごに
東京脱出して地方暮らしを模索中です。
この週末滞在して宮崎のすてきなところ見てまわれたらと思っています。
いろいろお話しましょう!