ゲームAI備忘録

ゲームAIに使えそうな知識を備忘録として書き留める

人助けと思って何卒インストールをば! 詰碁/ アルコネ/ 五目並べ

TensorFlow - MNISTのチュートリアル(専門家向け)を試してみる.

TensorFlow - MNISTのチュートリアル(初心者向け)を試してみる. - ゲームAI備忘録の続きです.

MNISTのチュートリアル(専門家向け)を試してみました.
https://www.tensorflow.org/versions/master/tutorials/mnist/pros/index.html

CNNをTensorFlowで構築してMNISTデータを分類するという内容.
下記パラメータで実験したところ,5分程度の学習時間で96%の精度となりました.(初心者向けだと91%)
時間をかければ,99.7%まで上がるみたいです.

パラメータ

実行

GitHub - namakemono/mnist-tensorflow

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# mnist_expert.py
import tensorflow as tf
import os
if not os.path.exists("input_data.py"):
    os.system("curl https://raw.githubusercontent.com/tensorflow/tensorflow/0.6.0/tensorflow/examples/tutorials/mnist/input_data.py -o input_data.py")
import input_data

def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')

def max_pool_2x2(x):
    return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

def weight_variable(shape):
    return tf.Variable(tf.truncated_normal(shape, stddev=0.1))

def bias_variable(shape):
    return tf.Variable(tf.constant(0.1, shape=shape))

def main(args):
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    with tf.Session() as sess:
        # Variables 
        x = tf.placeholder("float", shape=[None, 784])
        y_ = tf.placeholder("float", shape=[None, 10]) # y'
        keep_prob = tf.placeholder("float") # Used for Dropout

        # Build a Multilayer Convolutional Network: INPUT -> [CONV -> RELU -> POOL] * 2 -> FC -> RELU -> FC
        W1, b1 = weight_variable([3,3,1,32]), bias_variable([32]) # 3x3 Filter, input channel: 1, output channel: 32
        W2, b2 = weight_variable([3,3,32,64]), bias_variable([64]) # 3x3 Filter, input channel: 32, output channel: 64
        W3, b3 = weight_variable([7*7*64,1024]), bias_variable([1024])
        W4, b4 = weight_variable([1024,10]), bias_variable([10])

        x_ = tf.reshape(x, [-1, 28, 28, 1]) # 28x28, channel=1
        h1 = max_pool_2x2(tf.nn.relu(conv2d(x_, W1) + b1)) # First Convolutional Layer: CONV -> RELU -> POOL, image size: 28x28 -> 14x14
        h2 = max_pool_2x2(tf.nn.relu(conv2d(h1, W2) + b2)) # Second Convolutional Layer: CONV -> RELU -> POOL, image size: 14x14 -> 7x7
        h3 = tf.nn.relu(tf.matmul(tf.reshape(h2, [-1, 7*7*64]), W3) + b3) # Densely Connected Layer: FC -> RELU
        h4 = tf.nn.dropout(h3, keep_prob) # Dropout
        y = tf.nn.softmax(tf.matmul(h4, W4) + b4) # Readout Layer: FC 
 
        # Train and Evaluate the Model
        cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) # H = -Σ{y' * log(y) + (1-y') * log(1-y)}
        optimizer = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
        sess.run(tf.initialize_all_variables())
        for i in range(1000):
            images, labels = mnist.train.next_batch(50)
            optimizer.run(feed_dict={x: images, y_: labels, keep_prob: 0.5})
            correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
            if i % 100 == 0:
                print "[%d]\ttrain-accuracy:%.5f\ttest-accuracy:%.5f" % (i, accuracy.eval(feed_dict={x: images, y_: labels, keep_prob: 1.0}), accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
        print "Accuracy: %.3f" % accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0})

if __name__ == "__main__":
    tf.app.run()

実行結果

