« 2016年4月 | トップページ | 2016年6月 »

2016年5月

2016年5月30日 (月)

「りんな」の仕組みをもうちょっと詳しく調べてみた

5月25日に、de:code 2016のセッション「りんなを徹底解剖。"Rinna Conversation Services" を支える自然言語処理アルゴリズム」に参加してきました。 人気のセッションで入場制限になりましたが、ぎりぎり立ち見で参加することができました。 セッションビデオや資料はまだ公開されていませんが、 ニュース記事は以下のものなどが出ています。

今まで、 「女子高生AI bot」たる「りんな」の背後にディープラーニングや機械学習が働いている、 ということは聞いていましたが、 具体的な解説は見かけませんでした。 で、このセッションでは技術解説もあるらしい、 ということで聞いてきたわけです。

セッションは上の記事にもある通り、とても面白い内容でした。 ただ、私は最近ディープラーニングを勉強し始めたこともあり、 ディープラーニングを使っている具体的な場所をもう少し特定できんものだろうか、と思ったのでした。 そこで、 週末にセッション中で言及された論文を元に、 もう少し詳しく調べてみました。 まあ、この論文も、言語処理学会の年次大会(NLP2016)の20分枠の一般発表資料らしく、わりとざっくりした感じですけれども。

ということで、 以下、セッションと論文を突き合わせて考えた私の理解。 まだ説明読んですべてがぱっと分かるような境地ではないので、正しいかどうか自信ないけど。

チャットワーカー

今回調べる対象は、チャットワーカーです。 言葉を入力とし、言葉を出力とする部分。

りんなのフレームワーク

りんな:女子高生人工知能」から「図2. りんなのフレームワーク」

まず、りんなのシステムは、 インターネットから収集した「対話ペア」を学習ネタとして保持しています。 論文では「対話ペア」は厳密に定義されていませんが、リクエストとレスポンスからなる言葉によるやり取りと考えてよいでしょう。 後の話から考えて、 「対話ペア」のプールは「女子高生的ないい感じの会話」が選択されて大量に集められているんじゃないかな。

その上で、チャットワーカーは以下の二つのモデルを対話のエンジンとして使います。

  • ランキングモデル
  • 生成モデル

ランキングモデル

ランキングモデルは検索システムに似たシステムで、 対話ペアの中から、ユーザー入力(リクエスト)に最も類似するものを選び、そのレスポンスを返します。 その類似度(ランキング)を決定するランカーは以下の素性を使います。

  • 翻訳モデル(説明略)
  • 文の長さ
  • AIM言語モデル(説明略)
  • GRU類似度

この最後の「GRU類似度」の計算にRNN(ディープラーニングの技法のひとつ)が用いられています。 de:codeのセッションやその記事で「DSSM + RNN-GRU」として特に詳しく解説されている部分がここに相当します。 大量の「いい感じの対話ペア」を学習させることで、 ユーザー入力に対する各レスポンスの「類似度」(すなわち、「いい感じ対話度」)が出力されるニューラルネットを用意した、ということでいいのかな。 この部分の詳細な説明は、最初に挙げた記事を参照してください。

なお、ランカー自身はブースティング決定木として学習されます。

生成モデル

生成モデルは翻訳システムに似たシステムです。 リクエストを翻訳元言語、 レスポンスを翻訳先言語とみなして 統計的機械翻訳のような枠組みで対話ペアを学習させ、 リクエストからレスポンスを生成させます。

原理的にはここの学習でもRNNとか使うやり方もあるんじゃないかと思いますが、 論文には特にディープラーニングを使っているとは書いていません。

セッションで「りんなが詠む俳句はストックしているのではなく、その場で生成している」という話がありましたが、 俳句の生成は生成モデルを使っているのかな? ランキングモデルから俳句をひねり出せそうな気がしないし。 もしそうなら、その場合リクエストとして何を入力しているんだろう?

ランキングモデルと生成モデルの使い分け

