にほんごのれんしゅう

日本語として伝えるための訓練を兼ねたテクログ

ウィキペディア日本語版 tf-idfのidf辞書の公開

nora(野良)-idf-dic

モチベーション

ダウンロードリンク

  • Dropboxにアップロードしております。

www.dropbox.com

フォーマット

  • idfはjsonのdict型(ハッシュマップとも言います)です。
idf = { term1: weight1, term2:weight2, ... }

このようなフォーマットになっており、単語とidfの重みがペアになって格納されています。

式の説明

  • tf-idfはヒューリスティックなものなので、そもそも明確なんてないんですが、一番、わたしとわたしの周りが使う式を示します。
  • 発展的な知識が必要ならば、英語版Wikipediaを見て更にどういうことなのか理解してみるとよいです。

f:id:catindog:20170215222337p:plain

  • あんまり全体に渡って出現しない単語は、重要だろうという仮説に基づいています。そしてそれは、往々にしてうまくいきます。
  • tfはドキュメントdに於けるtの発生頻度です。

以下は実際にmecab等をインストールして、ゼロからidf辞書を作成する例なので、idf辞書を利用するのみなら参照する必要はありません。

プロジェクトの取得取得と、周辺ソフトウェアウェアのインストール

LevelDB(kvs)のインストール
(Ubuntu 16.04以上を想定しています)

$ git clone https://github.com/google/leveldb.git
$ cd leveldb
$ make 
$ cd include
$ sudo cp -r leveldb
$ sudo cp -r leveldb/ /usr/local/include/
$ cd ..
$ cd out-shared
$ sudo cp lib* /usr/local/lib/
$ sudo ldconfig
$ cd ~

mecabのインストール

$ sudo apt install mecab libmecab-dev mecab-ipadic
$ sudo apt install mecab-ipadic-utf8

mecab-python3, plyvelのインストール

$ git clone https://github.com/GINK03/tiny-japanese-wikipedia-tfidf-dic-generator
$ sudo pip3 install mecab-python3
$ sudo pip3 install plyvel

NeoLogdのインストール、及び辞書の書き換え

$ cd ~
$ git clone https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd/
$ ./bin/install-mecab-ipadic-neologd
[install-mecab-ipadic-NEologd] : Do you want to install mecab-ipadic-NEologd? Type yes or no.
>yes
$ sudo vi /etc/mecabrc
()dicdir = /var/lib/mecab/dic/debian -> (変更後)dicdir = /usr/lib/mecab/dic/mecab-ipadic-neologd

Neologdのテスト

$ echo "Fate/Grand Order" | mecab
Fate/Grand Order        名詞,固有名詞,一般,*,*,*,Fate/Grand Order,フェイトグランドオーダー,フェイトグランドオー ダー
EOS

動作確認

$ cd ~
$ cd tiny-japanese-wikipedia-tfidf-dic-generator
$ python3 nora-idf-dic.py
(何も表示されなけばOK)

Wikipediaのダンプ情報の取得

Wikipediaのスナップショットと呼ばれる情報を取得し、展開します。

$ wget https://dumps.wikimedia.org/jawiki/20170201/jawiki-20170201-pages-articles-multistream.xml.bz2
$ bunzip2 jawiki-20170201-pages-articles-multistream.xml.bz2

idf辞書を構築します。

$ python3 nora-idf-dic.py --wakati
(...60分ほど待ちます)
$ ls 
title_context.ldb(このディレクトリがあればOK)
$ python3 nora-idf-dic.py --build
(...3分ほど待ちます)
$ ls words_idf.json
words_idf.jsonls

tf-idfでベクトル化する

具体例を記しておきます。

$ echo "あなた狩りごっこがあまり好きじゃないけものなんだね"  | python3 nora-idf-dic.py --check
{'': 4.926646596986834, 'ない': 2.042401886218362, '': 2.8119346405476735, '': 1.2142350698667934, 'じゃ': 6.054326132384362, 'あなた': 5.476151075317936, 'ごっこ': 8.627077870130083, '': 3.364157726200682, '狩り': 7.11635016692977, '好き': 4.97306829447642, 'けもの': 9.584680272531994, 'あまり': 5.093448481495583, '': 1.6713533531785785}

