スロベニアに行ってきた話をする

自然言語処理データセット系の国際会議LRECに参加してきた。

立ち位置は微妙な会議なのだが、データセットコーパス)という視点で見ると、間違いなく世界最大である。

自然言語処理という立ち位置で見ると、上から6番目くらいの会議だろうか。 (個人的には、EMNLP, ACL, NAACL, EACL, COLING, LREC くらいの並びだと思っている)

今回はスロベニアポルトローシュで開催された。 スロベニアポルトローシュ?知らないでしょ?

スロベニアはイタリアの東の国。 かつてはユーゴスラビアの一部だった国だ。

ユーゴスラビアはご存知の通り、内紛で分裂したが、国によってその後の発展度がまったく違う。 東のセルビアあたりは戦争の爪痕が大きく残り、いまも禍根を残している。セルビア人の知り合いが1人いるが、彼も従軍してた話を時々してくれる。

一方で、スロベニアは、そもそも戦争はなかった。勝手に、周りが分裂したので、一緒に分裂しただけの国に過ぎない。

スロベニアのあたりは以前から観光地として機能していたので、独立後もいち早く経済機能を取り戻して(というか、特に経済機能に問題はなかったらしい)、豊かな国としてやっている。

ポルトローシュという場所はごたぶんにもれず、リゾート地である。この会議は主催者の趣味なのか、以前からリゾート地での開催が目立つ。

行き方

行き方は大きく2ルートある。1つは首都のLjubljana(リュブリャナ)を経由していく方法。もう1つはイタリア経由で行く方法。

2つのルートの、どちらも直行便などないので、乗り継ぎが2回は発生する。

2016年4月の段階では、イタリア経由の方が安かった。ぼくはイタリア経由で行った。

通ったルートは 成田 - (飛行機) - ミラノ - (飛行機) - トリエステ - (バス) - ポルトローシュ

リュブリャナ経由だと、フランクフルトだか、ヘルシンキを経由していけるようだ。

ポルトローシュのあたり

ポルトローシュは本当にリゾート地である。

街を歩いていると、基本的にヨーロッパ人ばかりである。 話している言語はイタリア語が一番多くて、次にドイツ語が多く聞こえる。

英語はあまり聞こえてこない。 アジア人はマジでいない。たぶん、他のアジア人もLRECに来ていたなんだろう。

ポルトローシュは本当に海が綺麗な街である。

街並みはこんな感じ。交通量は少ない。 f:id:kensuke-mi:20160526093101j:plain

海が本当に見える街である。 f:id:kensuke-mi:20160525153327j:plain

アドリア海に浮かぶ船。こんなに船が似合うのは久しぶりに見た。 f:id:kensuke-mi:20160526094109j:plain

バラもよく似合う風景である。 f:id:kensuke-mi:20160525154900j:plain

芝生にはひなたぼっこをしている人がたくさん。おばさんレベルになると、おっぱい丸出しで寝転がっていることもあった。 f:id:kensuke-mi:20160525155303j:plain

隣接しているピランという地区。ヨットハーバーとレストランが並ぶ。 f:id:kensuke-mi:20160527185537j:plain

ピラン地区を高台から見る f:id:kensuke-mi:20160526143705j:plain

ホテルの朝食。ピクルスとオリーブがこれでもか!と提供される。 f:id:kensuke-mi:20160526091913j:plain

ポルトローシュの昼食。おしゃれなランチタイム(女子力UP) f:id:kensuke-mi:20160526134711j:plain

リュブリャナに行ってきた

1日だけ完全な休みがあったので、首都のリュブリャナにも行ってきた。

リュブリャナには、平日ならバスで行ける・・・・が、日曜日だったため、バスがなかった。

仕方がないので、途中のポストイナという街まで乗り合いバスで行った。 後述するが、スロベニアでは、公共交通機関よりも乗合バスの方が信用されているらしい。

ポストイナまでは行ったはよいものの、そこからタクシーがない。 街の人に聞くと、なんと「この街にはタクシーは1台しかないわよ。でも、きょうは彼は休み」

日曜日はスロベニアでは一般的な休日なのである。

