寿司AIガリオ

ガリオ開発秘話

遠藤 友太

ご挨拶

面白法人カヤックでサーバーサイドエンジニアをしている遠藤と申します。
今回ガリオの実装をメインで担当いたしました。

面白法人カヤックとは、「つくる人を増やす」を経営理念に、新しい技術と面白いサービスを次々にリリースするクリエイター集団です。

ガリオは「技術の無駄遣い」をテーマに面白AIをつくってやろうというのが企画の発端でした。

そのガリオ開発の一部始終を、この記事ではお伝えします。また開発の勘所や裏側をお話しすることで、読者の皆様にIBM CloudやWatsonを使って、どのようにAIを開発するかをお伝えできればと思います。

「ガリオ」のシステムアーキテクチャ

ガリオのシステムアーキテクチャはこのようになっています。

ガリオシステム構成図

またガリオを支える各種技術については「ガリオを支えるIBM Cloudの各サービスのご紹介」をご覧ください。

ガリオでのIBM Cloudの活用

基本的な会話を実現するにあたって意識したこと

ガリオの会話機能を実現するためにIBM CloudWatson Assistantを利用しています。

ここでは会話を実現するコツをご紹介します。
Watson Assistantでチャットボットの会話を実現するにあたって大切なことが3つあります。

1. 会話フローを設計する。

当たり前のように思えるかもしれませんが、会話を設計することがもっとも重要です。
会話フロー図を作成し、会話一覧を表でまとめてシナリオを作成してから作業にとりかかるのがキモです。

ガリオはほとんどの会話が一問一答形式ですが、一問一答でどれだけ自然な会話が実現できるかという点にこだわり、一部の会話だけ連続性を持たせるような設計にしました。

例えば「心握り寿司」「創作寿司」についてはユーザーのインプットを保持して、次の回答を動的に変更しているので、連続性のある会話が体験できます。

※「心握り寿司」「創作寿司」の詳細は「ガリオの職人技」をご参照ください。

2. インテントとエンティティを切り分ける設計

Watson AssistantにはIntentEntityという概念があります。Intentとはユーザーの意図を汲み取るもの、Entityは名詞やキーワードとお考えいただくとわかりやすいと思います。

Intentにはできるだけ名詞やキーワードを含まないようにすることが大切だと考えています。

例えば「お寿司が好き」というインテントを作成し、次のイメージのように定義したとしましょう。

お寿司が好き

この「お寿司が好き」Intentと似た〇〇が好きのようなIntentが増えてしまうと解答精度が落ちてしまう恐れがあります。

いろいろな好き
いろいろな好き結果

そこで上のイメージのような例を、次のように設計することで解答精度が向上します。

Entityは名詞にあたる部分を以下のように定義します。

Entity

Intentは「好き」と定義し以下のような意図を汲み取れるようにします。その上でtry itで同じ内容を再実行します。

好き
好き結果

このようにIntentEntityの役割をしっかり分けることでより精度の高いチャットボットを構築することができます。

3. contextを有効活用する

Watson AssistantにおけるContext(コンテキスト)とは、ノードをまたがって状態を保持する領域のようなものとお考えください。

ユーザーが入力してくれた名前、日付、その他様々な情報をその後の会話でも保持しておきたい場合にContextを駆使することで連続した会話や気の利いたレスポンスをすることができます。

その他Tips
  • Watson Assistantで定義した内容はJSONで構成されていて、ファイル出力することが可能なので、Gitなどのバージョン管理ツールでしっかり管理すると有事の際に安心です。
  • ダイアログは管理コンソールで上から定義した順番に評価されます。
  • ダイアログを追加したり修正した場合Try itですぐに動作確認できます。
  • Content Catalogを利用することで実装コストが減ります。

AIチャットボットのテストの話

ガリオのテスト方法について

ガリオのテストは全て人力で行いました。その結果、様々な課題が浮き彫りになったので、経緯をお話ししたいと思います。