特に書いていないです。 ランキングモデルで選択した対話ペアのランク値があまりに低い場合には生成モデルで生成している、とかかな。 あるいは簡単な言い換えを実現するためとかに生成モデルを使うのかな。 「犬かわいい」から犬を猫に置き換えて「猫かわいい」へ置き換え、とか。 まあ、よくわからん。

思うことなど

もしこの理解が正しいとしてですが…

ディープラーニングの使いどころが思っていたものと違いました。 「いい感じ」を直接学習しているわけではなく、 既存の対話ペアの類似度を算出するのに使われており、その値がランキング判断の一要素として採用されるわけですね。

チャットワーカーは、 大量の「いい感じの女子高生っぽい対話ペア」を様々な技法で学習・活用することでいい感じの対話を実現しているということになります。 りんなのコンセプトが「Emotional AI」ということで、 なんらかの「感情値」みたいなものを計算しているのかと思ってたんですが、 こういう風に「いい感じのもの」を集めて学習させればいいのか。 なるほど。 それとも、一般にbot類はそういう風に作るものなのかな? 知らんけど。

また、このやり方だと、 ちょっと前に起きた、Microsoftの別のbotである"Toy"が不適切な会話を学習してしまった、 というような事件は原理的に起こりにくい、のかな。

あと、 りんなはあまり複雑なステータスは保持しておらず、 入力に対して反射的に回答している、 ということになります。 「その話さっきしたよ」みたいなことが発生するだろうけど、 あまり整合性のある会話を要求されないから、いいのか。

一般に、ディープラーニングをやるには正しくラベル付けられたデータを学習ネタとして大量に用意することが一苦労です。 りんなの場合、「女子高生的ないい感じの対話ペア」を大量に用意しているということになります。 ネガティブな対話ペアを学習させるわけにはいかんので。 この対話ペアの選別ってどうやっているのかな。 手作業じゃあないよな。

余談

「りんな」の名前は"RNN"に由来する、という話があるそうですよ。 セッションで技術部分を説明したりんな開発者のWuさん(上の論文の筆頭著者)はその話について「さて、どうですかね~(ふふふ)」みたいな反応でした。

さらに、セッションスピーカーの砂金さんが「一説によると」として、 「りんな」の名前の由来は"RNN"と開発者の坪井一菜さんの"Kazuna"から来ているらしいと紹介していました。 こちらは、同じくスピーカーだった坪井さんにその場で否定されていましたが。

2016年5月26日 (木)

de:code 2016雑感

今年も予算をなんとかしてde:code 2016に行ってきました。 会社にはまじめなメモを書くんだけど、 ここでは雑感など。

全般

例年通り、 スーツ率低めのお祭りで、楽しかったです。 開発者視点で近い将来の話が楽しくできるのはいいですね。

twitterとかでコミュニティな人たちが楽しそうにがんがん呟いているのを眺めながら、 その他大勢に混ざってうろうろしてました。 実況とかとてもできないしさ。

びわの木

会場(ザ・プリンス パークタワー東京)への道の途中にびわの木が色づいていまして、 そういえば去年も色づいていたなあ、と思って写真を撮りました。 (この記事、写真はこれだけです)

びわの木

キーノート

言うべきことにはすべて触れていて、うまくまとめているなあとは思いますが、 実は微妙に物足りなくて、なんでかなと考えるわけです。

去年のメモを見ると、 今年と同様に二部構成で、 前半はクラウド、後半はデバイスでした。 私には前半のトヨタの事例が一番インパクトありましたが、 他も豊富な事例をもとにしたデモが色々あり、興味深かった。

今年も二部構成なんだけれど、 焦点がぼやけている感じ。特に前半。 今になって考えると、私としてはBuild 2016で出た技術についてのメッセージを聞きたかったのかなあ。 しかし、それは新CTO(榊原さん)の顔見せっぽいパートでざっと触れられただけでした (Cognitive Serviceは後半でもう一度でてきたけど)。 HoloLensも事例とも言えないJALのイメージビデオだけだし。 CEOじきじきのお出ましも、 いつも通りわかりやすい口調で丁寧に説明していましたが、 スピーチ内容は今シーズンの定常ネタ + 日本固有部少し(りんなとか)という感じでした。 が、まあ顔を出しに来てくれたということが大事なのでしょう。 あー、でも、2014年秋のde:code special editionにやってきて、 開発者と同じ部屋でざっくばらんに話していた姿を思い出すと、ちょっとさみしい。