なんと、驚きなことに、彼女は父親を呼んでくれた。「父が暇だから、行ってあげるって。」と言っていたが・・・そういう問題なのだろうか。

リュブリャナは・・・・残念ながら、ほとんどの店が閉まっていた。 スロベニアでは、日曜日は安息日なのである。 まだまだ、宗教の信仰心が厚いスロベニアでは、観光客相手以外の店はすべて閉めてしまうのだそうだ。

なので、リュブリャナでは街の光景を眺め、リュブリャナ城に登って街を一望してきた程度にとどめておいた。

唯一開いていたリュブリャナ市内のスーパーで、醤油を発見した。日本のキッコーマン、恐るべし。 f:id:kensuke-mi:20160529165525j:plain

スロベニアでの移動手段

  • 飛行機 スロベニアは小さい国である。国内線などない
  • バス バスは国民が良く使う交通手段。国内バスだけでなく、国際バスもたくさん走っている。スロベニアはEU加盟国なので、国際バスでいろんな国に行ける。[1]
  • 鉄道 鉄道はスロベニア国民に信用されてない。遅い、ダイヤが守れない、などの評価でクソミソだった。
  • 乗合バス 乗合バスはとてもよく使われる交通手段。GoOptiという会社の乗り合いバスが一般的らしい。

乗り合いバス GoOpti

この会社。インターネットで予約ができる。もちろん、現地のInformationカウンターでも予約してもらえる。 www.goopti.com

インターネットで予約するときには電話番号が必要になる。 なぜなら、SMSで重要な情報が配信されるからである。

予約が完了すると、SMSで集合地点、集合時間、運転手の名前、乗合バスのナンバーが送られてくる。 この情報を頼りに、乗合バスに乗るというシステムである。

[1] ヨーロッパでは、バス停に停まってもバス停の名前を読みあげない。バス停の名前が読み取れないこともよくある。確実に降りるために、バスの運転手に教えてもらうようにお願いしておく or 周りの客に教えてもらうようにお願いする ということをしないと降りそびれる。

スロベニアでの通信手段

スロバニアではそれなりにWifiはある。ホテルのロビーや、レストランなどは無料 Wifiを設置していることがある(約6割の体感値)。

でも、国内を移動するには、それだと困ってしまう。 現地でSIMカードの調達をオススメする。

スロベニアではMOBITELという通信ベンダーがメジャーらしい。 SIMカードはガソリンスタンドに行くか、MOBITELの販売店に行くと手に入る。 f:id:kensuke-mi:20160602222835j:plain

電話番号が必要ないのであれば、4GBの通信容量でだいたい20ユーロで手に入る。有効期限は30日である。

スロベニアの人たち

スロベニアの国民を一言で形容すると、「親切、人懐っこい、素朴」がぴったり来る。 先も紹介したように、「タクシーがないから父親を呼ぶ」とか「観光局はオフィスはしまってしまうけど、できるかぎりは対応してあげるから個人の携帯番号を教えてくれる」とか日本人にはない発想を繰り出してくる。

そして、話が好きである。乗り合いバスに乗っても、大体は話をする。 話しかけたら、向こうも気軽に日常会話をしてくる。

スロベニアは観光で生きてる国だからか、ほとんどの国民は英語が通じる。 スロベニア西側の地区はイタリア語・東側の地区はドイツ語が通じることが多い。 日本語?無理に決まってんだろ。でも、リュブリャナ大学には日本語のコースがあるらしい。

イタリアの話

今回はイタリア経由で行ってきた。

ミラノに一晩宿泊して、トリエステまで飛行機で行った。

ミラノでは、日本着の空港と、トリエステまで行く空港は、別の空港である。 両方とも公共交通機関が使え、時間もそれなりに正確なので、きちんと下調べして行けば、そこまで問題でない。 ミラノの公共機関は、イタリアのイメージと違い、ほんとうに時間に正確である。

ただし、13時近くになると、きっちりお昼休みをとるために、店を閉めてしまうことが多いので、要注意。 f:id:kensuke-mi:20160531130923j:plain