keyを数値としてindexを振っていけば、libsvmやXGBoostやLightGBMで入力可能なフォーマットになります。
別にこのスクリプト経由で読み出すのではなく、jsonファイルだけ読み込んで、好きなように使っていただいて構いません。

コード

  • Wikipediaは巨大なコーパスなのでまともにはオンメモリでは処理できません。メモリに収まらない操作をコツコツとkvsを使いながらなんとかするという感じです。
  • githubにあげておきました。

github.com

ライセンス・その他

  • Text of Creative Commons Attribution-ShareAlike 3.0 Unported Licenseというライセンスに準拠
  • Wikipediaを参照してください

Wikipedia:クリエイティブ・コモンズ 表示-継承 3.0 非移植 - Wikipedia

  • Wikipediaのデータは2017/02/01時点のスナップショットです
  • 形態素解析エンジンにMeCab + NeoLogd(2016/12時点)を利用しました

StackGANによるフォントの錬金術

StackGANによるフォントの錬金術

f:id:catindog:20170205152727p:plain

図1. 中央が錬金したフォント

近況

f:id:catindog:20170205152954j:plain

図2. 真理の一撃を放とうとするカリオストロさん(公式絵より)
 グランブルーファンタジーというスマホのゲームでカリオストロというキャラクターがいます。もとは天才錬金術師で、自己の性別を錬金術で男から女に変えた天才です。そんな彼(彼女?)が真理の一撃だー!っていうんですよ、かっこよいですね。
 あまりにも今までの不可能を打開し続けるDeep Learning。自分で言うと甚だ科学としての機械学習が零落しそうですが、まだDeep Learningは体系化された知恵の集合体としての正しい科学の段階にはたどり着いていないように思います。どちらかと言うと錬金術に近い技かも。
 Deep Learningは、いつかまだ見ぬ真理へと人類を導いてくれるんでしょうか。各人、期待しております。

モチベーション

  • 日本語のフォントを作成する際に、デザイナは膨大な時間的・肉体的・精神的な労力を払うことになる[1]
  • フォントのデザインを見ているとある一定の法則があることがわかる。それは、大まかなフォントのデザインの土台があってデザインを装飾するように、なんらかの固有な表現が付加されている
  • これはディープラーニングで情報を付加する特徴を覚えさせ、変換させるのに適した好例である
  • 単純な情報付加では、pix2pixでも可能であろうが、StackGANと呼ばれるGANを複数回重ねることでより高度に近づけたい画像に近づける手法を適応する[2]

先行研究

StackGANについて

 StackGANは少ない情報からよりもとの絵に近い情報を復号するのに適しているネットワークである。
 もとの論文ではSkip Thought Vectorsを用いて文章からの画像の生成であるが、Skip Thought Vectorsの代わりに、画像のベクトルを入力する。条件を同じようにするため、DCGANで用いられるノイズも付与する。
 ネットワーク構成図を書き直した。
f:id:catindog:20170205153835p:plain

図3. 今回用いたネットワーク

実験手法

  • 論文を読んでChainerで実装した
  • 何度か実験したところ、二段目のGANにて勾配消失を起こしてしまうのか、一段目のGANの出力結果に強く引っ張られてしまったので、学習レートを大幅に引き下げるという処理を入れた。本当は一定のiterationが回るまで、学習を遅延させたいのだが、今のところ実装に至っていない。
  • フォントを2種類要した。
  • 書道のようなフォントである青柳隷書フォント、windowsで標準でインストールされているHGP創英角ポップ体の2つを検証対象とした
  • フォントの選択条件は、夏目漱石の「坊っちゃん」、「こゝろ」、「吾輩は猫である」で使用されている3313語を用いた。そのうち、800語を別途検証用データとして学習用データとは区別した。[3]
  • 各種パラメータは、一回目のGANはFacadeと同様で、二階目のGANはそれを1/5にしたものである。詳細なパラメータサーチは別途、本格的な生成タスクで行うことにした。

f:id:catindog:20170205154127p:plain