ガリオの機能を検証するためにExcelなどの表に会話のシナリオ一覧を記載して、期待する回答が得られるかを一つ一つチェックしたり、同僚に遊んでみてもらってフィードバックをもらったり、ソフトウェアテストを得意とする方々にテストを依頼したりしました。しかしこのテスト方法は非常に非効率的なテスト方法でした。

会話フローの修正が発生しIntentEntityDialogを更新することで、それまで正常に動作していた会話が成立しなくなってしまったり、予想外の返答がきたりと様々な問題が発生しました。

Watson AssistantIntentEntityを更新することで再学習プロセスが走ります。
その際に今までの優先順位などが変わる可能性があり、ダイアログを追加する場所によって、期待していた回答が得られなくなる可能性があります。

したがって修正する度に全体的におかしな点がないか再確認する必要があります。

以上の課題を踏まえて、どのようにテストをすれば効率的な開発ができるかを次に話します。

理想的なテスト方法について

会話フローをまとめた表からテストを実行するように自動化してあげることが良いと考えています。

例えばSpreadSheetやExcelで会話フロー一覧を定義し、その表の列にユーザーインプットが記載されていたら、その文言を読み込んでWatson AssistantmessageAPIをコールするScriptを組んで、結果を表に出力するだけでかなりの工数削減になります。

このようなテストフローを組まなかったことにより、余計な工数をかけてしまったことから、システムの構築より優先すべきことだったかもしれないと思いました。反省点です。

心握り寿司(感情分析)と創作寿司(提案機能)の話

企画段階でガリオには感情分析機能を実装したいと考えました。
Watsonで感情分析といったらTone Analyzerですが、今回のシステムではTone Analyzerは使っていません。

Tone Analyzerが日本語未対応だったことや、期待する感情の種類が足りていなかったことなど、様々な理由があり起用することを断念しました。

そのTone Analyzerに変わって感情分析を担っているのがDiscoveryです。

では、どのようにDiscoveryで感情分析を実現したのかを説明します。

感情について調査したところ、感情は大きく分けると8つの基本感情で構成されるようです。そのモデルを参考に以下のように分類するように定義しました。

  • 喜び
  • 信頼
  • 恐れ
  • 驚き
  • 悲しみ
  • 嫌悪
  • 怒り
  • 期待

これらの8つの項目にさらに中項目を定義しました。喜びを例に挙げると以下になります。

  • 喜び
    • 平穏
    • 喜び
    • 恍惚

このように3×8=24種類の感情を分析できるように設計しています。

そして24種類の以下のようなJSONデータを作成してDiscoveryに学習させています。

JSONデータ例

{
  "data_type": "心握り寿司",
  "emotion": "喜び",
  "strength": "恍惚",
  "key_words": [
    "随喜",
    "喜ぶ",
    "よろこぶ",
    .....
  ],
  "response": {
    "text": "そりゃめでてぇな!",
    "image": "https://example.com/images/tai.jpg"
  }
}

上記のJSONの説明としては
emotionが8つの大分類でstrengthが3つの中項目になります。
key_wordsに関連するキーワードを登録します。
responseはユーザーに回答する情報になります。

まずはユーザーの入力をこれらのデータが格納されたDiscoveryに対してNatural Language Queryで参照することにより、key_wordsとマッチングします。マッチングしたJSONに含まれるresponseを返却することでTone Analyzerを代用することにしました。

また同じメカニズムを使って創作寿司も実装しています。

創作寿司のJSONの構成は以下のようになって、心握り寿司と殆ど同じ構成になります。

{
  "data_type": "AI創作寿司",
  "genre": "都道府県",
  "area": "北海道",
  "key_words": [
    "北海道",
    "ほっかいどう",
    "ホッカイドウ",
    "ホッカイドー",
    ...
  ],
  "responses": [
    {
      "cuisine": "ジンギスカン",
      "patterns": [
        {
          "text": "寿司はどうでい?舌の上でとろけるぜ。",
          "image": "url"
        }
      ]
    },
    ...
  ]
}

