虎の穴開発室ブログ

虎の穴ラボ株式会社所属のエンジニアが書く技術ブログです

MENU

Teachable Machineとenebularで簡単機械学習!画像判別ボットを作ってみた

こんにちは、礒部です。

虎の穴ラボ 虎の穴ラボ Advent Calendar 2020 - Qiita 8日目の記事になります。

7日目ははっとりさんの 本番で使えるFargate環境構築 - 虎の穴開発室ブログ です。

9日目はS.Sさんが フロントエンドに関する記事 を投稿する予定です。

今回はTeachable Machineとenebularを使って簡単な画像認識アプリを作成してみたいと思います!

アジェンダ

  1. Teachable Machine について
  2. 機械学習モデルを作成する
  3. enebular について
  4. 構造を考える
  5. Flowを組み立てる
  6. 完成!

1. Teachable Machine について

f:id:toranoana-lab:20201113113933p:plain

Teachable Machine

  • Web上から機械学習モデルを作成する事が可能なサービス
  • 画像認識、音声認識、ポーズ認識の3種類が存在する
  • 無料

2. 機械学習モデルを作成する

早速作成してみます。Teachable Machine の 画面右上にある「使ってみる」をクリックし、画像プロジェクトを選択します。

f:id:toranoana-lab:20201113114643p:plain

今回は、二つの単純分岐のクラスを作成してみました。メイドちゃんの青髪とピンク髪の二人をサンプルとして画像を5つ登録します。

サンプルを登録し終えたら、「モデルをトレーニング」ボタンを選択して学習させます。

作成し終えたモデルは、そのままブラウザ上で動作確認ができます。

f:id:toranoana-lab:20201113114942p:plain

登録していない画像でも、 ピンク髪のメイドちゃんだと判別ができています!

正しく学習できている事が確認できました。

f:id:toranoana-lab:20201113150603p:plain

最後に、モデルをエクスポートします。

Tensorflow.js としてクラウド上にアップロードしました。Teachable Machine上に無料でアップロードする事ができます。

アップロードするとURLが発行されるため、このURLで外部からモデルを利用できます。

これで外部からこのモデルを使う準備が整いました。

3. enebular について

f:id:toranoana-lab:20201113165830p:plain

enebular - あらゆるデバイスとクラウドサービスを「つなぐ」、IoTのためのデータ連携プラットフォーム

  • Node-REDのFlowをWeb上から作成できるサービス
  • 無料プランあり

Node-REDは、IoTアプリ開発をノンコーディングで行えるNode.jsのオープンソースソフトウェア。

flows.nodered.org

Node-REDにはTeachableMachineと連携する為のノードが存在するので、今回はNode-REDをWeb上から簡単に扱えるenebularを使ってサービスを作成します。

4. 構造を考える

どのようにFlowを組み立てていくか考えていきます。

flows.nodered.org

flows.nodered.org

Node-REDにはLINE向けのメッセージAPIと画像取得APIのノードが存在します。これを使えばLINE上で対話形式で試してみる事ができそうなので、こちらを利用してみる事にします。

LINE側でbotを作成し、enebularのWebhookURLを設定します。これでメッセージが届いたらenebular側で検知できるようになります。

以下のような構造で作成していきます。

  1. LINEにて、画像が投稿されたらenebular側で検知する
  2. 画像を取得する
  3. Teachable Machineへ画像を渡す
  4. 結果を取得し、LINEに返す
  5. LINEにて、結果を表示する

5. Flowを組み立てる

Flowを組み立てていきます。

http inノードを使い、WebhookURLが実行された時に処理をスタートするようにします。

debugノードに繋げて、レスポンス内容を確認します。

f:id:toranoana-lab:20201113202243p:plain

{
    payload: {
        events: [
            {
                type: "message",
                replyToken: ***,
                source: { ... }
                message: {
                    type: "text",
                    id: ***,
                    text: "テスト"
                }
            }
        ]
    }
}
  • メッセージID(line-imageノードに必要) : msg.payload.events[0].message.message.id
  • replyToken(返答時に必要) : msg.payload.events[0].replyToken

LINEからメッセージを送ると、上記の内容が取得できました。

replyToken は返答時に使うため、別の場所に逃してあげる必要があります。Teachable Machineの返り値も msg.payload に返ってくるため上書きされてしまいます。

functionノードに接続して、msgの構造を変更します。

// msg直下にreplyTokenをコピーする
msg.replyToken = msg.payload.events[0].replyToken;

return msg;

取得したmessageIdを利用して、 line-imageノードに接続し画像を取得します。

取得した画像を利用して、 Teachable Machineノードに接続します。先ほど作成した機械学習モデルのURLを設定します。

ここまでで一度デバッグしてみます。

f:id:toranoana-lab:20201113204148p:plain

{
    replyToken: ***,
    payload: [
        {
            class: "メイドちゃんA(青髪)",
            score: 0.9024636745452881
        }
    ]
}
  • 判定結果 : msg.payload[0].class
  • 判定スコア : msg.payload[0].score

先ほどのモデルから、投稿した画像を使って判定した結果が返ってきました!あとはLINEに返却するだけです。

functionノードに接続して、msgの構造を変更します。

const event = {
    "replyToken": msg.replyToken,
    "type": "message",
    "message": {
        "type": "text",
        "text": `判定結果:${msg.payload[0].class}
判定スコア:${msg.payload[0].score}`
    }
}

msg.payload = {};
msg.payload.events = [];
msg.payload.events.push(event);

return msg;

ReplyMessageノードに接続して、LINEにメッセージを返却します。

最終的な構造はこのようになりました。

f:id:toranoana-lab:20201113204314p:plain

6. 完成!

f:id:toranoana-lab:20201113211258p:plain

画像を投稿すると、数秒後に判定結果を返してくれるようになりました!これで完成です。

今回は全てWeb上で完結する簡単な構成で作成してみました。本格的な学習をさせ、何か業務に組み込めないか試してみたいです。

P.S.

カジュアル面談

弊社エンジニアと1on1で話せます、カジュアル面談も現在受付中です!こちらも是非ご検討ください。 news.toranoana.jp

その他採用情

虎の穴ラボでの開発に少しでも興味を持っていただけた方は、採用説明会やカジュアル面談という場でもっと深くお話しすることもできます。ぜひお気軽に申し込みいただければ幸いです。
カジュアル面談では虎の穴ラボのエンジニアが、開発プロセスの内容であったり、「今期何見ました?」といったオタクトークから業務の話まで何でもお応えします。

カジュアル面談や採用情報はこちらをご確認ください。
yumenosora.co.jp