図4. 青柳隷書フォント、人手で書いたデータをスキャンしたらしい


f:id:catindog:20170205154228p:plain

図5. Windowsに入っているあのダサいフォント

結果

  • Inputが入力ベクトル作成に用いた画像
  • Predictが出力結果
  • Ground Truthが人間の職人が作成したフォントである

f:id:catindog:20170205154409p:plain

図6. 青柳隷書フォント学習による出力結果


f:id:catindog:20170205154501p:plain

図7. HGP創英角ポップフォント学習による出力結果

考察

  • Ground Truthに情報量的に近い習字の字ではないけれど、習字っぽい字が表現可能なのはGAN故にだろう。入出力の誤差の最小化が目的でないので、人間が書いた文字は潜在的に大きなノイズや誤差を含む。その点を吸収してくれているように思う。
  • もともとは同人フォント作家の作成コストを下げられるような仕組みがあればと思って、コーディングを開始したものである。今現在、開発が止まってしまっている東亜重工フォントの足りてないフォントの穴埋めや、人間がフォントを作成する際の下書きに用いられたら良いと思う。[3]

Future Work

  • StackGANのパラメータを調整して、下書きから漫画を一気に作成するなどしたい(データない)
  • 音声の問題にも適応できる気がしてて、周波数成分をルールにしたがって上げたり下げたりする作業を、GANにやらせればより人間っぽくなるっしょって思惑があって、男性でも女性のキャラクタを演じたり、その逆ができるように感じる。
  • パラメータサーチや、ネットワーク構造の問題だけでなく、今回は周りの学習の安定度に応じて学習を開始してほしいというニーズが発生したので、その辺を実装していきたい
  • 一応ConditionalStackGANに簡単にする方法があって、その方法を図示すると、こんなふうになる(と思う)

f:id:catindog:20170205155408p:plain

図8. Conditional StackGAN

参考文献

[1] 文字数14000字! 手書き毛筆フォントができるまで http://portal.nifty.com/kiji/151118195086_1.htm
[2] StackGAN: Text to Photo-realistic Image Synthesis
with Stacked Generative Adversarial Networks https://arxiv.org/pdf/1612.03242v1.pdf
[3] 「シドニアの騎士」に出てくるフォントを再現する「東亜重工電子書体化計画」が公開中止に http://gigazine.net/news/20140702-toa-heavy-industries-font/

謝辞

 インフルエンザか風邪だかわからないが熱が下がらない。隣の席の上司がインフルで休んでいるので、多分インフルなんだろう。つらい。
 そんな中、今週は業務では主にAWSとAnsibleとの戦いに時間を割いていたのだが、やはり機械学習やってる方が気が楽...(エンジニアに向いてない疑惑)
進捗なしかとおもいきや、やっぱり音楽とMMDのちからでなんとか乗り切った。MMDでは艦これで山風のモデルが多数のアーティストによって頻繁なアップグレードが行われている。非常にクオリティが高く、尊い
作品中でも、山風は江風と海風と一緒にいじられることが多いのだが、この三人を組み合わせるとヤバい。それぞれの方向性が異なる性格のベクトルが見事に調和していい感じにまとまっている。興味のある人はYouTubeで「山風 MMD」で検索しよう。
MMD職人に感謝である、GPL v3ライセンスとかにしたほうがいいのではと思う。
f:id:catindog:20170205155704p:plain

この三人組すごい好き

RNNのアンサンブルによる音楽の新規創出

近況

Qiitaに投稿しない理由なのですが、自分はQiitaを技術ナレッジのレポジトリのような使い方を想定してしていて、実際、多くの方が素晴らしい技術的なプラクティスを提供なさっています。
 古い言葉でチラシの裏という表現がありますが、今回の私のは、ブログが良い選択肢であるの思うのです。十全な責任を持てない発信やSNSでの補足が必要になるレベルになるものに関してはブログを利用しています。

モチベーション

 RNNという技術がなんともオワコンと言われているので、手向けに興味があった音楽の生成を行うことにしました。

f:id:catindog:20170129211338p:plain

