ディープラーニングのプログラムを組み直す(2)

相当基本的なところから組み直した。ごちゃごちゃしたプログラムをだいぶ整理した。直しはバグのもとであり、結局、MNISTの手書き文字の認識まで戻ってテストせざるを得なくなった。

ディープラーニングのエンジンである、バックプロパゲーションのところだけは、流石にいじらなかった(笑)ここをいじり始めたら収拾がつかなくなる。

以前は、学習とテストを同じ関数でやっていたが、きちんと切り分けた。CUIからGUIにインターフェイスをレベルアップさせた。

かなり拡張性も出てきたと思う。MNISTの正解率も以前のものと同じものに戻った。オブジェクトというか、クラスをかなり整理したので見やすいプログラムになったと思う。

これで、最適助詞選択プロジェクトに入る。

ディープラーニングのプログラムを組み直す(1)

昨年作ったディープラーニングのデータを組み直している。

もともと、プログラムは複雑である。ネットワークは、レイヤーとニューロンという構造を持っているし、バックプロパゲーションを組み込まないといけないし、さらに、私の場合はオートエンコーダ(自己符号化器)というディープラーニングの手法を組み込んでいる。

前回作ったプログラムは、
https://github.com/toyowa/jautoencoder
においてある。

プログラムの構造が、ネットワークの構造にうまく対応していない。オブジェクト指向が徹底されていないと行ってもいい。

問題はわかっても、直すのは手間がかかる。1年前の自分の頭に戻すのが大変なのだ。

一文章の要約システム(6) : データフォーマットの変更

これまでの話では、「名詞」+「助詞」+「名詞/動詞」の3語のパターンで、深層学習のデータを作ると書いたが、実際できたデータを見ると、前後の語から間の助詞を判断するのは、自分で見ても難しい。そこで、もう一つ助詞をとって、

「名詞」+「助詞」+「名詞/動詞」+「助詞」

のパターンで、はじめの助詞を推定するという構造に変えた。これで日本語wikipediaデータをパースすると、前よりもデータ数は減ったが、それでも、17,588,062対を得ることができた。これで、深層学習のデータを作成しよう。

データ(一部)は次のような感じである。

体:は:羽衣:の
もの:が:付い:て
輸送:において:採算:を
千年:から:エネルギー:を
延長:を:図っ:て
路線:を:中心:に
7日間:しか:目:を
ジラーチ:は:ロシア語:で
ハイダル・アリー:は:戦争:の
その後:も:戦争:は
イギリス:は:マンガロール:に
1784年:に:第二次マイソール戦争:は
マンガロール:で:休戦:と
これ:は:インドの歴史:で
インド:の:民族:にとって
イギリス:に:腰:を
し:て:休戦:を
ウォーレン・ヘースティングス:は:これ:を
国王:と:議会:に
市内:の:殆ど:の
地域:で:最寄駅:まで
線:を:皮切り:に
通常:の:プレイ:で
路線:の:開設:に
210:は:バス路線:の
空白域:を:ピンポイント:で
2004年:から:2008年:にかけて
1780年:は:武装中立同盟:に
ため:に:増発:を
キャンペーン:の:一環:として
ネーデルラント連邦共和国:に対し:先手:を
深夜バス:の:運行:も
武装中立同盟:は:ヨーロッパ:の
6月19日:から:7月17日:まで
間:に:ニンテンドーWi-Fiコネクション:で
結果:は:ヨーロッパ:で
赤字:が:続い:て
7月1日:から:7月31日:まで
イギリス:は:ネーデルラント:が
扇動:と:オランダ政府:の
イギリス:の:攻撃:を
ホウエン地方:の:トクサネシティ:の
フレーズ:を:口:に
これら:の:こと:から
セレビィ:と:ウバメ:の
独立戦争:の:最初:の
これ:を:基:に

大学研究室のロボットサイトを閉じた