寿司スキャン(画像解析)の話

今回ガリオの開発で最も苦労したのは寿司スキャン機能でした。
Visual Recognitionは少ない画像データでも画像解析できるようになる機能ですが、開発が進むに連れ致命的な問題が発覚しました。

その問題とは白身系のネタがあまりにも似ていることです。

正直、私たち人間でも知識がないと判断できないくらい見た目が似ているネタもあります。

この人間でも難しい画像解析の精度をあげるために、ありとあらゆる手を尽くしました。
どのようにして画像解析の精度を向上させたかを説明いたします。

学習用画像データへのこだわり

最初はプロジェクトの関係者で寿司を食べに。。いえ撮影しました。個室を予約して、寿司を食べずにひたすら写真を撮るとても怪しい団体でした。次々に運び込まれる寿司をただひたすら撮影してました。店員の女性が奇怪な目でこちらを見ていた顔が忘れられません。

そんなこんなで集めた写真をVisual Recognitionに学習させて、いざ検証してみると全然精度がでませんでした。

なぜ精度がでないのか、あらゆる仮説を立てて改善を試みたところ、いくつかわかったことがあります。

精度が上がらなかったと思われる理由

  • 寿司の皿の模様や色が多種多様であること
  • 撮影者によって光の当たり具合がバラバラであったこと
  • 学習させる画像の枚数が多かったり少なかったりまばらであったこと
  • 撮影者によって撮り方にムラがあること

これらの問題を解消するためにもう一度寿司パーティ。。いえ撮影しました。
前回の反省を踏まえて、今回は大量の寿司をお持ち帰りしました。
色があるネタは白いお皿に移して撮影し、白身のネタは黒いお皿に移して撮影しました。

すると前回とは比べ物にならないくらい精度が向上しました。
どうやら皿の色や模様、被写体の光の当たり具合がとても重要なように思えます。

しかし精度が上がったとはいえ、まだまだ運用に耐えうる精度ではありませんでした。
ですが、そんな何度も寿司パーティ。。いえ寿司を撮影するわけにはいきません。

今ある学習用データをもとにどのようにすれば、精度を向上できるのか考えに考えました。
そこで閃いたのが2段構えの画像解析です。

2段構えの画像解析とは

2段構えの画像解析とは、その名の通り画像解析を2回して精度を向上させるという発想です。

具体的にいうと、Visual RecognitionにはCustom Classifierというオリジナルの学習モデルを作成する機能があるのですが、これを2階層にすることで精度の向上を測りました。

まずは1つ目の階層で「赤身」「白身」「イカ・タコ」「軍艦」などのざっくりとした分類を判定します。

sushi

例えば1階層目で「赤身」と判定された場合は、2階層目の「マグロ」「トロ」「サーモン」などを学習したモデルに対して画像解析をします。

akami

1階層目で「軍艦」と判定された場合は、2階層目の「いくら」「うに」「ネギトロ」などを学習したモデルに対して画像解析をします。

このようにまずは大分類で大まかにターゲットを絞ってから、特定のネタに特化したモデルに画像解析をかけることによって精度が飛躍的に向上しました。

正直に申し上げるとまだまだ改善の余地もあります。白身に関しては全然精度がまだでていません。
しかしこの短期間で寿司という特徴が似通っている非常に難しい素材に対して、ここまで精度を向上できたのは素晴らしい成果だと思っております。

Cloud Internet Servicesの話

Cloud Internet Services(以下CIS)は以下のようなセキュアなインターネットサービスを提供するために必要な様々な機能が1つに集約されたサービスです。

  • Webアプリケーションファイアウォール(WAF)
  • DDoS攻撃からの保護
  • ロードバランシング
  • Health Check
  • グローバルロードバランシング
  • キャッシュ
  • TLS