図1. いーあるふぁんくらぶと千本桜を合成したらどうなるの?

 機械学習が流行りだしてから、まるで機械学習といえば絵を描いたり、音楽を奏でたりということができるという認識がニュースで流行りだしたりしていて、実際にやってみた系の記事が、音楽であったでしょうか。Qiitaではありますが、あれは音楽をRNNに記録させて取り出したというもののような気がします。[0]

 RNNといえども、基本はニューラルネットワークに情報の符号をモデルに刻み込んでいくスタイルなので、どうしてもある程度特徴量の抽出はするものの、そのまま覚え、覚えた内容をそのまま出力するという流れになりがちです。[1][2]

 自然語処理の分野でも、他の方が自分の著書を書いて、その内容を記録させるということをしていますが、その著書の範囲のコンテンツしか創造能力が獲得できません。[11]
 
 特段新しい手法ではない(と思うの)ですが、複数のモデルの結果を合成(この文脈ではアンサンブルと呼ぶ)することで創造能力の獲得を目指します。
 
 CNNなどの識別タスクやGANなどの生成タスクでの応用などが考えられます。

前提

この世に完全なるオリジナルは存在しない

 なんとも哲学的な題材なので、正直これについては述べたくなかったけど、これを最初に言っておかないと後が続かない気がするので言いますと、多くの芸術家が言っていることとして、オリジナルは存在しなく、創作物は何らかの参照と引用で構築されているという意見です。[3][4]
 これは今の私には否定出来ないことなので、正しいと思うのです。

ピカソとポーラ・シェールの本質であるコンビナトリアル・クリエイティビティなど、ネットワーク化された知識です。私たちが真に創造し世界に貢献するためには、無数の点を結びつけ、豊かな分野のアイデアを相互に結びつけ、これらの要素を結合して再結合させ、新しい城を建設することができなければなりません。[4]

提案

複数音楽を学習したモデルを合成することで新規性を獲得する

 人間がいくつかの経験をし、新たに直面する問題に対処するときは、おそらくそれまでの経験の幾つか思い出して手法を組み合わせて対処するかもしれません。それを真似しようという発想です。
 RNNとは、過去の出力状態に依存した確率場を表現する出力をするものというものです。mutableなニューラルネットワークです。
 もう何度も図示しましたが、中二チックに単語を選んだ図を再掲します。
f:id:catindog:20170129211137p:plain

図2. 音楽のRNNの系列

引用になりますが、Conditional Random Fieldとも見れます。
f:id:catindog:20170129211612p:plain

図3. Conditional Random Field(CRF)

 ベイズ系の記事を読んだ時、ヒートマップで表現している方法が分かりやすかったです。
f:id:catindog:20170129211919p:plain

図4. 確率場のヒートマップの遷移

 数式です。
f:id:catindog:20170129212659p:plain
アンサンブルは機械学習では特段珍しい手法ではないのですが、創造系のタスクでアンサンブルは珍しいと思います。
 

 提案したいことは単純で、それぞれの時間系列 t+1に対して次の音が来る確率の中庸点(特定のモデルにバイアスをかけることもある)を求めます。
 
 結果が確定したら、RNNの状態をアップデート(ステップを進める)して次に来る確率をまた予想します。

f:id:catindog:20170129212255p:plain

図5. 出力確率の合成による創造

f:id:catindog:20170129212424p:plain

図6. ヒートマップの合成(イメージ図)

f:id:catindog:20170129212854p:plain

 図では、2つのモデルの合成のみが示されていますが、実際には多くの音楽を学び、たくさんのモデルがあればその組み合わせはかなりの数になります。これは到底人間が一生かかって創造活動しても網羅できないレベルです。

実験環境

音の符号化

 一番苦労した点はこの符号化の点であると感じています。音を記号で示すにはどうしたら良いでしょうか。WaveNet[5]や他の研究では音をそのまま波形として扱うこともあるのですが、精度は高いものの非常に生成するのに時間がかかるということで、よりかんたんなMML(Music Macro Language)を使用しました。
 MMLはかなりの方言があり、一般的と呼ばれる記述を調べるのに非常に苦労しました。a~gのcharactorが音階になっていて、それを装飾するl, p, gなどの符号と量を示す数値で構成されているようだとわかりました。符号の粒度が分かれば、RNNで学習することができます。

