tensorflowでライフゲーム【python】
CPPXのXです。
tensorflowを使ってライフゲームを実装したお話をします。
GPUを使ってライフゲームを動かしたいなあ って思ったので、畳み込みを使いつつtensorflowで実装を行いました。
ライフゲームのルールとかは、知っている人しかこの記事に流れてこないと思うので省略します。
実装の流れは、
1. 畳み込んでセルの数え上げ
2. 入力と数え上げ結果を使って次世代の状態を計算
だけです。
環境
- python 3.5.3
- tensorflow 1.9.0
import
import tensorflow as tf import numpy as np import pylab
この辺り使っていきます。
モデル部分
inputs = tf.placeholder(tf.int8, [None, size, size, 1]) # size = 500 flt = tf.initializers.constant([ [1, 1, 1], [1, 0, 1], [1, 1, 1], ]) cnt = tf.contrib.slim.conv2d(tf.cast(inputs, tf.float32), 1, 3, padding="same", activation_fn=None, weights_initializer=flt) outputs = (tf.equal(inputs, 1) & tf.greater_equal(cnt, 2) & tf.less_equal(cnt, 3)) | (tf.equal(inputs, 0) & tf.equal(cnt, 3))
sizeは整数で、適当な幅を指定してください。
入力に対して、真ん中が0でそれ以外1の3 * 3行列を重みとして畳み込みをします。
周囲のセルを数え上げています。
セルの数え上げ結果と、入力を使って次世代セルの状態を計算します。
ライフゲームのルールに則って、計算します。
周囲のセル数が2以上3以下で既にいるなら維持。
周囲のセル数が3でまだいないなら誕生。
それ以外は死滅です。
テスト
sess = tf.Session() sess.run(tf.global_variables_initializer()) img = np.random.randint(0, 100, (1, size, size, 1)) < 30 # 初期化:30%の確率で誕生 img = img.astype(np.int8) with tf.device("/device:GPU:0"): # 自分の環境に応じて for _ in range(1000): pylab.imshow(np.squeeze(img)) pylab.show() img = sess.run(outputs, feed_dict={inputs: img})
乱数でデータを作って1000世代まで計算しています。
特には言うことないです。
sess.run(... の部分で次世代の計算が行われます。
コード全体
import tensorflow as tf import numpy as np import pylab #%% size = 50 inputs = tf.placeholder(tf.int8, [None, size, size, 1]) flt = tf.initializers.constant([ [1, 1, 1], [1, 0, 1], [1, 1, 1], ]) cnt = tf.contrib.slim.conv2d(tf.cast(inputs, tf.float32), 1, 3, padding="same", activation_fn=None, weights_initializer=flt) outputs = (tf.equal(inputs, 1) & tf.greater_equal(cnt, 2) & tf.less_equal(cnt, 3)) | (tf.equal(inputs, 0) & tf.equal(cnt, 3)) #%% sess = tf.Session() sess.run(tf.global_variables_initializer()) #%% img = np.random.randint(0, 100, (1, size, size, 1)) < 30 img = img.astype(np.int8) with tf.device("/device:GPU:0"): for _ in range(1000): pylab.imshow(np.squeeze(img)) pylab.show() img = sess.run(outputs, feed_dict={inputs: img})
確率の概念とか取り入れて何かしたら面白そうだなあ って漠然と思いました。
outputsに使っている計算も、連続関数で近似したら誤差逆伝播も使えると思うし、何かに使えなかろうか。