大学の研究室サーバー上のロボットサイト「ibot研究会」にあった記事を、全てこのサーバーに移した。そして、大学研究室のサーバーにアクセスするとこちらのURL転送をするように設定した。

このサイトは、私がオーナーである、ibot株式会社の公式サイト ibot.co.jp である。大学のサイトは、2014年から今年はじめまでの、私のロボット研究の経過が詳細に終えるようになっていた。

このサイトは、お名前.comのバーチャルサーバー上に置いてある。月1000円もかからない、超安価なサーバーであるが、まあ、十分使えるし使いやすい。ibot.co.jp以外の、私のwashida.netなどのドメインも、このサーバー上でホスティングしている。osはlinuxである。

ただ、スペックは低い。もし、レスポンスが我慢できなくなるくらい遅くなったら、スペックをあげるつもりでいる。

一文章の要約システム(5) :深層学習による最適助詞の推定

色々考えてきたが、ここに及んで、深層学習に頼ることにした。アイデアをより詳しく語ると、word2vecと深層学習をつなげてみようということだ。

まず、日本語ウィキペディアから拾ってきた、名詞+助詞+(名詞・動詞)のデータは、4000万個になった。両脇の名詞、あるいは動詞から、それらをつなぐ間の助詞をどう推定するのか、データを眺めていてもさっぱりラチがあかない。前後の名詞と動詞を品詞化して、次のような感じにして、情報を集めたが、これでもパッとしない。

巡洋艦(名詞,一般,*,*):が(助詞,格助詞,一般):支援(名詞,サ変接続,*,*)
愛知県名古屋市西区(名詞,固有名詞,地域,一般):の(助詞,連体化,*):上小田井駅(名詞,固有名詞,地域,一般)
古代ローマ(名詞,固有名詞,一般,*):は(助詞,係助詞,*):ギリシア(名詞,固有名詞,地域,国)
インクジェットプリンター(名詞,固有名詞,一般,*):に(助詞,格助詞,一般):対象(名詞,一般,*,*)
祭神(名詞,一般,*,*):は(助詞,係助詞,*):博多区(名詞,固有名詞,地域,一般)
処理(名詞,サ変接続,*,*):が(助詞,格助詞,一般):いくつ(名詞,代名詞,一般,*)
キャピタルワン(名詞,固有名詞,一般,*):を(助詞,格助詞,一般):買収(名詞,サ変接続,*,*)
政権(名詞,一般,*,*):を(助詞,格助詞,一般):とる(動詞,自立,*,*)
婚姻(名詞,サ変接続,*,*):の(助詞,連体化,*):20%(名詞,固有名詞,一般,*)
10節(名詞,固有名詞,一般,*):に(助詞,格助詞,一般):定め(動詞,自立,*,*)
サッカー(名詞,一般,*,*):は(助詞,係助詞,*):0(名詞,数,*,*)
ヤン・ヴァーツラフ・ヴォジーシェク(名詞,固有名詞,人名,一般):の(助詞,連体化,*):作曲(名詞,サ変接続,*,*)
男子シングルス(名詞,固有名詞,一般,*):で(助詞,格助詞,一般):最初(名詞,一般,*,*)
たよっ(動詞,自立):て(助詞,接続助詞,*):霧(名詞,一般,*,*)
人物(名詞,一般,*,*):の(助詞,連体化,*):風景(名詞,一般,*,*)
板垣退助(名詞,固有名詞,人名,一般):が(助詞,格助詞,一般):第2次(名詞,固有名詞,一般,*)
前線(名詞,一般,*,*):に(助詞,格助詞,一般):なり(動詞,自立,*,*)
存廃(名詞,一般,*,*):の(助詞,連体化,*):判断(名詞,サ変接続,*,*)
連城(名詞,固有名詞,人名,姓):の(助詞,連体化,*):憧れ(動詞,自立,*,*)
型(名詞,接尾,一般,*):の(助詞,連体化,*):吸入(名詞,サ変接続,*,*)
地区(名詞,一般,*,*):も(助詞,係助詞,*):発生(名詞,サ変接続,*,*)
王座(名詞,一般,*,*):を(助詞,格助詞,一般):アグスティン(名詞,固有名詞,人名,一般)
ELMS(名詞,固有名詞,組織,*):の(助詞,連体化,*):LMP(名詞,一般,*,*)
たち(名詞,接尾,一般,*):は(助詞,係助詞,*):11月23日(名詞,固有名詞,一般,*)
舞台(名詞,一般,*,*):は(助詞,係助詞,*):ポルトガル(名詞,固有名詞,地域,国)
1944年(名詞,固有名詞,一般,*):に(助詞,格助詞,一般):主税局(名詞,固有名詞,組織,*)
現象(名詞,一般,*,*):について(助詞,格助詞,連語):幾分(名詞,一般,*,*)
湾(名詞,接尾,一般,*):の(助詞,連体化,*):北(名詞,一般,*,*)
代(名詞,接尾,一般,*):に(助詞,格助詞,一般):結婚(名詞,サ変接続,*,*)
上番(名詞,一般,*,*):や(助詞,並立助詞,*):平安時代(名詞,固有名詞,一般,*)
3月(名詞,固有名詞,一般,*):は(助詞,係助詞,*):永田鉄山(名詞,固有名詞,人名,一般)
シュテティーン(名詞,一般,*,*):で(助詞,格助詞,一般):商業(名詞,一般,*,*)
ホルティ(名詞,一般,*,*):は(助詞,係助詞,*):反共主義者(名詞,固有名詞,一般,*)
冏(名詞,一般,*,*):を(助詞,格助詞,一般):討つ(動詞,自立,*,*)
プラットフォーム(名詞,一般,*,*):の(助詞,連体化,*):合計(名詞,サ変接続,*,*)
ショパン(名詞,固有名詞,人名,姓):によって(助詞,格助詞,連語):フルート(名詞,一般,*,*)