ちなみに、ナデラはんはこの後、 スタッフを激励し中学校のプログラミング授業を見トヨタの社長と会談し(ネクタイしめてるよ)その後東南アジア歴訪だそうですよ。 次の日はタイで講演とか。 えらい人は大変だねえ。

後半も面白いんだけど、 後から見ると機能紹介を並べただけみたいになってたなあ。 あ、でも、ロボティクス関連は新しいか。

セッション

今年は同じ部署から複数人を送り込んだこともあり、 Azure/.NET/Visual Studio系はほかの人にまかせて、 DevOpsとAI関連を主に聞いてました。 それでもセッション数が多くて、 聞きたいのがかぶって色々迷いましたが。

AIについては、 Cognitive Serviceは面白いんだけど、 それを実現する元になっているDeep Learningの話は無いのかなあと思っていたら、 最後の方のセッションでそれらがちょっと出てきました。

りんなのセッションでは、 りんなのどこにDeep Learningが使われているのかの話がありました。 セッションでの言及から言語処理学会の年次大会で発表された論文も見つけたし、 これを起点に勉強してみます。 この論文の筆頭著者でもあるWu Xianchaoさんが、 このセッションでりんなのテクノロジー部分を説明してた人ですね。

ところで、セッションスピーカーの砂金さんは「一説には」として、 「りんな」という名前の由来は"RNN"(りんなで使われているニューラルネットワークの技法)と開発者の坪井一菜さん(キーノートでりんなのデモした人)の名前の"Kazuna"をマージしたものだ、と紹介していました。 同じくスピーカーだった坪井さんは否定していましたが。

あと、続くDBP-014で機械学習系の事例を紹介しており、 その中で紹介程度ですがCNTKが出てきました。

DevOpsは… 牛尾さんのブログは大好きだし、 セッションに来ている人はすごいし、 話聞いていると確かにそうなんだけど、 前途多難だなあ、と思うわけです。 本格的にサービス主体に移るつもりなら、 DevOps体質にならねばやってられないのは明らかなんだけど。 なんかね、キーノートでの伊藤かつらさんの「DevOpsと聞くと踊りだす人」というポジティブ表現が肺腑をえぐるのですよ。 まあ、熱量をためこみつつ、あきらめずにやっていきます。

エキスポ

今回は、redhat、GitHub, JetBrainとか、 今までは少し「別世界」にいた会社が出展していました。

一方、大手総合ITベンダーは完全に消えました。 去年はかろうじて富士通が残っていましたが、 今年はいませんでした。 単なるタイミングの波であればいいんだけど、 もし、ここへの出展が効果をあげていないとの判断だとすると、 従来型SIがタコツボ化しつつある兆候のような気がして不安。

あと、2010年頃まで、 こういう展示会にはでかいサーバーがでーんと置かれており、 わたしらは「冷蔵庫」とか呼んでました。 クラウド時代になって、 そういうのが消えたなあ、と思っていたら、 Dellが久々に置いていましたね。 多分、 Azure Stackを想定したものなんでしょう。

Windows 10 Mobile。 去年はまだIS-12T使ってましたよ。 MADOSMAの実機展示があって色めき立ったのが去年のde:codeで、 今年はといえば、10機種ほどの実機が並んでいるわけですよ。 感無量です。

もしContinuumサポートする機種が買えるならどれがいいかなあと触ってみました。 NuAns NEOに心惹かれはするけど、MADOSMA Q601かなあ。 私はどうやら多少大きくても薄いほうが好みらしいのと、 MADOSMAの中の人に絶大な信頼を持ってしまったので、 この人がいる限り継続的にアップデートされていく(はず)のWindows 10でも 動かなくなることはないだろう、と勝手に思っているからです。

