スクリーンショット_2019-02-26_1

PICO-8 でニューラルネットワークを使った進化のシミュレータ(ヘビライフ)を作った

過去、何度か移植し続けているものなのだが、ニューラルネットワークを使って生物の進化をシミュレートするヘビライフという環境を、今回 PICO-8 向けに実装した。

(まだ進化の様子がわかりやすく作れていないので公開はしていない。)

このシミュレータはヘビゲームという、蛇を操作して餌を食べると伸びて、どこまで生き残ることができるかに挑戦するゲームを土台に作っている。ヘビゲームのプレイヤーの代わりに蛇自身が行動を判断するようになっている。また蛇は複数体存在し、一定の長さになると上半身と下半身に分裂する。蛇は脳を持っており、分裂時に上半身の脳によく似た、でも少し違うものを下半身にコピーする。また、蛇は死亡するとその体がそのまま餌となる。

添付している画像ではピンク色が蛇、肌色が餌である。よく見てもわかりにくいとは思うが、画像では蛇同士が衝突しそうになったら左右のどちらかに避けるように行動している。

これは進化によるもので、最初は全く避けようとしない。稀に避ける行動を取る蛇が生まれると、直線移動しかしない蛇たちの交通のなかでは衝突しないように避けるわけだから、優性遺伝子だ。しばらくすると選択と淘汰によりその遺伝子を持つ蛇が繁殖するようになる。

昔に作ったシミュレータで、その当時書いた僕の昔のブログの記事も残っている。

以下はこのブログの引用だ。

段階A 原始時代

直進しかしません。まっすぐ進むので、横切るヘビと衝突して死亡して、わずかに運よく生き残ったヘビが居ます。

まれに同じ場所をぐるぐる回る特殊なヘビも生き残ります。

段階B 沈黙時代

生き残りが、段階Aで死亡したヘビの跡(エサ)を食べて成長し、分裂を繰り返します。このとき、分裂したヘビも直進しかしないので一本の長いヘビのようになるか、前のヘビ(親)がエサを食べて体がひとつ伸びるので後ろのヘビ(子)が親の尻尾に頭をぶつけて死亡します。死亡した子供を食べてまた子供を生み、これを繰り返します。

段階C 風雲時代

段階Bで生まれる新しい命が、誕生した瞬間にまれに左右のどちらかに曲がり、親から離れます。親から離れることに成功したヘビがようやく誕生します。

突然変異を待っているので、この段階にたどり着くまでには時間がかかることが多くなります。

段階D 出産バブル期

段階Cで誕生した親離れヘビは、エサを食べて成長し、子供を次々に誕生させます。この子供も親に遺伝しているのでほとんどが親を離れることができます。

また、この子供は障害物をよける能力も備わっています。親は障害物だったので、同じく他の障害物にも「曲がる」という反応を見せているのでしょう。

そして、ヘビが生き残りやすくなったのでフィールド中がヘビだらけになります。

段階E

一定数以上に増えなくなります。エサが足りないことが原因だと思われます。なので、子供を増やすより、いかにして死なないかがポイントとなっているようです。

このとき、今まで単に「曲がる」だけだったヘビの中に、「Uターン」をするものがちらほら現れます。縦横にぐるぐる回ってフィールド中を移動していくのは少々危険で、Uターンにより今まで何度も通っている安全な場所を行き来することを選択したためと考えています。しかし、何度も通った場所はほとんどエサがないので子供を増やすことに成功するのは難しいようです。

また、今までは曲がる方向が左にしか曲がらない、右にしか曲がらない、といったヘビばかりでしたが、前に障害物があるとき、右に障害物があれば左へ、左に障害物があれば右へ曲がるタイプも居るようです(きちんと確認はしていませんが)。

わりと優秀なヘビたちがこの段階で誕生しているようですね。

これをもっと面白くしたい

引用した『前に障害物があるとき、右に障害物があれば左へ、左に障害物があれば右へ曲がるタイプも居るようです』という点はやや疑問がある。というのも理由は社会性が生まれるからだ。

段階 E でさらに待つと、遺伝子的に利己的に働くため共存する社会を形成するようになる。例えば避けるときのルールは「右に曲がる」と社会的なルールが決まると「左に曲がりたがる蛇」は淘汰される。なぜなら並走する蛇が他の蛇を避けようとするときにこのルールが決まっていないとその蛇同士が衝突して死んでしまうからだ。ルールを守らない蛇は生き残れないようになるということだ。これを社会性と言うのは大げさではあるのだが。

ではもっと面白くするにはどうしたらよいか。面白いというのは、想像を超える進化をするという意味でもある。

仕組み

まずは脳がどうなっているか解説する必要があるだろう。タイトルの通り、脳はニューラルネットワークという数理モデルを使っている。このモデルは複数の入力(刺激)に対して重み計算により出力を決定するもので、この重みが脳の思考回路というわけだ。入力は蛇の頭の前・左・右に障害物(他の蛇の体)があるかないか、である。そして出力は直進・左折・右折のいずれかだ。進化するように、分裂した下半身側の脳の重みに変異を与えている。この重みが入力に対して、次第に生き残る出力をするようになっていくことで、進化が始まる。

ニューラルネットワークは入力の数、出力の数にルールはない。なので先程の障害物だけでなく、餌の位置も入力したり、一定距離の障害物にも反応させるようにする、などのアイデアが出てくる。もちろんこれは既に実装して長時間稼働させてみたが、どうも面白くならない。ニューラルネットワークの容量の問題なのか、待っている時間が足りないのか、それともこのルールではこれ以上期待できないからなのか。

面白くなるのか?

例えば、餌をすべて横取りしていくような貪欲な蛇、集団で他の蛇を捕まえて餌を確保するなど、そんな行動をとったほうが生物らしい。しかし、このモデルではそこまで進化することは今までなかった。

このルールのアイデアは良かったと思っているが、更に期待してしまっているのだろうか。

遺伝子は体の色にも現れ、より多くの情報を処理できるように脳をディープラーニング(多層ニューラルネットワーク)に取り替えて、蛇の頭の周囲の状態(体の色なども含む)をより詳細に入力することで何か変わるかもしれないとも思ったりしているのだが、これは実行時間的に進化まで待つことができる気がしない。今のように頭の1マス隣の状態しか見えていないくらいの情報の量が程よいのではないか、と思う。

より面白くなるようにもう少し工夫をしていこうとは思っているが、これ以上は PICO-8 で行う必要がないのではないか、と思ったりする。ライブラリレベルだと C++, C#、プラットフォームだと Unity 版を github で公開しているので、それを改造するほうが処理速度やらなんやらで利点が多い。ということで、PICO-8 版は少し改良したら公開して終わりにしようと思っている。

ローグライク(仮)の作業が進まないので、ヘビライフの方は気が向いたときに改造して遊ぼうと思う。

応援してくださると嬉しいです。よろしくお願いいたします!