Hatena::ブログ(Diary)

shi3zの長文日記 RSSフィード Twitter

2016-03-28

超人工生命ハッカソン、150人を突破してしまったのでさらに参加人数を増やします 09:16

https://i.gyazo.com/5af679dbb50be5b47d5acdd604d5cea5.png


 昨日参加人数を50人増やした超人工生命ハッカソンですが、既に50人埋まってしまったため、さらに参加人数を増やします。でもたぶんこれが最後。ちなみに先着順なので、今まで申し込んだ人は来てくださいね。


 スポンサー/取材は引き続き受付中です。

超人工生命ハッカソン - connpass

http://connpass.com/event/28982/


 ついでに昨日買った本

イラストで学ぶ ディープラーニング (KS情報科学専門書)

イラストで学ぶ ディープラーニング (KS情報科学専門書)


 この本わかりやすくて面白いわー。

 ハッカソン前に読んでおくといいですよ。


https://i.gyazo.com/fbd9bcc9b80698149667c3570401311a.png


 ちなみに初心者の方も来ると思うので少し用語説明を。


 よく機械学習の話題に出てくるテンソルという言葉ですが、もうテンソルという言葉がでてきただけで何が何だかわからない人も続出するので先に言っておきます。単なる多次元配列のことです。


 Wikipediaでテンソルの説明を読んだ時には誰もが絶望的な気分になると思います。

現代的な(成分を使わない)アプローチではテンソルはまず抽象的に多重線形性の概念にもとづく数学的対象として定義される。よく知られているような諸性質が線型写像としての(あるいはもっと一般的な部分についての)定義から導かれる。テンソルの操作規則は線形代数から多重線形代数への拡張の中で自然に現れる。


数学における普通のやり方では、ある種のベクトル空間を用いて、必要なときに基底を考えるまでは特に座標系を指定しないようにされる。例えば共変ベクトルは一次微分形式として説明できるし、あるいは反変ベクトル空間の双対空間の元として説明することもできる。


現代流の成分によらないベクトルの概念によって、成分表示にもとづく伝統的な(しかし、初学者にベクトルの概念がどんなものかを教えるには有効な)取り扱いが置き換えられるように、この取り扱いは成分にもとづく取り扱いをより高度な考え方によって置き換えることを目的としている。「テンソルはテンソル空間の元のことなのだ」という標語を掲げることもできるだろうが、高階のテンソルに対して幾何的な解釈をどう与えるかという難しさもあって、成分表示によらないアプローチが支配的になったというわけではない。


物理学者や技術者たちはベクトルやテンソルが(勝手に選べてしまうような)座標系に左右されない概念としての重要性を認識した。同様に、数学者たちは座標表示することで簡単に導けるようなテンソルの関係があることを見いだしている。

https://ja.wikipedia.org/wiki/テンソル

 解るか!


 たぶんですけど、数学の説明って、とにかく細かく正確に説明しないと「違うぞ」というツッコミが全方位からやってきてWikipediaの場合特に荒れるので、もう最初から全ての防衛線を張っておいて「正確にはこうです」みたいな、もう法律とか契約書の文言くらい回りくどい説明になってる。


 まあでも頭のほうにこう書いてあります。

