前回から、ディープラーニングを使って対話ができるコンピュータを作ることを目標に、ディープラーニングに関するさらに詳しい説明に入りました。

前回説明したように、ネットワークに文字を入力する際は、文字を数字に変換するのが一般的です。文を入力するのであれば、文を分かち書きし、それぞれの単語ごとに数字を与え、その数字をネットワークへの入力として扱います。各単語に対してどんな数字を与えるかについてはさまざまなやり方がありますが、ひとまずランダムに適当な数を与えておいて構いません。

次にこの単語が出力されるべき確率は?

さて、これで文字(を表す数字)を入力することはできますが、出力はどうでしょうか。ネットワークから出力されるのは、やはり数字です。入力のときと同様、ネットワークからどんな数字を出力するのかについてもさまざまなやり方がありますが、ここでは一般的な手法として「ある単語が出力されるべき確率」を出力するように学習させます。

例を見ながら、もう少し具体的に説明しましょう。

今、目標としているのは「昨日メロンパンが食べたかった」という文を生成することです。入力が何もない状態から文を生成することはできないので、ここでは「『昨日』という入力に対して、『昨日メロンパンが食べたかった』を出力する」という課題だと考えます。

文はいつも分かち書きの単位で扱います。「昨日」が入力されたのであれば、次に出力されるべき単語は「が」です。そして、「が」が入力されたのであれば、次は「メロンパン」が出力されるべきでしょう。

ネットワークからの出力となるのは「それぞれの単語が出力されるべき確率」です。つまり、出力のなかで最も大きい値に対応する単語が出力されます。以下の例で言えば、上から3番目の値が最も大きい値になれば「が」が出力されるということです。

最も高い確率(大きな数値)に対応する単語が出力される

したがって、「メロンパン」と入力して「が」を出力したいのであれば、「メロンパン」に与えられた数字を入力とし、「が」に該当する箇所の数字(確率)が最も大きく(高く)なるように学習させれば良いわけです。

また、ネットワークから出てくるのは「どの単語が次に出力されるべきか」という確率ですから、使用する単語数は有限である必要があります。単語がいくつあるのかわからなければ、数字をいくつ出力するのかを決定できませんし、どの単語がどの数字に対応しているかもわからないからです。

もし「昨日メロンパンが食べたかった」という文だけ出力できれば良いのであれば、出力する数字の数は文を分かち書きした単語数に等しいので、「昨日」「メロンパン」「が」「食べ」「たかった」に対応する5つとなります。先の図で出力層に丸が5つあるのは、そのためです。

これに加えて「昨日あんパンが食べたかった」という文も出力したいのであれば、「あんパン」という単語も必要ですから、扱う単語の数は「昨日」「メロンパン」「が」「食べ」「たかった」「あんパン」の6つとなります。すなわち、出力層の丸の数は6つとなります。

今、目標としているのは「昨日」という入力に対して、「昨日メロンパンが食べたかった」を出力することなので、教師データは次のように作成すると良いでしょう。

入力 出力
昨日 メロンパン
メロンパン
食べ
食べ たかった

このような教師データを学習すれば、コンピュータは「昨日」という入力には「メロンパン」を出力しますし、「メロンパン」という入力には「が」を出力するようになるでしょう。この教師データを学習したネットワークに、「メロンパン」を表す数字を入力したときの出力例を次の図に示します。

「メロンパン」という入力に対して「が」が出力されるということは、出力された5つの確率のなかで「が」に該当する確率が最も高かったということ

「メロンパン」の後に「が」を出力すべきだとわかれば、次は「が」の後に出力すべき単語を推定する必要があります。この場合、同じネットワークに「が」を表す数字を入力し、またこの5つの出力のなかで最大となる部分を確認すれば良いわけです。おそらく、上から4番目の「食べ」に当たる確率が最も高くなるでしょう。

なお、ニューラルネットワークを取り扱う場合、入力や出力を表す丸を毎回たくさん描くのは大変なので、丸をまとめて長方形で略記することがあります。今後は本連載でも特筆すべき場合以外は、次のように略した図で取り扱っていきたいと思います。

ここではこれまでの図をイメージしやすいように黄色の丸も描いたが、略図の場合は描かないケースが多い

出力したい文が増えると困る!?

教師データを使って学習させることで、「昨日」と入力すると「メロンパン」を出力し、「メロンパン」と入力すると「が」を出力するようにできそうです。

しかし、この方法には大きな問題があります。

「昨日」を入力して「昨日メロンパンが食べたかった」を出力するというのは一例なので、本格的に対話を実現するためにはほかの文も出力できなければなりません。例えば「スポーツ」と入力すると「スポーツがしたい」と出力したり、「ロンドン」と入力すれば「ロンドンに行った」と出力したりといった具合です。

そうなると当然、教師データのなかには「昨日メロンパンが食べたかった」以外の文を分かち書きした単語も含まれてきます。もし「スポーツがしたい」という文も出力したい場合、先の表に加えて次のような教師データも学習することになるでしょう。

入力 出力
スポーツ
したい

これを先ほどの教師データと一緒に学習した場合、「スポーツ」という入力に対しては「が」を出力できるでしょうが、「が」に対しては「食べ」を出力してしまう可能性があります。

同様に、「メロンパン」に対して「が」を出力できても、「が」という入力に対して「したい」が出力されてしまう可能性があるということです。これでは「スポーツが食べたかった」「昨日メロンパンがしたい」というおかしな文章が出力されかねません。

こうした問題が起きる原因は、出力したい単語の直前の単語のみを考慮して次の単語を出力していることにあります。

本来、文を出力するためには、直前の単語だけでなく、それまでに出力した部分も確認する必要があります。「が」の前に出力されたのが「メロンパン」なのか「スポーツ」なのかがわかっていれば、このような間違いは起こらないからです。

次回は、この問題をどのように解決するかについて説明します。

著者紹介


株式会社NTTドコモ
R&Dイノベーション本部 サービスイノベーション部
大西可奈子

2012年お茶の水女子大学大学院博士後期課程修了。博士(理学)。同年、NTTドコモに入社。2016年から国立研究開発法人 情報通信研究機構 研究員(出向)。2018年より現職。一貫して自然言語処理、特に対話に関する研究開発に従事。人工知能(主に対話技術)に関する講演や記事執筆も行う。
著書に『いちばんやさしいAI〈人工知能〉超入門』(マイナビ出版)。
twitter:@WHotChocolate