イタリアでルパン3世の落書きをみた。ルパンの里帰りである。 f:id:kensuke-mi:20160524222147j:plain

このブログの使い方をメモっておく

結論として、このブログはポエムを書くブログにすることにした。

元々は技術ブログとして始めたのだが、その立ち位置はすでにQiitaに移ってしまっている。

ぼくもQiitaのほうが使いやすいし、他の人への役立ち度もQiitaのほうが大きい。

では、はてなブログは?となると、多くの人がたくさんのスマッシュうんこを量産できるところがメリットだと思う。

というわけで、ぼくもスマッシュうんこポエムを投稿することにした。

キモオタがやってみるデータサイエンス〜その3:ミスコン支援アプリを作ってしまった話〜

きょうはこんなこと書くよ

  • ミスコン出場者の相関関係がわかるアプリつくったよ
  • ついでだから、Mr用にも作ってやったよ。
  • みんな投票してね♡
テクニカルにはこんな内容だよ

こんばんは。

さて、きょうはでーた・さいえんすの力を使ってミスコンをさらに楽しむアプリを作ったので、紹介しますお。*1

さて、スクリーンショットとともに紹介しましょう。

全体的にはこんな簡素な作りでございます。

f:id:kensuke-mi:20151013220721p:plain

上に表示されているのは「相関図」*2と呼ばれるグラフです。

相関図では、あらゆるデータを2の軸があるグラフに表示してしまいます。

なので、データの様子をながめて、うひひ・・ぐへへへへするのに最適なのです。

さて、相関図の下にある表は、出場者全員の情報がある表です。

なんと!知りたい行を押すと、相関図の中で、どこにデータがあるのか?すぐにわかります。

f:id:kensuke-mi:20151013221127p:plain

あら!素敵!

さらに、なんと!表の項目名を押すと、ソートができます。いまは身長でソートしてます!

f:id:kensuke-mi:20151013221249p:plain

まだまだおどろくなかれ!なんと、相関図の点をプロットすると・・・

f:id:kensuke-mi:20151013221403p:plain

出場者の情報が吹き出しになってでてきます!

こんにちは〜福井セリナさん〜。私の同僚がイチオシする出場者のお方です。

もう、すでに投票してくれたんですって。も・う・ほ・れ・ちゃ・う・ぞ!*3

まだまだあるぞ!おもむろに点をクリックすると・・・・なんと出場者のプロフページに飛べるのダァァァ!*4

こんな素敵なアプリにはここからアクセスできます。

さあ、いますぐあなたもアクセス!


いかがでしたか?*5

これで、あなたもミスコンに投票するっきゃないですね!

トップページはここからアクセスできますお。

あ、ちなみに私、このミスコンサイトを運営している会社とはなんら一切の関係がありません

所属している会社もなんら関係ありません

ただ、自分の興味のままにやりました。*6え?何が興味があるのかって?

そんなの出場者の一覧をながめてうひひひしたいに決まっているじゃないですか。

これがデータサイエンティスト()なのです。

あ、Mrコンテストとかいうのもあるので、作ってやりましたよ。これをみてくださいね

てくにかるのーと

いちおう、データサイエンティスト()なので、簡単に概略を述べます。

今回やったことを簡単にまとめると、こんな流れです

  1. プロフ情報とQA文で出場者のベクトルを作る
  2. SVDで次元圧縮をする。2次元まで圧縮します
  3. 圧縮した座標に従って、プロットします

1 ベクトルをつくろう

ベクトルの作り方ですが、プロフからは

  • 年齢
  • 身長
  • 血液型

の情報をいただきました。 QA文は形態素分割した後に、BOW(単語が出現したかOR NOTの0と1で構成される)でベクトル空間にします。

なので、できあがった出場者ベクトルは

[ 年齢:int 身長:int 血液型:カテゴリ数値化 ここからずっとBOWの0 or 1 ~ ]

という形です。

さらに今回は、特別にQAを細かく分割しています。なので、「ここからずっとBOWの0 or 1」の部分は