CISは脅威をブロックし、不正なボットやクローラを制限し、帯域幅とサーバー・リソースを浪費する可能性のある、グローバルに分散したクラウド・サービスです。グローバルHTTP(S)リバース・プロキシーおよび管理対象DNSサービス・プロバイダーとして機能します。

他にもアプリケーションおよびインフラストラクチャの停止によるダウンタイムを回避するために、Webサービスおよびアプリケーションの信頼性を向上させるのに役立ちます。たとえば、グローバルロードバランシングでは、Webサービスとアプリケーションを複数の地域に展開できます。

CISは、グローバル・ロード・バランシングが使用可能になっているときに、お客様の要求を最も近い地域に経路指定します。
いずれかの領域に障害が発生した場合、その要求は最も近い次の場所にルーティングされるため、お客様はダウンタイムの影響を受けません。
WebサイトまたはAPIに障害が発生した場合、CISから自動的に通知が送信され、復元時に通知されます。

これらの素晴らしい機能をとても少ないコストで設定できるCISは、とても強力なサービスと言えるでしょう。

Watsonの魅力

今回の開発にあたって思ったWatsonの魅力をご紹介します。

WatsonはAIと言っても複雑な知識は全く不要でAPIを呼び出すだけで結果を得ることができます。
短期間かつ少ないデータでAIを構築できることが最大の魅力と言って過言ではないでしょう。

他にもIBM CloudやWatsonはPaaSやAPIとして利用できるのも魅力的でした。
基本的なWebの知識さえさればすぐに利用できるので、比較的に学習コストが少なく簡単にサービスに導入することができます。

すでにWatsonの様々な導入事例があります。
なかでもコールセンターや自動チャットでの活用が多いようですね。

時間と検証を重ねれば、コールセンターのような複雑な業務でもAIが活かせるにも
ガリオのようなプロジェクトでもWatsonを利用することで自由度の高いAIを利用したサービスを素早く開発することが可能です。

また今回利用したVisual Recognitionは少ない画像でそこそこの精度が出る画像解析ができました。今回は寿司という非常に似たものが多い素材を解析するため、カスタムモデルを何度も作成し直したり素材を再撮影したりなど紆余曲折ありましたが、特徴があるものは数枚学習させればそこそこ精度が出るということもコスト面でもとても魅力的です。

そのため費用面でも非常に低コストで運用が可能です。特にメイン機能であるWatson Assistantの利用料金に関しては運用開始して1週間で¥2,000もコストがかかっていないことがわかりました。

そしてガリオを通して一番印象的だったのはWatsonを利用することでAIを超短期間で構築できたことです。開発から完成まではなんと実質2ヶ月です。開発者の人数もリードエンジニア1名とサポートエンジニア1名という非常に少ない体制で制作しました。

さらに学習コストが少ないことも印象的でした。後述しますが、参考記事を読みながら実装すれば誰でもAIチャットボットをつくることが可能です。

AIと聞くとすごく難しそうだったり専門知識が必要そうに感じてしまいますが、Watsonは難しい知識は不要です。
Watsonを利用してAIチャットボットを作る上で必要なものはやってみる勇気だけです。

そしてIBM Cloudはほとんどのサービスや機能を無料で利用できます。(※制限や制約はあります)

ガリオを支えるIBM Cloudの各サービスのご紹介

Watson Assistantとは
Watson Assistant はチャットボット等、ユーザーとコンピューターが自然言語で対話可能なアプリケーションを簡単に開発するためのサービスです。 機械学習の適用により、ユーザーからの自然言語での入力を理解し、適切な応答を返すことができます。 開発者はシンプルで洗練された統合開発ツールを用いることで、対話の流れを直感的な操作でつくることができます。 また、さまざまな業務に特化した事前定義済みのコンテンツを活用することで、より迅速なアプリケーション開発することが可能です。