品詞を使うことも考えたが、品詞情報はとても弱い。助詞の選択は、品詞で機械的にも止まるものではなく、前後に使われている名詞や動詞の意味に連結しているのだ。

そこで、深層学習を利用しようということになった。前後の言葉を入れると、最適助詞を選び出すようなニューラルネットワークを構築すれば良い。深層学習のjavaプログラムはすでに作ってある。自己符号化型のものだが。

ただ、言葉膨大にある。入力ユニット数を数万に増やすわけには行かない。そこで、言葉をword2vecを用いて、200次元ベクトルで表し、前後の言葉で、合計400次元にすれば、難なく、深層学習で扱える。出力は、助詞のいずれか一つが選択されるように、助詞の数だけのユニットだから、それは、限られた数で良い。せいぜい数十個だろう。

4000万個のうち、3000万個くらいを学習させて、残りの1000万個でテストすれば良い。早速データを作ろう。

自然言語とコンピュータ言語

自然言語(日本語とか英語など)とコンピュータ言語(JAVAとかC++など)は、どう違うんだろうと考えることはままある。

が、ふと、同じようにできるのでないかと思った。

例えば「私は人間である」というのは自然言語だ。これをJAVA的に表すと

String watashi = "人間";

しかし、これが変なのは、「私は学生です」もありえるが、一旦、人間ですを入れると学生ですが入れられなくなるのだ。

だったら、watashiをクラスにすればいい。

class Watashi {
    List<String> attributes = new ArrayList<>();
}

こういうクラスを作っておいて、

Watashi watashi = new Watashi()

とインスタンス化すれば、

watashi.attributes.add("人間");
watashi.attributes.add("学生");

などと、いくらでも私という存在の属性を加えていくことができる。逆にこのインスタンスがあれば、

String reply(String question){
  switch(question){
    case "あなたは何ですか":
        return "私は"+attributes.get(0)+"です";
    case "あなたは学生ですか":
        if(attributes.contain("学生")){
            return "はいそうです";
        }else{
            return "いえ、私は学生ではありません";
        }
   }
   return "わかりません";
}