[ 質問Aへの回答BOW_a_1 .... 質問Aへの回答BOW_a_n 質問Bへの回答BOW_b_1 質問Bへの回答BOW_b_n]

みたいな感じで分割してます。

なので、結果的に高次元になりました。1万2千次元くらいにはなったかと思います。

さらに、今回は正規化をしています。

なぜなら、身長と年齢はかなり大きな数値を取るのに対して、BOW特徴量は0か1しかないからです。

もちろんscikit-learnを使いました。

2 次元圧縮しよう

Scikit-learnのSVDを使いました。

以上!

3 プロットしよう

今回は、インタラクティブなグラフを作るために、Bokehを使いました。

Bokehはpythonで簡単にインタラクティブグラフが作れる素敵なライブラリです。

実態はJavaScriptのラッパーです。

Galleryで作ることができるグラフを眺められるので、どんな感じなのか。感じてください。考えるのではないです。感じるのです。

今回、各機能を作るのあたって、下記のメソッドを呼び出ししてます。

こんな感じです。

その集大成のコードはipython notebookにまとまっています。こちらをごらんください。

そう、Bokehはipython notebookで作ることができるのです!

インタラクティブな環境でインタラクティブなグラフを作るのが新時代のpythonistですよ。がっはっは。

ぜひ、データサイエンティスト()のみなさんも、そうでないみなさんも手持ちのデータをプロットしてお楽しみください。


*1:実はすべてhtml埋め込み・・というたいへーんシンプルなものです。なので、狭義の意味ではWebアプリとは呼べないっす

*2:おいんぐりっしゅではscatter graphといいます

*3:ちなみに同僚は外国人、身長180cm超、金髪のナイスガイです

*4:飛べる先のページはこの場合ここです

*5:いつもいろんな記事を見ていて、みんな様式美()みたいに使うので、いつか使ってみたいと思っていた

*6:私はノーベル賞受賞された梶田先生のお言葉「研究者個人の好奇心でやっている分野」(中略)「きちんと(研究を)やっていけば、何かに結びつくんじゃないかと思ってきちんとやった。自分の進んでいる道が正しいと思って頑張った」というお言葉にとても感銘を受けました。

キモオタがやってみるデータサイエンス〜その2:RBMでミスコンっぽい顔を知る〜

この記事ではこんなこと書くお

  • RBMで特徴量の学習をしてみる
  • pylearn2を本格的に使ってみる

記事の本文だお

どうも、キモヲタです。

さて、前回はDeepLearningで共通顔画像の抽出と題してやってみましたが、あまりうまくいきませんでした。*1

さて、前回はChainerでAuto-Encoderだけを試してみたわけですが、画像認識系タスクでDeepNNを使う際は、RBM(制約つきボルツマンマシン)を使うことが多いようです。*2

なので、今回はRBMで特徴量の学習と可視化をしてみることにします。 (なお、RBMの概説はこの記事が大変ためになります。マジ感謝です)

はじめに断っておきますが、きょうの学習結果画像は怖いです。*3

さて、RBMを使おうとしてみるわけですが、Chainerではどうやらキツイようです。 (そう言っているのはこんなツイートを見たから。)

そこで、今回はPylearn2を利用することにします。

Pylearn2でAV女優さんの顔画像を学習しようとしたキモい人もいるわけですし、きっと可能でしょう。

Pylearn2を使う

正直いうと、セットアップはとても面倒です。*4

Pylearn2がすでにセットアップ済みのVegrantのイメージファイルがあるので、ちょー面倒だったら、イメージファイルでコンテナを起動したほうが早いかもしれません。

とはいえ、インストールしちゃいました。

pylearn2のインストールからデモスクリプトの実行までをシェルスクリプトにまとめたので、どなたかの参考になれば幸いです。

なお、.bashrcに環境パスを通してありますが、実は必須ではありません。

他のpylearn2でも環境パスを通す。みたいな説明が多いですが、「パスを通しておくと、デモスクリプトが簡単に実行できるよ」というだけで、そんなメリットがないです。

実際、trainingする時は自分でスクリプト書いたほうが手間がかからないように思いました。

