ディープラーニングを使って自分を模した人工知能を作って会話してみた

ディープラーニングを使って自分を模した人工知能を作り、会話しました。

## デモ動画
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">僕を模した人工知能と会話するデモ動画を作りました！<br>人工知能に、「あなたは人工知能だ」という事実を伝えてみました。<br><br>上（ピンク）：僕<br>下（水色）　：僕を模した人工知能 <a href="https://t.co/iEWfNDnghR">pic.twitter.com/iEWfNDnghR</a></p>&mdash; ヒホ（ヒロシバ） (@hiho_karuta) <a href="https://twitter.com/hiho_karuta/status/1068656559406821376?ref_src=twsrc%5Etfw">2018年12月1日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

僕のような言い回しで、僕のような声で、会話してくれます。

## 仕組みの概要
<img src="https://qiita-image-store.s3.amazonaws.com/0/103491/91794fa1-1a3d-e8d2-0cce-a6fd1f51fd0c.png" height="65">

実現したいものは音声対話です。音声対話の主な要素は

* 音声認識
* 会話応答
* 音声合成

の３つです。今回は、音声認識に既存APIを用い、残り２つは自分のデータを集めてディープラーニングしました。それぞれの概要と、苦労した点を書いていきます。

## 音声認識
<img src="https://qiita-image-store.s3.amazonaws.com/0/103491/74efb6e6-07e6-1b13-28b5-1419e994efc0.png" height="65">

音声をテキストに変換するタスクです。今回はchromeに備わっている[Web Speech API](https://developer.mozilla.org/ja/docs/Web/API/Web_Speech_API)を用います。このAPIは、音声が進むと、途中でも推定結果のテキストをコールバックしてくれます。途中の推定は少々不正確ですが、次々表示されるとリアルタイム感があって楽しいので、これを用いました。

リアルタイムに表示できるので、生放送の字幕とかにも便利です。 

**デモ動画**
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">今日の進捗：声質変換音声だと、何言ってるかわからなくなる時があるから、リアルタイムで字幕をつけたい。単純に音声認識使って表示するととても違和感があった。音声の方を遅らせて、字幕の表示間隔を空けてあげるとちょっとマシになることがわかった。どうすりゃいいのかなかなか難しい。 <a href="https://t.co/O1TGfkdGlM">pic.twitter.com/O1TGfkdGlM</a></p>&mdash; ヒホ（ヒロシバ） (@hiho_karuta) <a href="https://twitter.com/hiho_karuta/status/1046801013984780288?ref_src=twsrc%5Etfw">2018年10月1日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 会話応答
<img src="https://qiita-image-store.s3.amazonaws.com/0/103491/7eb035c7-e23c-578b-726e-dd732ab6f832.png" height="65">

なんらかの入力文に、なんらかの応答文を返すタスクです。そもそも会話とは何かなのか定義が難しいのですが、今回は「問いかけの文章を、自分なりの文章にして返す」ものとしました。要約とか、言い換えをして会話を成立させる狙いです。

こうすると、学習タスクは簡単になります。自分の発言テキストを特徴量化し、元に戻すよう学習します（オートエンコード）。学習に必要なデータが自分のテキストだけなので、簡単に用意できます。

特徴量化が十分に汎化できていれば、任意のテキストに対してそれっぽく応答できるはずです。そのため、特徴量化には、大量のデータで学習されたモデルを用います。今回は、文章を特徴量にするdoc2vecを、[pixiv小説で学習したモデル](https://devpixiv.hatenablog.com/entry/2016/09/13/161454)をお借りしました。

特徴量からテキストにするディープラーニングモデルは、LSTM2層の自己回帰モデルにしました。データは、僕がSNSで発言した約１０万のテキストを用いました。リプライ文中のユーザーIDを消したり、一部の固有名詞を消したりなどの事前処理を行いました。

面白かったこととして、過学習させたモデルの方が会話していて面白いなと思いました。１０万テキスト程度の少ないデータでは、頻出単語を使って当たり障りのないことを言います。代名詞が頻出単語なので、「こういうときは、それはそうですね」といった面白くない回答が多く現れました。過学習させたほうが、バリエーション豊かに感じられたので、会話していて楽しいんだと思います。

## 音声合成
<img src="https://qiita-image-store.s3.amazonaws.com/0/103491/2c832388-4074-6431-d863-0f9a8d4be4ef.png" height="65">

テキストを音声に変換するタスクです。今回の音声合成では、テキスト→テキスト特徴量→音声特徴量→音声と変換しました。この２つの特徴量変換にディープラーニングを用いました。

テキストの特徴量化には[OpenJTalk](http://open-jtalk.sp.nitech.ac.jp/)を、ディープラーニングには[音声合成論文の追実装](https://r9y9.github.io/nnmnkwii/latest/nnmnkwii_gallery/notebooks/tts/02-Bidirectional-LSTM%20based%20RNNs%20for%20speech%20synthesis%20(en).html)を、ボコーダは[World](https://github.com/mmorise/World)をお借りしました。学習データは、自分の声を録音した４９０文を用いました。

テキストの特徴量化がなかなかややこしいです。正しくできているのか正直わかりません。音声合成は自然言語処理と音声信号処理の総合格闘技だと聞いていましたが、身をもって体感できました。（勉強にあたって[r9y9さん](https://twitter.com/r9y9)にとてもお世話になりました。ありがとうございます。）

**デモ動画**
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">nnmnkwiiをお借りして音声合成を学習させてみました🎉<br>１つめ：正解　２つめ：合成結果　３つめ：右が正解、左が合成 <a href="https://t.co/oWfMikOJas">pic.twitter.com/oWfMikOJas</a></p>&mdash; ヒホ（ヒロシバ） (@hiho_karuta) <a href="https://twitter.com/hiho_karuta/status/1062014166880313344?ref_src=twsrc%5Etfw">2018年11月12日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 音声対話のフロントエンド
音声対話の３つの要素をまとめる部分はwebフロントにして、chromeブラウザ上で動かしました。webフロントにしたのは、googleのAPIを雑に使いたかったのと、オーディオ周りのOS依存を吸収してほしかったためです。

## ソースコード
今回実装したディープラーニングやフロントエンド周りのコードは、音声合成の学習を除いて全部githubで公開しています（ドキュメントはまだ整備できていません）。

* 会話応答 https://github.com/Hiroshiba/hihobot
* 音声合成 https://github.com/Hiroshiba/hihobot-synthesis
* APIサーバー https://github.com/Hiroshiba/hihobot-tts
* フロントエンド https://github.com/Hiroshiba/hihobot-front

また、この記事には間に合いませんでしたが、自分の人工知能を手軽に学習できるコードを整備したいと考えています。続報をお楽しみに！（下にツイッターアカウントがあります。）

## これから（ポエム）
今回は間に合わせのために、自分のデータのみを用いてできるものを作りました。次はちゃんといろんなデータを用いて会話応答をちゃんと応答にしたいです。

この成果は、ここで終わりじゃないです。いろいろやりたいことのうちの１手目です。この辺のことをやろうとしてる人を多く観測しています。なにか面白いことがあったらぜひ気軽に声をかけて頂ければと思います。

Twitterアカウント → https://twitter.com/hiho_karuta

（この記事は、[ドワンゴ Advent Calendar 2018](https://qiita.com/advent-calendar/2018/dwango)の１日目の記事です。）