などと、質問に対して答えることができる。これで、do(する)、playなども関数としてクラスに組み込むことができる。

一文章の要約システム(4) : 助詞の使い方

(3)で書いたように、短くしたときに、重要でない言葉を削除した後の文章のつながりが悪くなって、そのままでは聞き取りにくいところができてしまうという問題の解決に取り組んでいるところだ。

基本的に、削った言葉の前と後の言葉を繋ぐのだが、助詞の使い方が重要だと考えている。そこで、日本語wikipediaから、名詞+助詞+名詞(動詞)というパターンを全て取り出してみた。本来どのような助詞で繋がるかは、文法上決まっていると言っていいのだが、現実には、繋がるべき名詞や動詞の内容というか意味に依存している。

問題は、コンピュータは必ずしも名詞の意味を理解していないので、言葉だけから助詞の選択がうまくいかないと思っている。実際に使われた助詞は、正しいと判断しなければならないので、そのような助詞の使い方を全部拾い出したのだ。

集めたパターンは、例えば次のようなものである。名詞:助詞:名詞というフォーマットになっている。

医療:の:役割
マラソン:では:20km
先:にば:八坂神社
ベスゴ:は:54日間
オンライン:の:ビデオ
ゴム:といった:トラック
スロバキア国民党:と:人民党・民主スロバキア運動
胴:を:籐
心:などが:テーマ
度:か:巣内
観客:の:感情移入
乾隆帝:の:継
劇場:の:休演日
スカルノ:を:党首
サーバ:によって:ウェブ
千葉ロッテ:の:関谷亮太
第一次五カ年計画:による:経済開発
テッド・ターナー:の:MACW
一族:の:大胡
ウマル:は:兄
エミレーツ航空:と:カタール航空
948人:の:死者
一族:の:姓氏
主人公:と:観月
本人:が:原因
池ノ上:の:弥
エンディング:の:クレジット
国籍:が:メキシコ
庭:に:大砲
同法違反:で:罰金
3月:からの:テアトル
高屋窓秋:や:石橋辰之助
デンマーク:の:法学
殺人:の:ハードル
2016年:に:オリックス
リング:などの:精密機械
少将:を:理由
データ:の:数量
魚:を:産
240ドル:から:260ドル
ベスゴ:は:53日間
代用品:として:綿
事故:が:スキャンダラス
映画:が:興行成績
暗黒:の:堕天使
一番槍:の:勇者
ローグ:と:Gエグゼス
金日成:が:拠点
報道機関:が:市議会
間:に:チャナク危機
ネーデルラント:の:南部
車内:に:東京スカイツリー
農家:の:二男
二眼レフカメラ:の:Rollei
データ:の:末尾
魚:を:男
パレスチナ:の:キッチェル
ノズル:から:高圧
魚:を:町

集まった数は、全部で21,678,079対である。この2千万対を削除した前後の名詞に適応するというのが戦略である。

単一文章の要約システム(3) : 知的ロボットのセリフを自動で短くする

単文要約をスムースにすることは、当面する最も重要な課題だと思っている。すでに、過去二階の投稿で、初期の実行方法は示した。そして、実際それは即興漫才ロボットに組み込んでいる。しかし、先の投稿にも書いたように、まだ不十分で、単純にword2vecの距離で測って主語と関係性の薄いフレーズをバサバサと削って短くしているのでは、言葉としてつながりが悪くなって意味が伝わりにくくなってしまうのである。名詞と名詞、動詞と名詞などを繋いでいく助詞の選択が悪いなどの問題がある。

どうするのか?マルコフ連鎖を応用して、文章を生成していく手法があるが、それは、2つや3つの連続することがから、次の言葉を生成するシステムである。その発想を利用して、ある句を削除したときに、削除した前後の句をうまくつなげるように、前の句の助詞を改定していくのが良い。