いーあるふぁんくらぶの例
liarufanclub$ cat input.txt.org
v100q25o5l1a a a a a a a l2a q100l8d c l4d l8.d d l16d d l8c d l2.d l8d c l4d l8d l16d l8d l8.d l8d f f f g f q66l4.d q100l16d c q50l4d q100l8.d d l16d d l8c d l2.d l16a a a a a a a a l8g g g g f l2^4.d l8d c l4d l8d l16d l8.d l8d c d l2.d l8d c l4d l8d l16d l8.d l8d d l16f f l8f f g f l4.d l16d c q50l4d q100l8.d l16d l8d ...

 また、MIDIMMLは一部互換性があるらしく、運がよいとMIDIMMLに変化することができます。変換に使用したソフトは、テキスト音楽「サクラ」になります。[6]

 これを自作のスクリプトでかなりアドホックですが、一つの素性の単位に分解します。コードは別途転載するので、必要な方は参照してください。[7]

RNNの学習

 ざっくりとですがパラメータサーチを行った結果

  epoch:200
  batch:50
  rnn_unit: 386
  layer: 3
  学習率: 2e-3

ぐらいが曲を丸ごと覚えられる感じだったので、採用しました。
loss errorは10^-3以下になります。

これを一曲一つのモデルで学習させていきます。
学習させた曲は、以下の通りです。
いーあるふぁんくらぶ(最初の冗長なイントロまで再現されています)

バッドアップル  

ロストワンの号哭

千本桜

RNNのアンサンブルのコード

自然言語処理でどうしようもなく、精度が出ないときがあったのでアンサンブルの発想に至ったのですが、まぁ、普通に考えたらno free lunchの定理より、多くのモデルを混ぜると精度は改悪するので、idea賞というレベルのものを今回再利用しました。結構強引な改修を行ったのでコードが汚いです。[8]

結果

いーあるふぁんくらぶ、バッドアップル、ロストワンの号哭、千本桜を合成するのに、それぞれのウェイト(重要度のようなもの)を指定して、任意の割合で合成できるようにしました。
 
いーあるふぁんくらぶ50% + 千本桜50% ○ 新規性ありそう

いーあるふぁんくらぶ50% + Bad Apple50% △ 後半、いーあるふぁんくらぶ強くなってく

Bad Apple50% + 千本桜50% △ Bad Appleから入っていく感じ、似てるけど別物

ロストワンの号哭50% + いーあるふぁんくらぶ50% ○ そういう曲だと言われれば?

いーあるふぁんくらぶ90% + Bad Apple 90% + ロストワンの号哭 100% + 千本桜 100% ○なんか新しい曲調

色々良さそうな音楽を探索したいのもやまやまなんですが、疲れてきたのでこの辺にしときます。
コードを公開するので、自由にしてください。

結論

 任意の組み合わせで、再生に耐えられる音楽を作り出すことはできました。しかし、これが歌詞や音楽を知っているから、違和感なく感じるのか、音楽のプロが見たらどう判断するのか正直なところわかっていないです。
 自分に音楽の才能が著しくないことを理解しているので、どんどんやっていこうというモチベーションは出ないですが、人並みには興味があったのでやってみたというところが事実です。

 途中に介入したり、Conditionalに指定の曲調を作り出すことも、まぁ、可能なのですがデータがないのと手がまわらないのでどうしようもない感じです。

 音楽は画像生成タスクに比べれば楽という印象ですが、前処理、学習、評価、Webのアップロードだけでプライベートな時間の殆どを消費してしまいました。悲しい。
 

謝辞

 これは前からあったアイディアで、プログラムを作るの結構めんどくさかったので、半ば放置していたのでした。そんな折、My name is HAPPY HARDCORE.という音楽に出会いまして、最後までプログラムを書き上げるために強制的にテンションを上げていただき、ありがとうございます。この音楽がなかったら、この発想は私の中で永久に検証する機会がなかったと思います。

f:id:catindog:20170129214029p:plain