$ time python mnist_expert.py
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
can't determine number of CPU cores: assuming 4
I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 4
can't determine number of CPU cores: assuming 4
I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 4
[0]	test-accuracy:0.10000	test-accuracy:0.10110
[100]	test-accuracy:0.80000	test-accuracy:0.77120
[200]	test-accuracy:0.94000	test-accuracy:0.87740
[300]	test-accuracy:0.86000	test-accuracy:0.89560
[400]	test-accuracy:0.98000	test-accuracy:0.91680
[500]	test-accuracy:0.90000	test-accuracy:0.92050
[600]	test-accuracy:0.96000	test-accuracy:0.93260
[700]	test-accuracy:0.90000	test-accuracy:0.93360
[800]	test-accuracy:0.88000	test-accuracy:0.94250
[900]	test-accuracy:1.00000	test-accuracy:0.94650
Accuracy: 0.951

real	7m39.909s
user	12m24.497s
sys	2m26.872s

References

  • Kingma, Diederik, and Jimmy Ba. "Adam: A method for stochastic optimization." arXiv preprint arXiv:1412.6980 (2014).

AdamOptimizerの元論文

TensorFlow - MNISTのチュートリアル(初心者向け)を試してみる.

TensorFlowのMNISTチュートリアル(初心者向け)を試してみました.
MNIST For ML Beginners

MNISTとは

環境

  • TensorFlow: version 0.6.0

実行

下記スクリプトをmnist_beginner.pyとして貼り付けて実行することで精度を確認できます.
データを拾ってきて加工する部分は,そのままチュートリアルスクリプトinput_data.pyを使っています.

# mnist_beginner.py
import tensorflow as tf
import os
if not os.path.exists("input_data.py"):
    os.system("curl https://raw.githubusercontent.com/tensorflow/tensorflow/0.6.0/tensorflow/examples/tutorials/mnist/input_data.py -o input_data.py")
import input_data

def main(args):
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    with tf.Session() as sess:
        # Variables 
        x = tf.placeholder("float", shape=[None, 784])
        y_ = tf.placeholder("float", shape=[None, 10]) # y'
        # Predicted Class and Cost Function
        W = tf.Variable(tf.zeros([784, 10]))
        b = tf.Variable(tf.zeros([10]))
        sess.run(tf.initialize_all_variables())
        y = tf.nn.softmax(tf.matmul(x, W) + b) # y = W.T * x + b
        cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) # H = -{y' * log(y) + (1-y') * log(1-y)}
        # Train the Model
        optimizer = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
        for i in range(1000):
            batch = mnist.train.next_batch(50)
            optimizer.run(feed_dict={x: batch[0], y_: batch[1]})
        # Evaluate the Model
        correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
        print "Accuracy: %.3f" % accuracy.eval(feed_dict={x:mnist.test.images, y_:mnist.test.labels})

if __name__ == "__main__":
    tf.app.run()

実行結果

$ python mnist_beginner.py 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7309  100  7309    0     0  62090      0 --:--:-- --:--:-- --:--:-- 62470
Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
Extracting MNIST_data/train-images-idx3-ubyte.gz
Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
can't determine number of CPU cores: assuming 4
I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 4
can't determine number of CPU cores: assuming 4
I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 4
Accuracy: 0.909

MacでGTPを利用した囲碁プログラムの対戦

Macではgogui-twogtpを利用することで囲碁プログラム同士を対戦させることができます.

# GNU vs. GNU 試合数:1, 9路盤, SGF形式でgnugo.vs.gnugo.sgfに保存
gogui-twogtp -black "gnugo --mode gtp" -white "gnugo --mode gtp" -games 1 -size 9 -alternate -sgffile gnugo.vs.gnugo -auto

# GNU vs. Fuego 試合数:1, 9路盤, SGF形式でgnugo.vs.fuego.sgfに保存
gogui-twogtp -black "gnugo --mode gtp" -white "fuego" -games 1 -size 9 -alternate -sgffile gnugo.vs.fuego -auto

References

囲碁AI記事一覧

囲碁AI - 訓練データを作るための前段階を作ってみる #003

囲碁AI - どういうモデルを作ればよいか調べてみる.#002 - ゲームAI備忘録
の続きです.

大量の高段者のデータは手に入ったので,このデータを先ほどの訓練データとして変換する必要がある.

とりあえず囲碁AI:gnugoを参考にしてみる.

