Slide 1

Slide 1 text

後藤汰誓 Pythonで⼈⼯⽣命を実装する会

Slide 2

Slide 2 text

About cono event このイベントについて

Slide 3

Slide 3 text

⽣命の動きをシミュレートすることによって、 「⽣命とは何か?」と⾔う根源的な問いを探求する分野 ⼈⼯⽣命(ALife)とは? 3

Slide 4

Slide 4 text

nプログラミングの幅を広げたい⼈ n数理シミュレーションに興味を持っている⼈ n⼈⼯⽣命・⼈⼯知能に興味を持っている⼈ 対象となる⼈ 4

Slide 5

Slide 5 text

『⽣命のパターンを作ってみよう』 n Gray-Scottモデル n セルラーオートマトン(1次元) ※主催者はAlifeに全く詳しくありません! 今回やること 5

Slide 6

Slide 6 text

『作って動かすAlife ―実装を通した⼈⼯⽣命モデル理論⼊⾨』 サンプルコード https://github.com/alifelab/alife_book_src 正誤表 https://github.com/alifelab/alife_book_src/wiki/%E6%AD%A3%E8% AA%A4%E8%A1%A8 参考とする本 6

Slide 7

Slide 7 text

Todayʼs dekiru mono. 今回できるもの

Slide 8

Slide 8 text

Gray-Scottモデルに基づいたパターン作成 8

Slide 9

Slide 9 text

セルラーオートマトンによるパターン作成 9

Slide 10

Slide 10 text

Library installation. ライブラリのインストール

Slide 11

Slide 11 text

かっこ内は参考書で想定されているバージョン(最新でも⼀応動いてます) n NumPy (1.14.5) n Vispy (0.5.3) n PyQt (5.10.1) n Pyglet (1.3.2) n Pymunk (5.3.2) n Pillow (5.1.0) n Keras (2.2.0) n TensorFlow (1.8.0) 必要なライブラリ 11

Slide 12

Slide 12 text

① Anacondaをインストール https://www.python.jp/install/anaconda/ ② 以下のコマンドを実⾏ pip install pyglet pymunk vispy keras tensorflow Anacondaを使う(オススメ) 12

Slide 13

Slide 13 text

Making seimeitive pattern. ⽣命のパターンを作る

Slide 14

Slide 14 text

⽣命のパターンを作る 14 ⽣命はさまざまなパターンを持っているが、 そのパターンはどの様にして⽣み出されるのか。

Slide 15

Slide 15 text

⽣物の体や、⾃然界に存在する結晶はそれを構成する要素(細胞・分⼦)が繋が っていく(増えていく)ことで最終的な全体を形作る 設計図があるわけではなく「⾃発的な組織化」が起こっている ⾃⼰組織的な⽣命のパターンの根底にあるのは、同じ要素が少しずつ変化しなが ら「複製」を繰り返す、⾃⼰複製的現象 ⾃⼰組織化(Self-organization) 15

Slide 16

Slide 16 text

Gray-Scott Model Gray-Scottモデル

Slide 17

Slide 17 text

アラン・チューリング(1912~1954) 今⽇のコンピュータの基礎「チューリングマシン」⽣みの親 「The Chemical Basis of Morphogenesis」(1952) ⽣物がどの様にしてその形態を作るのかと⾔うことを ⾃⼰組織的なロジックで数学的に⽰す論⽂ 仮想物質「モルフォゲンを扱う⽅程式」 →「反応拡散系(reaction-diffusion system)」 ⽣成パターンモデルの基礎「反応拡散系」 17

Slide 18

Slide 18 text

反応拡散系の代表例である「Gray-Scottモデル」について学ぼう Gray-Scottモデル 18

Slide 19

Slide 19 text

2つの物質UとVが「反応」そして「拡散」していくことで模様が出来上がる Gray-Scottモデルの仕組み 19

Slide 20

Slide 20 text

Gray-Scottモデルの仕組み:「反応」 20 U V U U U V V V V V V V 物質Uを一定の 補充率で追加 反応:2つのVが エサとしてUを使いVを作る 物質Vは一定の 減量率で不活性化 P U

Slide 21

Slide 21 text

Gray-Scottモデルの仕組み:「拡散」 21 U U U U U U U U U U U U U U U U U U U U U U V V V V V V V V V V V V V V V V

Slide 22