GANによるノイズ・モザイク等の除去

GANによるノイズ・モザイク等の除去

近況

 眠い。
 実は今月、三回も停電が起きてそのたびに機械学習のモデルが飛んでいます。原因は電子レンジとケトルを両方利用したとか、そういった当たり前のことなのですが...(ブレーカを飛ばしているの私でないです)。

モチベーション

 pix2pixなどのニューラルネットでの画像変換は、通常のフィルタと違って、情報量を増加させることができるような振る舞いをすることがある。
 画像は大学の学部で習ったレベルの知識しかないが、平滑化フィルタなどの画像を変換する系のやつは大抵が行列で表現されるようなやつで、平均値だの分散などを取るので、情報量が下がるものがほとんどだった(というかそれしか知らない)。
 GANでモザイク除去や、なんやらができるとは先行研究でわかっていたし、理論は単純だし、この前のpix2pix with textに比べて簡単だと思った。

先行研究

理論

  • GANなので、生成DNNと判別DNNがお互いを騙そうと、競争し合う。
  • 十分に学習した生成DNNが生成タスクとして利用可能
  • 一番良い理解はソースコードを見ることだと思う

f:id:catindog:20170124190828p:plain

図1. 生成タスクの例
f:id:catindog:20170124191025p:plain
図2. 判別タスクの例

実験環境

  • この前のpix2pix with textを更に変更したモデルを利用
  • textの領域にランダムなデータを入れることで、もとのDCGANのような、ランダムに近いZシードの位置づけを作成した(直感的な理解であるが、いらなくてもなんとかなるのでは)
  • GTX 1060, GTX 1070で4日ほど回した
  • 途中、chainerのバグを踏む、serializerがメモリバカ食いという点はあったものの、色々細工することで乗り切った. (バグは今は直っている。大容量なswapをNVMeに作成するなど)
  • 学習データとは別のデータセットを用意して、各モデルの学習の進み具合を確認してepochを進めていった. leakは防げていると考えている。
  • epoch: 350
  • 画像ドメイン: 艦これの7500枚の一人だけ表示されている絵、ただし縦横比が2:1, 1:2までのカラー画像のみ
  • その他パラメータは原則、Facadeのものに従っている
モザイク生成
  • opencvを利用
  • 一度1/10まで縮小して単純に10倍に拡大することで、モザイクを発生させる[1]
  • モザイク状態のデータと、正解データを対応させて学習する
ランダム情報欠落
  • opencvを利用
  • 全体の画像の面積の半分を白いブロック領域でランダムにデータを欠落させる[1]
  • 情報が欠落した状態のデータと、正解データを対応させて学習する
評価
  • 評価には、別途用意した500枚の画像を利用する

結果

  • 概ね良好な結果が得られた。
    • inputとはgeneratorの入力値である
    • predictとはgeneratorの出力値である
    • ground truthとは未加工のもとデータである

f:id:catindog:20170124191437p:plain

図3. ブロックノイズ除去の例

f:id:catindog:20170124191513p:plain

図4. モザイク除去の例

考察

  • ランダム情報欠落は、復元しやすいのかかなり強力に動作しているように見える
  • GANの特徴として、判別機を騙せるようにGeneratorは学習していくので、ニューラルネットという人間に近い判別の仕方、判別能を持っているので、人間をうまい感じに騙せような補完をしてくれる(別にground truthに近くなるわけでない)
  • 停電でpix2pix with textのデータが飛んでしまったので、しかたなくやった感があったが、思ったより簡単に結果が出たので、学部の論文とかにはいいかもしれない.ただし、通用するのは今年までな気がする
  • 比較こそしていないが、少しの汚れや情報欠落ぐらいでは、うまくドメインが合致していれば、もとの絵とイメージは違うけど、十分見れるものを出力できている.色々応用は広そうである

Future Work

  • StackGANを参考にUltra High-resolution GANを組んでみたいが、4Kの画像のデータセットとかあるのかな。実装の案はあるのだけど
  • 画像だけでなく、ベクトル表示できるものならなんでも行ける、多分
  • 自然言語の応用を考えてみる