MacへのGoGuiとFuego, GnuGoのインストール方法 - ゲームAI備忘録
gnugoは以前の記事でインストールすることができる.

gnugoのヘルプを見てみると,

$ gnugo --mode ascii -l game.sgf -L 100 --quiet

Beginning ASCII mode game.

Board Size:   19
Handicap      2
Komi:         0.5
Move Number:  99
To Move:      black
Computer player: White

    White (O) has captured 0 pieces
    Black (X) has captured 2 pieces

    A B C D E F G H J K L M N O P Q R S T        Last move: White R17
 19 . . . . . . . . . . . . . . . . . . . 19
 18 . . . X X X X X X X O . . . . . . . . 18
 17 . . O O O O O O O X O . O X X .(O). . 17
 16 . . . X . . . . O O X . O O . X . . . 16
 15 . . . . . . . . . O X X O X X . . X . 15
 14 . . . . . . . X O X . . X O O . O . . 14
 13 . . . . . . . . X X X X . . . . . . . 13
 12 . . . . . . . O O X X . . O . X O . . 12
 11 . . . . . . . . . O O X X . . X O . . 11
 10 . . . X . . . . . O X O . X X O . . . 10
  9 . . . . . . . . . . . . . . . O . . .  9
  8 . . . . . . . . . . . . . . . . . . .  8
  7 . . . . . . . . . . . . . . . . . . .  7
  6 . . . . . . . O O . X . . . X . . . .  6
  5 . . . . . . . X O X O O . O O . O . .  5
  4 . . . X . . . X O O X . O . . + O . .  4
  3 . . . . . . X . X O O X X . X X O . .  3
  2 . . . . . . . . . X X . . . . . X O .  2
  1 . . . . . . . . . . . . . . . . . . .  1
    A B C D E F G H J K L M N O P Q R S T

とすれば,ファイル名がgame.sgfとなるSGFファイルを読み込み,100手の盤面と次の一手(カッコで囲われている箇所)を表示してくれるらしい.

これを利用して,棋譜から終盤までの盤面を表示してみる.

この方式だと遅いので,gnugoのコードをいじってSGFファイルを読み込んで訓練データを出力するプログラムをあとで書く.

囲碁AI - どういうモデルを作ればよいか調べてみる.#002

囲碁AI - 囲碁AIを作ってみる.#001 - ゲームAI備忘録
の続きです.

論文[2]をざっと読む限り,KGS Go Serverの棋譜データを訓練データとしてモデルを構築しているらしい.

半年ぐらい前に書いた「高段者の囲碁棋譜データを取得する方法」を利用して棋譜を取得する.
KGS高段者棋譜の取得方法 - ゲームAI備忘録

論文[2]によると,現在の盤面と次の手からどの程度良い手かを出力するモデルを構築すれば良いらしい.
特徴ベクトルとして下記の8項目を利用しているとある.

  • 現在の石の色(黒白空の3パターン)
  • 呼吸点?(Number of liberties)の数
  • 打ったあとの呼吸点の数
  • 合法手(Legality)かどうか
  • Turns since(5次元) How many turns since a move was played
  • Capture size(7次元) How many opponent stones would be captured
  • Ladder move(1次元) Whether a move at this point is a successful ladder capture
  • KGS rank(9次元) Rank of current player

ややこしいので,とりあえず問題を簡単にするために,現在の盤面と手番の色を入力すると,各候補手ごとに打たれる確率を出力する学習器を作ってみる.

引用文献

囲碁AI - 囲碁AIを作ってみる.#001

数年前はモンテカルロ碁が主流だったが,どうやら最近はDeep LearningのひとつCNNを使った囲碁AIが流行りらしい.

前々から囲碁AIを作るとか言いながら作ってない...ブログにこうやって書くことで背水の陣を敷いてみる....

やらないとダメそうなこと

  • 囲碁をルールどおり打てるAIを作る.
  • SGF形式のファイルを訓練データとして使えるようにする.
  • 他のAI(GnugoやFuego)と対戦できるようにする.

メモ

  • 思いつきでやっているため途中で失踪する可能性があります.
  • 弱いなりにも動くようになったらgithubにでも公開してみます.