テンソル(英: tensor, 独: Tensor)とは、線形的な量または線形的な幾何概念を一般化したもので、基底を選べば、多次元の配列として表現できるようなものである。しかし、テンソル自身は、特定の座標系によらないで定まる対象である。個々のテンソルについて、対応する量を記述するのに必要な配列の添字の組の数は、そのテンソルの階数とよばれる。

 多次元の配列・・・なぜわかりやすく多次元配列と言わないんだ。「の」をつけるな「の」を。

 なんだよ基底を選べばって。まあその通りなんだけど、こういう言葉が増えれば増えるほどわかりづらくなっていく。


 数学ほど厨二病を刺激するものはないと思うくらい、もうわけわかんない用語と「正確な」表現で書かれてるわけですが、我々実用派プログラマーにとっては数学的に正確な表現などどうでもよろしい。数学的に正確な表現など、我々にとってはポエムと同じに見えてしまう。



 実用派プログラマー的に言えば、テンソルとは要するにnumpy.ndarrayです。ndarray・・・すなわちn次元配列です。1次元、2次元、3次元、4次元・・・となる配列のことです。


 多次元配列でピンと来ない方。

 例えばこういうことです。1と(1,1)、そして (1 1 1)は全てテンソルです。

 わからねー?


 要するに、これまで普通の数学ではスカラーと呼んでいた単独の値、ベクトルと呼んでいた複数の値、行列と呼んでいたベクトルの集合、これらが全部、テンソルなんです。


 スカラーは0階のテンソル、ベクトルは1階のテンソル、行列は2階のテンソルです。当然、3階のテンソル、4階のテンソルもあります。要するにこれまで別々の概念として扱われていたスカラーとベクトルと行列を一つの概念でひとくくりにしたものがテンソルです。


 「わかんねーよ」と思いますか?思います。僕もそうでした。そんなもんなんに使うんだよ具体的にと。



 実際、僕が最初にテンソルという単語を知ったのは二十代の時です。当時付き合ってた彼女が、大学院修士課程に居て、「テンソル面白いから勉強したほうが良いよ」と説明してくれたのですが、テンソルを扱う具体的なメリットというか必要性が感じられず、そしてなんでこんなもんに夢中なんだこの女は、と思って気がついたら別れてました。いわばテンソル失恋。クソ、テンソル・・・お前さえいなければ・・・。


 おっと失礼。

 しかし必要は発明の母。プログラミング言語は知性の具象表現。自然言語での説明よりもよほど明快です。今度から数学の論文にはgithubのサンプルコードを付けることを強く推奨します。そのほうが百万の言葉よりも雄弁だからです。


 それでテンソルですが、機械学習ではテンソルを扱う、と聞いたので一年奮起して20年ぶりにあの宿敵、テンソルに挑むことと相成ったのです。


 でも・・・・実際の所拍子抜けするほど簡単でした。

 まあ基底を選べば・・ね。よくわかんないけどテンソル業界の人にはそれなりに言いたいことがあるでしょうがここでは無視します。言いたいことがあればWikipediaに書いておくように。


 そもそも、実はみなさんは既にテンソルを見ています。