唯一困るのは、ポケットに入らなさそうな大きさであることかな。 私はスマホをポケットに入れておきたい人なのです。 今のQ501ですら胸ポケットからはみ出しているからなあ。 気にせずそのまま持ち歩いているけど。

その他

「配給券」は今年はなし。 自己申告で1日にドリンク2本、ミスドのドーナツ3個まで。

弁当は例年通り、だったと思う。 去年の忘れた。

WiFiはつながるようにはなった。苦し気な時もあるけど。

ちょまどさんのステッカーは入手できず。 一回すれ違ったんだけど、 「あっ」と思って振り向いたらもはや人ごみの中。 毎年のことだけど、 あの通路の混雑どうにかならんものだろうか。

2016年5月12日 (木)

Microsoft Bot Frameworkを使ってSlashのbotを作ってみた(前編)

連休中にMicrosoft Bot FrameworkでBotを作って、 家族内の連絡に使っているSlackのチームに突っ込んでみました。 まずは、特に工夫もない単純なBotだけど。 その話などぼちぼち書いてみます。

Microsoft Bot Frameworkとは

Microsoft Bot FrameworkはBuild 2016において"Conversations as a Platform"の一要素として発表されました。 賢いBotが人間の相手をして、仕事を色々とこなしてくれれば、 GUIとかとはまた違った便利なインターフェイスなるだろう、 そういうBotを作ろうぜ、 という話ですね。

Botを作る話はFacebookも最近発表しました。 Facebookの話がFacebook Messengerを対象にしているのに対し、 Microsoft Bot Frameworkは様々なメッセージングサービスを相手にします。 Botサービスを一つ立ち上げておいて、 それを各種サービス(Email, Slack, Skype, Facebook Messenger, etc.)に繋ぎます。 LINEも対応予定だと言っていたなあ。 現状のメニューには出てなかったけど。

以下の図がよく説明で引用される図です。

Bot Frameworkの説明図

Bot Framework Overviewから

Bot Frameworkは大きく以下の三つの要素からなります。

  • Bot Builder SDKs: Botを簡単に開発できるようにするSDK
  • Bot Connector: 作ったBotをメッセージングサービスに繋ぐサービス(SaaS)
  • Bot Directory: (将来予定)Botを流通させるためのサービス

BotとBot Connectorの関係はこんな感じ。 BotはBot Builder SDKで作らなくても、 インターフェイスを満たせばBot Connectorで繋げることができます。

Bot Frameworkの構成図

Bot Framework Overviewから

メッセージングサービスにBotを送り込む枠組みはこれでよいとして、 「賢い」Botを実装するためには、 賢く状況を認識できるようにしなければなりません。 そのための道具立てが"Conversations as a Platform"のもう一つの要素である"Microsoft Cognitive Services"です。 色々な認識を行うためのサービスが揃っています。 その中のEmotion APIは先月簡単に動かして見ました(前編, 後編)。

さて、ということでSlack上で動くBotを作ってみます。 今編では、まずBot Builder SDKを使ってBot本体を作ります。 次編でBot Connectorを使ってそれをSlackに接続します。

どういうBotを作るか

ファーザーBotを作ります。 以下のセリフをランダムに返します。

  • いいです。
  • わしもですか?
  • みんなもですか?
  • わしがですか?

これは、 「神聖モテモテ王国」のファーザーが発行した紙幣(壱萬ラブ)の四コマ中のセリフです。 これをランダムに返してくれると、 いい感じに壊れた雰囲気になるでしょう。

言語の選択とSDKの準備

まず、言語を選択します。 現状用意されているのはC#またはNode.jsです。 ここではC#を使います。 C#を使う場合は、 Visual Studio 2015 Update 2以降が必要です。 Node.jsを使う場合は、Node.jsとエディタだけでできそう。

C#版SDKは実質的にはテンプレートのみです。 テンプレートのzipファイルをユーザーレベルのテンプレートの置き場所に置くだけです。 具体的には説明の通り。

プロジェクトの作成

ここでVisual Studioを起動し直すと、 「新しいプロジェクト」のC#のプロジェクトテンプレートの中に「Bot Application」テンプレートが現れるようになります。

「新しいプロジェクト」ダイアログ