それを実現するために、大量の文章コーパスから

〇〇□□〇〇

のように、挟まれた助詞に関するデータベースを作成すれば良い。これも、一つのマルコフ連鎖である。

ただ、データが膨大になってしまう可能性がある。あるいは逆にデータの欠落が大量に発生してしまうという可能性もある。どうするのか。少し考える。

ロボット即興漫才の到達点:事務所のネタ見せを終えて

事務所のネタ見せがあり、人前でロボット即興漫才を披露した三度目の機会となった。今回の機会は、全2回と決定的に違っている。単にこれまでの漫才よりもうまくいったということではない。確かに、その点ではよかったのだが、それよりもはるかに重要な意味があるパフォーマンスだった。

まず、漫才台本もその一部である謎かけも、完全にその場で作るものだった。前回は、基本、コアとなる言葉は、私が作るわけではなく、コンピュータが作るものだが、ロボットが聞き取れる言葉については、全て事前に釣らせていた。今回は、そのコアの言葉もすべて、その場でロボットに作成させた点で、私的には「画期的」なことなのだ。

というよりも、これこそ私がお笑いロボットをやりだしてから最もやりたかったことなのだ。それができたという点で、私的にはすごいことだった。

漫才も謎かけも、レベルは低いし言葉がちょっとおかしなところがあったりしたが、今回は、本当に漫才や謎かけになっていた、と私は思っている。

しかも、今回は、ロボットが認識できる言葉をこれまでの3000語弱から、8000語以上まで増やしたのだ。これも画期的だ。というよりも、その場でロボットが自由にネタを作る力を持ったから、単に、聞き取り語彙を増やすだけで、ネタ作りができるようになったのだ。つまり、ロボットが聞き取りできる言葉がいくら増えても、ロボットは基本、ネタを作ることができるシステムになっている。

現在、8000語を認識するために、サリーのtopicファイルをコンパイルする時間として1分以上かかるようになっている。前は10秒か20秒で終わっていたのに。

今後これを、サリー(ロボットnao)がどこまで認識できるかわからないが、数万程度に増やしたい。というよりも数十万、数百万個まで増やしたいのが本音だが。

じゃあ、次の課題は(1)ロボットの認識語彙を数万に増やす、(2)単文要約が、まだ不十分で、要約した文章が、理解しにくくなる時がある。(3)漫才と謎かけネタをよりレベルの高いものにする、などがすぐに思い浮かぶ。(1)は、ただ、語彙を増やしてそれがうまくいくかチェックすればいいだけで、うまくいくところの上限が限界なのであり、確かめるだけで良い。

問題は、(2)の単文要約である。これについては、次の投稿にする。

4000万ツイートから名詞を使用頻度の順に取り出す(2)

具体的な手順としては、ツイートファイルをまず一つにまとめるところからである。

$ cat tweets*.txt > all_tweets_181012.txt

5,358,925,973バイトあった。5Gbである。

集めたファイルを、mecabで分かち書きする。時間も測っている。名詞だけを取り出し、余計なものをカットし、改行を空白に取り替えると次のようなコマンドラインになる。

$ time mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/ all_tweets_181012.txt | grep -e "名詞,一般" -e "名詞,固有名詞" -e "名詞,サ変接続" -e "名詞,接尾" | cut -f1 | tr '\n' ' ' > twitter_wakati_data_noun_181012.txt

これで、1時間40分くらいかけて、名詞だけわかち書きされたファイル出来上がる。名詞だけにしたので、2,459,139,485バイトになった。

20スレッドくらいで並列処理したいので、一個のファイルだと不便だ。次のコマンドで125メガくらいのファイルに分割する。パソコンの並列スレッド数は24だが、全部使って動かすと、パソコンがギクシャクしてくるので。

$ split -b 125m twitter_wakati_data_noun_181012.txt

あとは、javaで処理する。