https://i.gyazo.com/7fc224f6413bed428e474cf132159edd.png


 たとえばこれ。

 これはテンソルです。

 この画像は231 × 215ピクセルです。しかもカラー画像なので3原色があります。

 これをデータ化すると231x215x3の多次元配列になります。つまりテンソルです。


 そして機械学習の世界では、ミニバッチと言って複数の画像をまとめて扱います。100枚の画像を扱うときは100x231x215x3で4階のテンソルを扱うわけです。なんだよ簡単じゃねえか。画像の集合のことかよ!


 これ、ファイルの階層構造の方がへたすればずっと複雑でしょ?

 たとえばMacの場合、/Users/shi3z/Downloadsでもう3階のテンソルになります。

 言葉の問題じゃんか。ビビらせおって。


 そしてディープラーニングでは、学習用の入力をテンソルとして(つまり画像の集合みたいな形で)入力して、出力もテンソルとして(大抵の場合は1階のテンソル、すなわちベクトルで)受け取ります。これだけ。


 文字や音声などは何らかの方法で一度ベクトル化(もちろんテンソル化)してから入力します。一番簡単なのは、a=1、b=2、c=3といった感じでベクトル空間に文字を直接マッピングすることです。



 あれーおかしいな。なんか難しい話みたいになってる。

 いや、簡単なんだこの話は。つまり、aを入力したいとするじゃん。すると作るベクトルは


  input_vector = (1, 0, 0 ,0 ,0)


 になるんだよ。abcdeをそれぞれの次元にマッピングした場合。

 bの場合は


  input_vector = (0, 1, 0 ,0 ,0)


 だよ。

 なんでこんな回りくどいのかって? そうしないとニューラルネットワークに入力できないからだよ。


 ちなみに、いまは説明のために5次元にしてるけど、五次元だと当然ながらabcdeまでしか再現できないから、普通はアルファベット26文字ぶんとスペースと文字列の終わり(EOSと呼ぶ)を入れて28次元くらいで入力するんだよ。


 日本語の場合はもっと次元数が多い。漢字カタカナひらがな記号などが混ざって6000次元とか。英語の場合はスペースで句切られてるんで文字ではなくて単語レベルで次元に落とす場合もあるよ。


 閑話休題。

 で、aかbどちらかである確率が50%ずつの場合は


  input_vector=(0.5, 0.5, 0, 0, 0)


 と入力することになる。まあそういうケースは珍しいけど、こういうこともできるってこと。

 重要なのは、これが出力になった場合で、たとえばこういう出力ベクトルがでてきたとする。


 output_vector = ( 0, 0.1, 0.3, 0.7, 0.1)



 このとき、一番可能性が高いのは0.7になってるdの次元(機械学習では文字がそれぞれの次元に割り当てられているのでこういう言い方をする)なんだけど、正解は(0,0,1,0,0)だとするじゃん。正解との誤差(ロスと言う)を比較して、ニューラルネットワークを今度は出力から入力に向かって逆伝搬させて学習させるわけ。これをバックプロパゲーション(逆伝搬、まんまだね)と呼ぶ。ちなみに、入力から出力に行くのはフォワードだよ。



 さあベクトルとテンソルという言葉がわかってしまえばディープラーニングは半分くらいは理解したも同然です(専門家のツッコミは無用)。だいたいテンソルという言葉がわかんなすぎてつまづきます。最初は。でもベクトルもテンソルなので、ディープラーニングはテンソルの流れを表現すればだいたい上手くいくということでGoogleフレームワークの名前はTensorFlow(テンソルフロー)なわけです。直球。



 数学はとにかく新しい言葉を入れると分かる人が1/10くらいになるのでややこしいですが、テンソルは理解が簡単です。ただし、テンソル場とか別の概念が出てくるとややこしいのですが、機械学習ではテンソル場は使いません。これ以上難しい概念は出てこないから大丈夫だ。そもそもテンソル自体も別に難しくないのに新しい言葉で説明しようとするから難しく見えるだけだ。


 ところで、人工生命とはなにか?

 まあ意味はいろいろありますが、普通は人工生命というと、人工知能的な要素とコンピュータグラフィックス的な要素の両方があります。


 人工知能が知能の再現を目指すのに対し、人工生命は生命の再現を目指すところが違います。


 人工生命がアーティフィシャル・インテリジェンスと呼ばれるのに対し、人工生命はアーティフィシャル・ライフ、またはA-Lifeと呼ばれます。


 今回、ドワンゴ人工知能研究所が開発した人工生命(名前はまだない)は、最先端のディープラーニングと組み合わせた人工生命としてはおそらく世界初となる事例です。


 Unity空間上に存在する仮想生命体からの視覚情報を畳み込みニューラルネットワーク(CNN)に入力し、その結果得られた特徴ベクトルを今度はDeep Q-Learningネットワーク(DQN)に入力します。


 DQNからの出力は、方向キーとスペースキーなど、現実のゲームと同じようなものです。その出力をUnityにキーボード入力として入力すると、Unity内で実際に仮想生命体が動き、穴に落ちたりリンゴを拾ったりします。


 リンゴを拾ったりすると報酬系が働き、穴に落ちると懲罰系が働くようにDQNに強化学習をかけて行くとあら不思議。どんなマップでも効率的にリンゴを探す人工生命のできあがりというわけです。凄い!!


 しかもUnityなので、簡単に他のプレイヤーと接続できます。

 つまり、人間が人工生命の世界にVRで入ったり、沢山の人工生命がお互いに刺激を与え合いながらりんごを奪い合ったり、環境を変化させたりといったことまでが可能なのです!!



 すごいぜ人工生命


 あとはハイパーパラメータのチューニングですが、要はそれをハッカソンで見つけ出そう、というわけです。

 わかりました?