pylearn2利用の大体の流れ

  1. trainingデータを用意する
  2. yamlファイルにトレーニング設定を記述する
  3. training実行

1は画像がすでに特徴量行列になっていれば、楽勝です。 (後になって知ったのですが、Pipelineで前処理を繋げられる機能があるようです。試してないけど)

何かの役に立つかもしれないので、trainingスクリプトをさらしておきますね

yamlファイルにテンプレを書いておいて、trainingスクリプトで変数を埋めている感じです。

あと、yamlファイルはこちらです

学習データは前回と同じです。グレースケール化した100*100の顔画像です。 (100*100なので、10,000次元です。これ、yamlファイルのnvisに記述するのを忘れないでくださいね。)

可視化してみる

Pylearn2にはshow_weight.pyとかいう可視化する神スクリプトがあるのですが、使えませんでした

Exception: Tried to call get_weights_view on a dataset that has no view converterとかいう例外が発生します。

調べても意味がよくわからなかったので放置です・・・・

じゃあ、どんすんねん?って話ですけど、「スクリプトがないなら、書けばいいじゃない?」(神の声)

要は学習した重みを可視化すればいいわけです。書きました

可視化してみた結果www

さて、心の準備はできましたか??

出しますよ!

f:id:kensuke-mi:20151012063646p:plain

おしっこちびるかと思うほど、怖かったです。

さて、怖いながらもしっかり観察してみました。

Auto-Encoderを使った時の学習よりもきれいに特徴量が取れています*5

類別すると、4種類の写真がありそう(な気がします)

f:id:kensuke-mi:20151012064550p:plain

f:id:kensuke-mi:20151012064551p:plain

f:id:kensuke-mi:20151012064548p:plain

f:id:kensuke-mi:20151012064549p:plain

赤い四角が私がつけました。髪の分かれ目がしっかり特徴に出ているなぁ。と感心したんです。

え、なんでそんなとこ見たのかって?そんなの髪の分け目フェチだからにきまっているじゃないですか。

まとめ

  • 今回の設定としょぼいマシンと私のサボりグセを考えると、RBMの方がきれいな特徴量を出してくれた。ありがとう
  • 髪の分け目はとっても重要だお!
  • せっかく特徴量をとったから何かしたい。うひひひ

*1:チューニングをさぼっているから。と言われると痛い限りです。

*2:専門じゃないので、よくわかりません。でも、ブログで紹介されている量をみると、画像認識系タスクではRBMが多いような気がします

*3:深夜2時に学習終了とともに表示された時の恐怖といったら・・・

*4:chainerと比べると。。。という意味です

*5:前の結果もチューニングしたらよくなるかもしれません。Auto-Encoderが悪いって言ってるわけじゃないです。マシンスペックがね・・・

キモオタがやってみるデータサイエンス〜その1:DeepLearningでミスコンっぽい顔を知る〜

注:この記事はキモヲタがキモヲタ同業者のために書いたとぉってもきも〜い記事です。それ以外の方は吐血するかもしれないので気をつけてくださいね♩

こんばんは。キモオタです。ブヒブヒ

さて、10月になりましたね。10月といえば、そろそろ学園祭のシーズンです。

学園祭に付きものと言えば、ミスコンですよね。ブヒブヒッ!*1

ミスコンっていいですよねぇ。私は好きですよ。

実際に足を運んで、イベントとして楽しむのもいいですね。

でも、ほら、やっぱデータサイエンティスト()なんでぇ〜データ*2をみてきゃっきゃっうふふ♡しちゃうんですよね。

でも、日本中でミスコンをやっている大学なんてたくさんありますよね?

それをいちいち見に行くのって面倒臭いじゃないですか?

ところが、ある日、私は聞いてしまったのです。

それがね!いいサイトがあるのよ!奥さん。ミスコレっていうの! 日本各地の大学でやってるミスコンの情報をわかりやす〜くまとめてくれてるのよ! しかも、今なら利用料無料!さあ、今すぐ、ミスコレへ!

あら素敵!たちまち虜になりますね!ブヒブヒッ!

これで出場者の最新の情報が追えますね!