Slide 22 text

物質UとVの濃度の変化を表す式で表される!(u,vはU,Vの濃度で0〜1) 𝜕𝑢 𝜕𝑡 = 𝐷𝑢Δ𝑢 − 𝑢𝑣! + 𝑓 1 − 𝑢 𝜕𝑣 𝜕𝑡 = 𝐷𝑣Δ𝑣 + 𝑢𝑣! − 𝑣(𝑓 + 𝑘) Gray-Scottモデルの振る舞いを表す式 22 変化量 拡散 反応 流入・流出

Slide 23

Slide 23 text

数式を読み解いていこう:変化量 23 u, vは「とある位置(x, y)、とある時間(t)の濃度」 デジタルではこれらの変数x, y, tは離散 𝜕𝑢 𝜕𝑡 , 𝜕𝑣 𝜕𝑡 は「とある位置に、⾜される量(変化量)」 今のステップ t = n 次のステップ t = n+1 + =

Slide 24

Slide 24 text

数式を読み解いていこう:変化量 24 「uとvの変化量は、こういう式で決まるよ〜」 𝜕𝑢 𝜕𝑡 = 𝐷𝑢Δ𝑢 − 𝑢𝑣! + 𝑓 1 − 𝑢 𝜕𝑣 𝜕𝑡 = 𝐷𝑣Δ𝑣 + 𝑢𝑣! − 𝑣(𝑓 + 𝑘)

Slide 25

Slide 25 text

Du, Dvは拡散スピードに関わる定数(Du>Dv) Δu, ΔvのΔは『ラプラシアン』「周りの平均」と「⾃分」の差を表す演算⼦ →とある位置の濃度が変化するとその周りも影響を受ける →拡散しているように⾒える 変化量=定数×周りとの差 ←周囲との差をなくすように物質が増減する 数式を読み解いていこう:拡散 25

Slide 26

Slide 26 text

反応によって増減する濃度量 u:「反応」によって減っていく v:「反応」によって増えていく uが減る量とvが増える量は同じ 数式を読み解いていこう:反応 26

Slide 27

Slide 27 text

f:定数 feed(functionじゃないよ) (1 ‒ u):u(0~1)が0に近ければ⼤量に、1に近ければちょっとだけ供給する k:定数 kill -v(f + k):vが多い時は⼤量に、少ない時はちょっとだけ減らす(Pになる)。 数式を読み解いていこう:uの流⼊・vの流出 27

Slide 28

Slide 28 text

2つの物質の変化量(次に⾜される量)には、 2つの物質の「今の濃度」・「周りの濃度」及びいくつかの定数が関係している! →反応・拡散・反応・拡散…の連鎖が起こる 数式を読み解いていこう:全体 28

Slide 29

Slide 29 text

コードで表そう! 29

Slide 30

Slide 30 text

import sys, os sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定 import numpy as np from alifebook_lib.visualizers import MatrixVisualizer # visualizerの初期化 (Appendix参照) visualizer = MatrixVisualizer() 結果を可視化するための準備 30

Slide 31

Slide 31 text

# シミュレーションの各パラメタ SPACE_GRID_SIZE = 256 # 空間サイズ(縦横のマス数) dx = 0.01 dt = 1 VISUALIZATION_STEP = 8 # 何ステップごとに画⾯を更新するか。 シミュレーション空間の設定 31

Slide 32

Slide 32 text

# モデルの各パラメタ Du = 2e-5 Dv = 1e-5 f, k = 0.035, 0.06 # amorphous # f, k = 0.035, 0.065 # spots # f, k = 0.012, 0.05 # wandering bubbles # f, k = 0.025, 0.05 # waves # f, k = 0.022, 0.051 # stripe 定数の設定 32

Slide 33

Slide 33 text

# 初期化 u = np.ones((SPACE_GRID_SIZE, SPACE_GRID_SIZE)) v = np.zeros((SPACE_GRID_SIZE, SPACE_GRID_SIZE)) # 中央にSQUARE_SIZE四⽅の正⽅形を置く SQUARE_SIZE = 20 u[SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2, SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2] = 0.5 v[SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2, SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2] = 0.25 # 対称性を壊すために、少しノイズを⼊れる u += np.random.rand(SPACE_GRID_SIZE, SPACE_GRID_SIZE)*0.1 v += np.random.rand(SPACE_GRID_SIZE, SPACE_GRID_SIZE)*0.1 初期状態の設定 33