参考リンク

Discoveryとは
大量のデータを検索するとともに、データからパターンや傾向を読み取り、適切な意思決定を支援します。 主な機能として、文書取込機能、エンリッチ機能、クエリ機能の3つがあります。 また、Watson Knowledge Studioとの連携により特定の業界や企業特有の言葉や言い回しについても教え込み、より賢く業務を支援することが可能です。

参考リンク

Visual Recognitionとは
Visual RecognitionはWatsonの画像認識機能です。 すぐに使えるようにWatsonが既に学習をしており、画像・映像フレームに写った複数のものや、情景を分析・認識することができます。 また、機械学習によりWatsonに独自の学習をさせることもできます。 すでに、自社製品の認識・分類や、製造ラインにおける欠陥検出といった多種多様な業務で、高い精度の画像認識を少ない画像枚数による短時間の機械学習で実現しています。 さらに、日本語・英語を含む多数の言語で認識結果を返すことができます。

参考リンク

Cloud Foundryとは
Cloud Foundryはアプリを簡単に開発、デプロイ、および拡張することができます。各種プログラミング言語のSDKが用意されているので様々なアプリケーションに対応することができます。

参考リンク

Cloudantとは
Cloudantはデータが必要とされる場所にデータを配置してくれる管理不要の NoSQL データベース・サービスです。オフラインでもオンラインでもデータへのアクセスすることができます。

参考リンク

Cloud Internet Servicesとは
Cloud Internet Services は、Cloudflare の 150 以上の Global Points of Presence (PoP) を使用して、インターネットに接続されているアプリケーション、Web サイト、およびサービスに対して、信頼性、パフォーマンス、およびセキュリティーを提供します。 これには、ドメイン・ネーム・サービス (DNS)、グローバル・ロード・バランサー (GLB: Global Load Balancer)、Distributed Denial of Service (DDoS) 対策、Web アプリケーション・ファイアウォール (WAF: Web Application Firewall)、Transport Layer Security (TLS) およびキャッシングが含まれています。

※前述

Auto Scaleの話
Auto-Scaling for IBM Cloud サービスを使用すると、アプリケーションのコンピュート容量を自動的に増減できます。 定義する自動スケーリング・ポリシーに基づいて、アプリケーション・インスタンスの数が動的に調整されます。

IBM CloudやWatsonを学習する上で参考になる記事一覧

参考にさせていただいた記事も多数あります。著者の皆様ありがとうございます。

IBM Cloud API Docs
【2018/8月最新版】チャットボットを簡単に作れる!Watson Assistant(旧名: Conversation)の色々なTips(メモ)
【2018/8月更新】Watson Discovery Serviceが日本語対応したので、触ってみた【何、それ?】編
Watson チャットボットの作り方 第1回目
Watson チャットボットの作り方 第2回目
Watson チャットボットの作り方 第3回目
IBM Cloud Lite で LINE と Watson Assistant (旧Conversation) の連携よる接客チャットボットをつくってみた
Watson×Unity!初心者でもできる、VR 空間で Unity ちゃんとおしゃべりアプリ!

まとめ

ガリオを実装することでIBM Cloudの様々なサービスを利用することができました。

なかでもWatsonは非常に簡単に自由度の高いAIを構築できるので、みるみる成果が得られて、開発者として本当に楽しかったです。

弊社はプロモーションやキャンペーンのお仕事をお手伝いさせていただくこともあるので、様々な場面でIBM CloudWatsonが活用できる可能性を感じられました。

TwitterなどのSNSを利用したチャットボットでもWatsonを利用することでユーザーにインパクトのある体験を与えることが可能なのではないかと思います。

今後もWatsonを活用した面白コンテンツをつくっていきたいと思っています。

ガリオ開発秘話は以上です。最後まで読んでいただきありがとうございました。

この記事を書いた人
遠藤 友太