しかし、まだ問題があります。「最近の流行はどんな感じ」と聞かれた場合です。次のような場面を考えてみましょう。

Bob: Hi! Joey! What's up?
Joey: Hi, Bob! 最近、ミスコレでミスコンにはまっているんだ!たくさんの出場者が見れてとっても楽しいよ!
Bob: Sounds Good! 今年のミスコンの出場者はどんな人が多いんだい?
Joey: えっ・・・どんなって言われても・・・そ、そんなのたくさんいてわからないよ・・・
Bob: おいおい、勘弁してくれよ!たくさん見ているのに説明できないのかい?ダサダサだね。ハッ(笑)

これはダサいですね。

さて、Joey少年はどうするべきだったのでしょうか?

きっと、Joey少年は「ああ、出場者の顔の特徴をうまくつかめる何かがあれば・・・」と思ったことでしょう。

それ、できるんです。そう、Deep Learningならね!

Deep Learningとは?

Deep Learningとは、ここ十数年で人気になったアルゴリズムのことです。

もうすでにご存知の方はおめでとうございます!あなたはすでに、データキモオタへの入り口に立っていますよ。

では、耳にすることはあるかもしれない、Deep Learning、何に使えるのでしょうか?

Deep Learningって何に使えるの?

簡潔にいうと、共通の情報を抽出することを得意にしています。

たとえば、この絵をご覧ください。*3 f:id:kensuke-mi:20151006000435p:plain

このきもいおっさんは、人の画像をたくさん集めて、共通部分を抽出した結果です。

また、こちらの猫画像をご覧ください。*4

f:id:kensuke-mi:20151006000552p:plain

この猫画像もまた、大量の猫画像を集めて、共通部分を抽出した結果です。

この猫画像は、「共通部分を集めた画像でモフモフで癒されていいのか?」という激しい論争を日本猫画像モフモフ学会に巻き起こしました。

ちなみに、両方ともGoogleの仕事です。*5

上の例は画像に応用した例ですが、もちろんあらゆるデータに利用可能です。

音声情報・テキスト情報にも利用できます。

テキスト情報向けにアルゴリズムを作り直したword2vecはある特定の分野では話題になりました。加賀さんから乳を引いてみたが、「瑞鳳さんから引いたら時空が曲がってしまうのではないか?」などの激しい論争が巻き起こりました。

Deep Learningはどやって動いてるの?

さて、Deep Learningというと、どんなイメージでしょうか?

私のイメージはこちらです。

f:id:kensuke-mi:20151005201755j:plain

Deepそうな男が勉強しようとしてますね?もちろん違います。

Deep Learningの正体は下のようなごちゃっとしたネットワークです。

f:id:kensuke-mi:20151005201817j:plain

この「ネットワーク装置」そのものが、Deep Learningなのです。

この装置では、左側の「でーた」にデータを入れます。

装置の中央では、データをいろいろ分解したり、傷つけてみたりと、変な操作をいっぱいします。

変な操作をいっぱいした上で、右側の「でーた'」から結果を出すます。

「でーた」と「でーた'」は元は同じ内容です。ただし、「でーた'」は「中央で変な操作をいっぱいしたけど、いろいろがんばった結果、元のでーたっぽく復元できたもの」です。

こうすると、中央部分では、「操作しまくったり、傷をつけても、元のデータに近しいものが復元できる情報」が蓄積されます。

あれ、それって・・・そう、中央に蓄積される情報こそが「共通部分」なのです。

それじゃあ、Deep Learningつかってみよう

それでは、哀れなJoey少年のために、共通部分を抽出してみることにします。

まず、手始めに、ミスコレの全出場者の写真とプロフ情報を収集します。

出場者の名前にごとにフォルダ分け・・・きもいですね〜

f:id:kensuke-mi:20151006002638p:plain

次に、顔画像だけ切り抜きます。ここでも機械学習の技術が生きてますが、それはDeep Learningではありません。おっと、ときどき誤認識がありますね。こういうものは手動でハァハァしながら削除します。

f:id:kensuke-mi:20151006002834p:plain