Slide 34

Slide 34 text

while visualizer: # visualizerはウィンドウが閉じられるとFalseを返す for i in range(VISUALIZATION_STEP): # ラプラシアンの計算 laplacian_u = (np.roll(u, 1, axis=0) + np.roll(u, -1, axis=0) + np.roll(u, 1, axis=1) + np.roll(u, -1, axis=1) - 4*u) / (dx*dx) laplacian_v = (np.roll(v, 1, axis=0) + np.roll(v, -1, axis=0) + np.roll(v, 1, axis=1) + np.roll(v, -1, axis=1) - 4*v) / (dx*dx) # Gray-Scottモデル⽅程式 dudt = Du*laplacian_u - u*v*v + f*(1.0-u) dvdt = Dv*laplacian_v + u*v*v - (f+k)*v u += dt * dudt v += dt * dvdt # 表⽰をアップデート visualizer.update(u) シミュレーション 34

Slide 35

Slide 35 text

Cellular Automaton セルラー・オートマトン

Slide 36

Slide 36 text

格⼦状に並んだセルで世界が構成されている、ようなモデル セル:細胞、(表の)マス セルの状態は周りのセルの状態によって決まる セルラー・オートマトン(Cellular Automaton) 36

Slide 37

Slide 37 text

1. 空間がある セルを格⼦状に敷き詰める「空間」 2. 時間がある セルの状態を変更する時間単位(ステップ)がある 3. 状態がある 「⽣死の2つ」や「誕⽣、維持、志望の3つ」 4. セルの状態を変える条件がある 基本的には、対象のセルの現在の状態と隣接するセルの状態によって、対象の セルの状態を決定する セルラー・オートマトンのルール 37

Slide 38

Slide 38 text

⿊(1):⽣きている状態 ⽩(2):死んでいる状態 1次元セルラー・オートマトン 38 0 1 0

Slide 39

Slide 39 text

「⾃⾝が1で隣り合うセルが0であるとき、⾃⾝も0に変化する」 というルールを設定してみると… 1次元セルラー・オートマトン 39 0 1 0 0 1世代後

Slide 40

Slide 40 text

3つのセルがなすパターンは8個ある それらが⽣む次世代のセルの状態を決める 上に⽰しているパターンは 000111110(2進数)= 30(10進数)であるため ルール30と呼ばれる。 ルール30 40 111 110 101 100 011 010 001 000 0 0 0 0 1 1 1 1

Slide 41

Slide 41 text

ルール30をやってみよう 41

Slide 42

Slide 42 text

import sys, os sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートす るための設定 import numpy as np from alifebook_lib.visualizers import ArrayVisualizer # visualizerの初期化 (Appendix参照) visualizer = ArrayVisualizer() 結果を可視化するための準備 42

Slide 43

Slide 43 text

SPACE_SIZE = 600 # CAのバイナリコーディングされたルール (Wolfram code) RULE = 30 # CAの状態空間 state = np.zeros(SPACE_SIZE, dtype=np.int8) next_state = np.empty(SPACE_SIZE, dtype=np.int8) シミュレーションの設定 43

Slide 44

Slide 44 text

# 最初の状態を初期化 state[len(state)//2] = 1 while visualizer: # stateから計算した次の結果をnext_stateに保存 for i in range(SPACE_SIZE): # left, center, right cellの状態を取得 l = state[i-1] c = state[i] r = state[(i+1)%SPACE_SIZE] シミュレーションを実⾏・可視化 44

Slide 45

Slide 45 text

neighbor_cell_code = 2**2 * l + 2**1 * c + 2**0 * r if (RULE >> neighbor_cell_code) & 1: next_state[i] = 1 else: next_state[i] = 0 # 最後に⼊れ替え state, next_state = next_state, state # 表⽰をアップデート visualizer.update(1-state) シミュレーションを可視化(続き) 45

Slide 46

Slide 46 text

n RULE の値を変更 # CAのバイナリコーディングされたルール (Wolfram code) RULE = 110 おすすめルール:40・232・94・108・54・90・110・121 n 最初の状態を初期化 の部分を変更 # 最初の状態を初期化 ### ランダム ### state[:] = np.random.randint(2, size=len(state)) いろいろ変えて遊んでみよう 46