Amazon Alexa の内部システムの最先端を読む（2018）(2)

# Gunrock のアーキテクチャを見てみる

  さて、Gunrock が一体何をしようとしたのかわかってきたところで、どういう仕組みなのかを見ていきましょう。端的に言うと、以下の[論文中の画像一枚](https://s3.amazonaws.com/dex-microsites-prod/alexaprize/2018/papers/Gunrock.pdf)で済ます。

<img width="80%" src="https://raw.githubusercontent.com/MokkeMeguru/seminar/master/gunrock/img/gunrock_ovreview.PNG">

 とはいえ初見でこれは理解が難しいと思うので（理解できれば後の文章は読み飛ばしてください）ちょいちょいと説明を加えていきます。

 まず左上の **User** に注目してください。これは人間を指しています。つまり今椅子に座っているなりして画面を見ているあなたです。発言は矢印を進んでASRへ進んでいきます。この時点でいう発言は、**音声** となっています。イメージとしてはギジャギジャした例の音声波形みたいな感じです。

 **ASR** (automatic speech recognition) では音声を文字に書き起こす機能を提供します。Gunrockではこの部分は Amazon が提供している ASR の機能を用いたほか、それのエラーに対処する機構を作りました。それは例えば、あんまりにも信用ならないようなテキストがASRから得られた場合に、それを切り捨ててユーザにもう一度繰り返してもらうないし別の表現で喋ってもらう機能です。まあ結局、なんやかんやあってASRから``hello alexa my name is siri`` みたいなテキストが出てきます。

 そのテキストは次に **Neural Language Understanding**（一般にはNLUと言われているようです）というでっかいシステムへポイされます。ここでは上から下へ入力のテキストが *流れていきます* 。この流れる処理設計＋スレッドプール設計が処理速度面で効いたと論文中では言っています。そしてこれがGunrockが特に取り組んだ問題の１つ目です。

 この中身については後で簡単に触れておきましょう。今はなんやかんやしてうまいこと入力されたテキストに対して、カテゴリなどの情報抽出が出来たということにしてください。
 
 すると次にそれらが行くのは **Dialog Manager** という部分になります。ここはGunrock独自のシステムで、左側と右側で上下関係が出来ています。ここがGunrockが特に取り組んだ問題の２つ目です。

 上位にあたる **Intent Classifier** はユーザの3段階のプロセスで対話意図を分類します。１段階目は例えば ``Play music`` や ``set the temparature`` といったAlexaへの命令のようなものです。これに関してはAlexaの機能（音楽をかけるとか）を起動するように促します。２段階目は話題のカテゴリを特定することで、NLUから得られる付加情報（一部後述しますが、Google Knowledge GraphやMicrosoft Concept Graph、Amazon Alexa Prize Topic Classifier なんかから得られるカテゴリ情報です）を元にカテゴリ分類を行います。３段階目は lexical intents と名付けられたもので、ユーザが Gunrock に向かってある対象の好みや意見について質問しているのかどうかなど、ユーザの要求を分析するためのものです。これには正規表現を用いたようです。
 
 上位で処理されたものは、更に **Dialog Module Selector** (図には書かれていないですが、Intent Classifier -> Topic Dialog Modules の部分にあると思ってください。)で Topic dialog Module への分類が行われます。ここで行われていることは、Intent Classifierで行われた情報と、それまでの対話履歴を元に、どの Topic Dialog Module でそのユーザからの発話が処理されるべきかを最終的に決定することです。たとえば対話履歴からその話題について話されることがないとわかっているならば（例えば``話題を変えましょう”と事前に言われていたときなど）はもしその話題に行くべきだと前の部分が言っていたとしてもそれを受け付けず別の Topic Dialog Module に行きます。同様にその話題について話されなければならない場合（その話題の途中など）には直ちにその Topic Dialog Module へ行きます。
 
 下位で処理されるものは、それぞれのTopic Dialog Moduleとそれ以外の一般的な受け答えなどについてです。**Topic Dialog Module** はいくつかの話題についての対話フローが設計されており（つまりこれはかなり手打ちに設計されているということです。）、例えば Animal Module では動物についての話題を処理するためのフローが書かれていることになります。**一般な受け答えなど**、とは例えば ``how old is Lebron James`` といった一般常識のような質問に答えるためのものと、``how old are you`` といった bot への質問の２つに大別されます。前者には EVI と呼ばれる Amazon から提供されるサービス、後者には Universal Sentence Encoder いう文埋め込みの（つまり文をベクトル化する）モデルを用いて処理しています（Backstory と呼ばれる部分。独自のシステムらしいです）。
 
 さてここで Dialog Management へ向かう直線のもとである、**Knowledge Base** (知識ベース) について触れておきましょう。こいつは Reddit や Twitter Moment などから逐次的に得られるデータを knowledge graph へ統合していくシステムになっています。つまり情報源から得られる情報の関係性を調べそれをつなぎ合わせてデータベースに``自動的に''統合していくことになります。（これ、サラッと書かれていますが人間の記憶みたいなことをやっているので地味にすごいなぁと個人的に思っています。）この部分についても後でもう少し詳しく触れたいと思います。

 **Dialog Manager** を通りまして次に行くのは Natural Language Generation （NLG）です。ここでは主にDialog Manager で得られた応答に関する情報を用いて、実際の応答のテキスト、そしてその音声を生成します。こちらでは Template Manager が文生成の主役、Prosody Synthesisは音声合成の主役となっています。

 **Template Manager** はDialog Manager から流れてくる情報をうまく処理して人間が聞くベースとなるテキストにするわけです。というのも 多様性確保のために（同じ文を繰り返さないように）複数の言い方を Dialog Module から得られる応答は持っており、それをうまく選択しなければならないのです。またテンプレートに意図的に穴を開けておくことで動的に応答を生成することができるようになっています。（例えば、天気の話題の気温についての応答で、その温度の部分を空白にしておくことなど）
 
 **Prosody Synthesis** はAmazon SSML format と呼ばれる形式に従ってテキストを音声に変換する処理を行う（これにより番号なんかをうまく読み上げられるようになります）他、独自の機能として、"uh..." といったつなぎの言葉を付け加えることで、より人間的な応答を生成します。また長い文に関しては意図的に文を区切ることで、自然に聞こえるようにしたようです。そしてここがGunrockが特に取り組んだ問題の３つ目になります。
 
 最後に生成された応答の音声をAlexaから出力することで我々ユーザは応答を聞くことになる、ということになります。

# Gunrock の内部システムを深く見てみる (1)
  
  さて、ここでは **NLU (Natural Language Understanding)**　の概要をざっくり説明します。
  
  まず **Segmentation** です。ここでは入力をうまい感じに意味的に分割します。ちょっと難しいので例を出しましょう。例えば入力に、``alexa that is cool what do you think of the avengers``(かっこいいアレクサ、アヴェンジャーズについてどう思ってる？) という入力文があったとします。すると分割記号 <BRK> を用いて、``alexa <BRK> that is cool <BRK> what do you think of the avengers`` という風になります。これを行うために Gunrock は深層学習モデル (Seq2Seq モデル) と入力の音声データにおける空白時間(alexa || that is cool || what do you think of the avengers の 「||」 の空白時間に注目したようです)を用いた検出機構を組み合わせました。

  次に **Noun Phrase Extraction** です。こちらは入力文から名詞句を抽出することを目的としています。名詞句を取り出すと、後述される入力文をカテゴリ分類するときや表現抽出(entity recognition)を行うときに、必要になる名詞句が手に入ることになります。将来的にはこれを発展させて目的語の意味を持っているのか、主語の意味を持っているのか、などの詳しい情報を抽出しこれ以降の手順（例えばカテゴリ分類などへ）活かしていきたいらしいです。
 
  抽出された名詞句は、Google Knowledge Graph や Microsoft Concept Graph 、そして文脈についての情報をを組み合わせて**カテゴリ分類**されます。Stanford CoreNLPや spaCy なんかのツールは、大文字・小文字にその機能を依存させているフシがあるらしく、この場合あまり効果が見込めないと判断したためらしいです。文脈についての情報ってなんだと思いますが、これはGunrockが内部で保持している、「我々は今何の話題を話しているのか」という情報を用いるようです。（つまり映画について話しているならば avengers は映画の名前かもしれない、と考えることができる、ということのようです。）
 
  また名詞句を抽出する際に話している文脈の情報に応じて、**ASRのエラーを推測する機構**も作りました。こいつが何をしているかと言うと、ASRで出てしまう同音語なんかをうまく処理するために、文脈情報を使っています。わかりやすく日本語の例を出しましょう。例えば食事の話題を話しているときに、「はし」という言葉がASRから得られていたとします。すると食事の話題でありますから、「橋」よりも「箸」のほうがそれっぽいですよね。というわけGunrock君は「はし」ｰ>「箸」のほうがそれっぽいだろうと推測します。このようにして文脈情報を使ってASRから得られるテキストを修正するわけです。またこれを行うために double metaphone algorithm を用いていましたが、これはちょっとあまりにも英語英語しているので省略します（英語の発音は詳しくないのです・・・）。
 
  更に **Coreference Resolution** (日本語で言うなら、相互参照の解消となりますがちょっと想像しにくいですね)を行っています。これは例えば文中に現れる ``it, one" などが意味的に（つまりそれが何を指し示しているか）置換します。ちなみに既存手法（Stanford CoreNLPやNeuralCorefのSOTAなもの）は非会話データを元にして訓練されていたので、会話データにはあまり適していなかったそうです。そこでGunrockでは相互参照先になるであろういくつかのキーワード（oneなど）をラベル付けし、それをユーザの発話やシステムの情報なんかを元に置換したそうです。（こういう対象となる問題が異なるために同じタスクでもモデルの適性が統一されないのは、とても難しいところですね。SOTAだからって何でもかんでも解けると思わない方が良いということでしょうか）

 **Dialog Act Prediction**（対話上の役割予測）とはその発言が対話中で、どのような（意見や主張、質問といった）役割を持っているかを予測するための機能です。難しいので例を上げましょう。例えば ``awesome i like books why do you think the great gatsby is a great novel`` という文は、``awesome | i like books | why do you think the great novel`` という風に先述のSegmentationで分割され、Dialog Act prediction で ``awesome [appreciation] | i like books [opinion] | why do you think the great gatsby is great novel [open question]`` という風に役割予測されます。
 
 **Topic Expansion** では、話題を発展させるために、入力された単語から連想される他の単語を ConceptNet という knowledge graph から抽出します。つまりユーザが車の話題について話していると、Topic Expansionが働いて例えば 日産といったメーカーの車名を持ってきます。そして次にその車名について話が広がれば、同様にその車名に関連した内容をすぐに用意することができるようになります。

 **Profanity check** とはユーザの発話が不適切な・反社会的な発話でないかをチェックする部分で、こういった話題を展開してしまうと色々とまずいのでつけているそうです。尚、NLG(Natural language Generation) の Profanity check も同様の機能を提供しています。

# Gunrock の内部システムを深く見てみる(2)
  こちらでは **knowledge base** について簡単に踏み込んでみます。これはDynamoDBテーブルから構成される統合データベースとして実装されています。それぞれのテーブルは各話題に関するデータを集めており、データ源はReddit や Twitter moments, Debaste opinions, IMDB, Spotify といったデータを沢山出しているサイトです。

  またデータは一致するエンティティでまとめられ（例えば”林"と"森"）、エンティティ同士の関係は OpenIE を用いて分析され、Gremlin query language を用いて接続されます。ここにはAmazon の graph databse である Naptune が使われています。
  
  エンティティ同士の関係は、VADER sentiment という極性判定ツールを用いて極性が分析され、それを知識グラフに重みとして乗せているそうです。（この具体的な理由については詳しく書かれていませんでした。文脈を読む限り、ポジティブなほど関係が強く関連があるものとみなすということらしいです・・・）

  ここで注目すべきは、これらのデータの更新が毎日行われているということです。データの更新が比較的に楽であるという点が end-to-end な大規模なモデルに対する強みだと私は思っています（オンライン学習を出されるとちょっと弱いかもしれませんが）。
  
# Gunrock が残した課題
  色々やってうまいこといったこのGunrockですが致命的と言うか仕方ないと言うか弱点があります。それは提案した手法に対して **厳格な実験的分析** ができなかったという点です。どうやらアジャイル開発でゴリゴリと進めて行ってしまった結果、そちらの方まで手が回らなかったようです。とはいえ個人的には、対話システムで厳密な実験分析というのもなかなか難しいのではないかという気もしていますが。
  
  また性別や性格、好みといった**ユーザモデリング**についてもより取り組むべきという点もあったようです。こちらは恐らく計算時間やシステムのスケールとトレードオフなので結構難しそうな課題です。尚Gunrockを開発したチームは、より強い推薦システムを開発することでこれを解決しようと計画しているそうです。
  また**強化学習**を用いて、例えば適切なレストランや観光名所の推薦といったことを行えるようにしたいとも言っています。こちらに関しては不勉強と言うか色々県連研究を勉強したもののあんまりまともに動くビジョンが見えなかったので私は何もコメントできません。
  
  最後にシステムとユーザの対話データを自動的に学習できるような**オンライン学習手法**についても研究したいそうです。こちらも昨今の大規模すぎるモデルにどう適応していくのか、非常に興味がわきますね。

# 目次
[Amazon Alexa の内部システムの最先端を読む（2018）(1)](https://qiita.com/MeguruMokke/items/561e778ccd69e5160c74)
[Amazon Alexa の内部システムの最先端を読む（2018）(2)](https://qiita.com/MeguruMokke/items/83b3d921729b62ae8ee2)

# ソース(文とか翻訳記事とかなんとか)
ここ（研究室ではこの分野あんまり興味持ってもらえなかったので最低でも月1回位は更新してセルフゼミしようかなと思っています・・・issue なんかで色々教えて頂けると喜びます）
https://github.com/MokkeMeguru/seminar/tree/master/gunrock