さて、その後、画像をグレー画像にします。綺麗なお顔を色なしにしてしまうのは心苦しい限りですが、画像データの機械学習を行なう場合にはグレー画像化するのが定石なのです。*6

全部で434枚になりました。Googleがやったことに比べれば数は圧倒的少なさですが、まぁ、こんなものでしょう。

ここまでやって、最後に、さっきのDeep Learning装置にたくさんの画像を読み込ませます。

そして、最後に、中央の丸から共通部分を抜き出してみます。

その結果がこちらです。

f:id:kensuke-mi:20151006003547p:plain

いっぱいありますね?丸の数だけ画像が存在しているのです。いまは400個の丸を中央に置きました。

見りゃわかりますが、ほとんが砂嵐のテレビ状態ですね。

すべての丸が必ずしも人間が見て理解できる情報とは限らないのです。

でも・・・あれ?ちょっとまって、右端に顔っぽいものがありません?

拡大してみましょう。

f:id:kensuke-mi:20151006003843p:plain

顔の形をしてますね!11番と44番と58番は無事に顔の形を抽出できたようです!

ちょっと、比較してみましょう。

f:id:kensuke-mi:20151006004330p:plain

44番はこれら写真の特徴をうまく捉えているように思います。

他にも該当しそうな写真が30枚近くありました。

一方で、58番は少し顔を左に傾けて、左側も髪を下ろしているお方のようですね。これも該当写真が多くありました。

11番はロングの髪の女性のようです。しかし、それ以上の情報は捉えられていないようです。

ほかの番号の情報も確認してみたのですが、このレベルまで情報を捉えているものはありませんでした。

結論

今年のミスコン出場者は

  • 髪をやや左で分けている女性
  • 髪を両側まで下ろして、左に顔を傾けて写真にうつる女性
  • 全体的に長い髪の女性

がいそうだ。ということになります。*7これでJoey少年も大喜びですね!

その他

さて、とりあえずJoey少年を喜ばせる情報にはなりましたが、Googleの画像とはほど遠い感じでした。どうして差がでてしまったのでしょう?

まずはデータ量の違いです。今回は、たかだか400枚ちょっとしか使っていません。一方でGoogle人間は37,000枚の画像とのことです。

また抽出に要する時間も影響がありそうです。Deep Learningは一般に、たくさん時間をかけて抽出すると、よい共通情報が取れる(傾向があります)。

しかし、今回、たかだか、MacBookで数時間で終わるような抽出しかしませんでした。対してGoogleは巨大なサーバーを大量に用意して並列で抽出します。そら、かないませんわ。

てくにかる・のーと

実験に利用したコードはすべてGitの私のリポジトリにあります。

すべてpythonで書いています。

一緒にきゃっきゃうふふ♡するお仲間を募集中です。

なお、Deep NNの構築とTrainingはChainerを利用しました。

Chainerはとても簡便なDeep Learning用のフレームワークです。

チュートリアルをご覧になれば、大体のDeep NNの構築方法はわかるでしょう。

また、この記事はChainerのわかりやすいコードexampleだと思います。

今回、構築して試してみたDeep NNはこちらの記事で紹介されている内容とほぼ同じです。

つまり、AutoEncoderとDenoising autoencoderを試してみた。ということです。

特徴量の学習結果を観察すると、以下のような傾向がありそうです。

  • 活性化関数はSigmoidよりも正規化線形関数の方がよい結果が得られている
  • 中間ノード数は400前後がよいようだ。
  • Dropoutは実施した方が若干よい

私の記事で紹介した結果は2層、400ノード、DropOut有り、正規化線形関数の結果です。

手書き文字の認識では、ノイズありの方がよい傾向でしたが、今回はまったくダメでした。

ノイズを乗せると、すべてのノードでノイズだらけになってしまっています。

この傾向がデータ量のせいなのか、顔パーツというタスクから来るものなのか?わかりません。

最後に、テスト時のロスを表示しておきます。

この動きを見ると、学習イテレーションを増やせば、まだまだロスは減るかもしれません。

ただし、計算機資源のせいで30イテレーションでやめておきました。