ここからプロジェクトを新規作成すると、 プロジェクト構成はこんな感じになります。 ASP.NETのWeb APIがベースっぽいですが、 かなりシンプルになっています。

プロジェクト構成

ソースコードの修正

ソースコードの中心部は以下です。 テンプレートの初期実装は入力メッセージの文字数を答えるものですね。

namespace FatherBot {
  [BotAuthentication]
  public class MessagesController: ApiController {
    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<Message> Post([FromBody]Message message) {
      if (message.Type == "Message") {
        // calculate something for us to return
        int length = (message.Text ?? string.Empty).Length;

        // return our reply to the user
        return message.CreateReplyMessage($"You sent {length} characters");
      } else {
        return HandleSystemMessage(message);
      }
    }

これを以下のように変更します。 まあ、まずはシンプルな内容で。

namespace FatherBot {
  [BotAuthentication]
  public class MessagesController: ApiController {
    private static readonly string[] replies = {
      "いいです。",
      "わしもですか?",
      "みんなもですか?",
      "わしがですか?"
    };
    private Random random = new Random();

    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<Message> Post([FromBody]Message message) {
      if (message.Type == "Message") {
        string reply = replies[this.random.Next(replies.Length)];

        // return our reply to the user
        return message.CreateReplyMessage(reply);
      } else {
        return HandleSystemMessage(message);
      }
    }

ビルド

このままプロジェクトをビルドします。 実は、このソースだと「Postメソッドについているasyncの意味が無いぞ」という趣旨の警告をC#コンパイラが出します。 通常、Postメソッドの中では色々仕事をするだろうから、きっと非同期メソッドを呼び出すことだろう、 ということでテンプレートは非同期スタイルでPostメソッドを生成してます。 しかし、現状の内容だと同期的な処理しかしていないので無意味なわけですね。

でもまあ、実害はないので無視しましょう。 asyncを取り除くとそれはそれで同期スタイルに直さなければならなくて手間だし。

デバッグ実行

で、これをデバッグ実行すると、 ブラウザ上にスタートページが表示されます。

スタートページ

このページを開いている間、 Botサービスは動いており、 ページを閉じるとBotサービスのデバッグ実行が終了する、 だったと思うんだけど、 ページ閉じてもデバッグセッションが終了しないな。 ASP.NETのデバッグってそういう動きだったっけ?

まあともかく、 Botサービスを起動している間に、 その動作を試します。 それには、 Bot Framework Emulatorを使うと便利です。

Bot Framework Emulatorは 説明ページのリンクからインストールできます。 なんと、最近ほとんど見ないClickOnceアプリケーションですよ。

Bot Framework Emulatorを使うと、 こんな感じでBotの動きをチェックすることができます。 Bot Framework Emulator側で入力を与えつつ、 Visual Studio側でデバッグを行うことができるわけです。

Bot Framework Emulator

Bot Framework Emulatorを正しくBotに接続させるためには、 Emulatorの上部の帯にある"URL", "App Id", "App Secret"を正しく指定しなければなりません。

"URL"はBotを動かしているアドレスです。 先ほど開いたスタートアドレスのページのアドレスバーを見れば見当が付くでしょう。 注意点としては、BotのAPIのパスは(テンプレートそのままだと)サイトのルートではなく、"/api/messages"になるところですかね。

"App Id", "App Secret"によってBotはクライアントからの接続を認可します。 この値はプロジェクト中のWeb.configで設定されています。

現時点では、 テンプレートから生成された仮の値が入っています。 BotをBot Connectorに登録する際には、 ちゃんとした値を入れることになるでしょう。

スタートページ

次回、BotをBot Connectorに登録し、Slackから利用可能にします。

2016年5月 8日 (日)

ココログの「スマートフォン表示」に無理矢理スタイルを設定してみた

このブログ、 「PC表示」〔ママ〕に対してはスタイルを設定していましたが、 「スマートフォン表示」〔ママ〕に対しては設定していませんでした。 というか、 ココログの追加料金なしのプランでは「スマートフォン表示」にCSSを設定する方法がありません。

携帯版のブログのデザインをカスタマイズすることはできますか? (公式FAQ)

でも、素の「スマートフォン表示」は、 箇条書きが箇条書きにならないし、 表に枠がつかないし、 インデントもうまくできないし、 非常に見づらい。 制限の多かったガラケー時代の名残なのかな?

まあ、 モバイル系がこのままなのもアレなので、 頑張って「スマートフォン表示」に独自CSSを設定する方法を探しました。 結果としては、スマートフォンではなんとかなったんじゃないかな? ガラケーでどう見えているかはわからん。 ガラケーで見ている人はすいません。

別に小綺麗にしたいわけではなく、 単に文章構造を明確にしたいだけなんですけどね。 まあ、ちゃんとカスタマイズできる他のブログサービス使えと言われれば、 そうなんだけどさ。

まず、「カスタムCSS」について確認

ココログのブログ管理ページの「デザイン」の項には「カスタムCSSを編集」というメニューがあり、 独自CSSを設定できます。 しかし、「カスタムCSS」機能は「PC表示」にのみ有効で、 「スマートフォン表示」には反映されないようです。

では、「スマートフォン表示」に有効な独自CSS編集機能は?

前記FAQの通り、追加料金が必要。

なんとか追加課金なしでできないか?

直接的な方法はないし、 可能だったとしても「PC表示」と「スマートフォン表示」で別々のCSS書くのもいやだし、 どうしたものかな、 と考えていたところ、 ファビコンを設定した方法を思い出したわけです。

ファビコン(ブログアイコン、サイトアイコン)を設置してみましょう

これは要するに、 ココログの設定の「ブログのサブタイトル(キャッチフレーズ)」に設定した内容は、 HTML要素も含めてそのままページに埋め込まれるという仕様を利用した方法です。 そんなんでいいのか。

まあともかく、 この方法を流用し、 「ブログのサブタイトル(キャッチフレーズ)」にファビコンを参照するlink要素と並べて、 独自CSSを参照するlink要素を追加したら、 「スマートフォン表示」でもCSSが効くようになりました。

CSSは少し手直しが必要でした。 「PC表示」と「スマートフォン表示」でページの構造が結構異なります。 で、その各構造に割り当てられているクラス名がずいぶんと違う。 が、entry-contentというクラスが記事のコンテナとして共通に存在するので、 それを手がかりにスタイル設定対象を限定できました。 こんな感じ。

.entry-content td, .entry-content th {
  border: solid thin #999999;
  padding: 0.3em;
}
...

後は、 「PC表示」用に従来設定していた「カスタムCSS」は設定が重複するので削除して、 作業完了。 めでたしめでたし。

問題点

「ブログのサブタイトル(キャッチフレーズ)」の内容は、 ブログのページのh2要素の中に埋め込まれます。 ということで、 ページは以下のようになっております。 (このHTMLは説明のためのモノで、指定されているURL等は正しくありません)

<html>
...
 <body>
...
  <h2>サブタイトル
   <link rel="shortcut icon" href="favicon.png">
   <link rel="stylesheet" type="text/css" href="my.css">
  </h2>
...

h2要素中にlink要素を入れてよいのだろうか?

HTML5では大丈夫。 h2要素の内容はフレージングコンテンツであり、 link要素は条件付きでフレージングコンテンツと見なされる。 その条件とは、itemprop属性が存在する場合。 なので、itemprop属性を追加しておきましょう。

厳密には、文法的に許容されるというだけで、 head要素中に記述された場合と同じように機能する保証があるのかはよく分からんが、 まあ主なブラウザで機能しているみたいだし。

なので、 HTML5な「PC表示」ではOK。 ところが、 「スマートフォン表示」はXHTML 1.0なのです。 XHTMLでは、本当はだめだと思うなあ。 XHTMLではh2要素の内容モデルはテキストかインライン要素で、 インライン要素にlink要素は含まれない。 でもまあ、Windows 10 Mobile, iOS, Androidの標準ブラウザで効いているみたいだから、 いいや。

« 2016年4月 | トップページ | 2016年6月 »