f:id:kensuke-mi:20151006011049p:plain

*1:最近ではMrコンテストとかありますけど、どーでもいいです。マジで

*2:ここでいうデータとは広義のデータです。従って、顔写真とか顔写真とか、少しだけプロフィールもあるかな

*3:出典

*4:出典

*5:元論文はこちら

*6:専門じゃないから知りません。そう聞きました。

*7:この分け方はMECEではありません。かぶりもありながら、データ全体の特徴を複数の見方から観測していることになります

クラスの内部で並列処理を利用したメソッドを利用する

やりたいこと

pythonクラスで、並列処理を利用したメソッドを実装したい。

つまり、classの中で、multiprocessing.Pool を利用したい。

しかし、普通のやり方ではできない。そこで、ちょっとした工夫が必要になる。

※ ただし、multiprocessing.Process ならメソッドで使える。ただし、 multiprocessing.Processはプロセスの管理とか面倒なのだ

解決法

通常、クラスの中で、multiprocessing.Poolを利用したメソッドを書き、別のメソッドを並列処理させようとすると、エラーがでる。

PicklingError: Can't pickle : attribute lookup __builtin__.instancemethod failed

つまり、「引数が展開できへんで〜」と言っている。これはmultiprocessing.Poolの仕様なのだ。

じゃあ、どうするか、っていうと、クラスの外部に引数を展開して、目的のクラスメソッドを呼び出して、値を返す関数を定義することになる。

動かないコード

from multiprocessing import Pool
import time
 
class C:        
    def f(self, name):
        並列処理をしたいメソッド
     
    def run(self):
        pool = Pool(processes=2)
        pool.map(self.f, [1, 2, 3, 4])
 
if __name__ == '__main__':
    c = C()
    c.run()

ここで、self.fをcallせずに、「メソッドfをクラスメソッドとして呼び出す関数」を作成する

from multiprocessing import Pool
import time
 
def unwrap_self_f(arg, **kwarg):
    # メソッドfをクラスメソッドとして呼び出す関数
    return C.f(*arg, **kwarg)
 
from multiprocessing import Pool
import time
 
class C:        
    def f(self, name):
        並列処理をしたいメソッド
     
    def run(self):
        pool = Pool(processes=2)
        pool.map(unwrap_self_f, [1, 2, 3, 4])
 
if __name__ == '__main__':
    c = C()
    c.run()

こうすると、動いてくれる。

ちなみに、この内容はここ の英訳みたいなもんです。

Rスクリプトの実行パスを取得する

やりたいこと

Rスクリプトスクリプトファイルが存在しているパスを取得したい。

pythonでいうとこの__file__を実現したい。

もうちょい踏み込んだ説明

なんでかっていうと、コマンドラインインターフェースだけ独立させて存在させたいわけですよ。

私、分析系のスクリプトをしっかり書き上げてシステム的に整えると、どーしてもコマンドライン引数は増えてきます。

で、行数が増えるから、インターフェースだけは分離する。

独立させると、何が困るか?っていうと、source(読み込みたいスクリプトパス)の部分がおかしくなることがあるんですね。

毎回、コマンドラインインターフェース.Rのパスまで移動して実行するならいいけど、それって面倒じゃないですか。

だから、binに通して、別のところから呼び出すと、source(読み込みたいスクリプトパス)が不都合を起こすんですね。

だって、想定しているパスと違うわけですから。

じゃあ、どないするんや?ってわけで解決法です

解決法

コマンドラインインターフェース.Rが存在しているパスを特定させる。

ここに答えがあった。

具体的にはコマンドラインインターフェース.Rにはこんな感じに書きます。

#! /usr/bin/Rscript

initial.options <- commandArgs(trailingOnly = FALSE)
file.arg.name <- "--file="
script.name <- sub(file.arg.name, "", initial.options[grep(file.arg.name, initial.options)])
script.basename <- dirname(script.name)
source(file.path(script.basename, 'main.R'))

script.basenameにはコマンドラインインターフェース.Rが存在してるパスが代入されます。

なので、あとはmain.Rを記述するだけです。

Enjoy!