turn this jyputer notebook into python 3 script : # Init and helper functions
import tensorflow as tf
import numpy as np
import PIL
import urllib, cStringIO
import glob
from IPython.core.display import Markdown
from IPython.display import Image, display

import helper_functions as hf
import tensorflow_chessbot

np.set_printoptions(precision=2, suppress=True)
Let's load the tiles in for the training and test dataset, and then split them in a 90/10 ratio

# All tiles with pieces in random organizations
all_paths = np.array(glob.glob("tiles/train_tiles_C/*/*.png")) # TODO : (set labels correctly)

# Shuffle order of paths so when we split the train/test sets the order of files doesn't affect it
np.random.shuffle(all_paths)

ratio = 0.9 # training / testing ratio
divider = int(len(all_paths) * ratio)
train_paths = all_paths[:divider]
test_paths = all_paths[divider:]

# Training dataset
# Generated by programmatic screenshots of lichess.org/editor/<FEN-string>
print "Loading %d Training tiles" % train_paths.size
train_images, train_labels = hf.loadFENtiles(train_paths) # Load from generated set

# Test dataset, taken from screenshots of the starting position
print "Loading %d Training tiles" % test_paths.size
test_images, test_labels = hf.loadFENtiles(test_paths) # Load from generated set

train_dataset = hf.DataSet(train_images, train_labels, dtype=tf.float32)
test_dataset = hf.DataSet(test_images, test_labels, dtype=tf.float32)
Loading 8294 Training tiles
. . . . . . . . . Done
Loading 922 Training tiles
. Done
Looks good. Now that we've loaded the data, let's build up a deep CNN classifier based off of this beginner tutorial on tensorflow.

print "Setting up CNN..."
def weight_variable(shape, name=""):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial, name)

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

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

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

x = tf.placeholder(tf.float32, [None, 32*32])

# First layer : 32 features
W_conv1 = weight_variable([5, 5, 1, 32], name='W1')
b_conv1 = bias_variable([32], name='B1')

x_image = tf.reshape(x, [-1,32,32,1])

h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1, name='Conv1')
h_pool1 = max_pool_2x2(h_conv1, name='Pool1')

# Second convolutional layer : 64 features
W_conv2 = weight_variable([5, 5, 32, 64], name='W2')
b_conv2 = bias_variable([64], name='B2')

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2, name='Conv2')
h_pool2 = max_pool_2x2(h_conv2, name='Pool2')

# Densely connected layer : 1024 neurons, image size now 8x8
W_fc1 = weight_variable([8 * 8 * 64, 1024], name='W3')
b_fc1 = bias_variable([1024], name='B3')

h_pool2_flat = tf.reshape(h_pool2, [-1, 8*8*64], name='Pool3')
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1, 'MatMult3')

# Dropout
keep_prob = tf.placeholder("float", name='KeepProb')
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob, name='Drop4')

# Readout layer : softmax, 13 features
W_fc2 = weight_variable([1024, 13], name='W5')
b_fc2 = bias_variable([13], name='B5')

y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2, name='Ypredict')

# # Old single layer regression classifier
# W = tf.Variable(tf.zeros([32*32, 13]))
# b = tf.Variable(tf.zeros([13]))
# y = tf.nn.softmax(tf.matmul(x, W) + b)

# Ground truth labels if exist 
y_ = tf.placeholder(tf.float32, [None, 13], name='Ytruth')

cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv), name='CrossEntropy')

# train_step = tf.train.GradientDescentOptimizer(0.001).minimize(cross_entropy)
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1), name='CorrectPrediction')
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"), name='Accuracy')

# Add ops to save and restore all the variables.
saver = tf.train.Saver()

# Start Interactive session for rest of notebook (else we'd want to close session)
sess = tf.InteractiveSession()

# Training vs loading existing model
do_training = False

# Number of steps
N = 10000

if do_training:
    #Initialize session
    sess.run(tf.initialize_all_variables())
    
    # Training
    print "Training for %d steps..." % N
    for i in range(N):
        # Get next batch for training
        batch_xs, batch_ys = train_dataset.next_batch(100)

        # Print out progress to screen
        if ((i+1) % 100) == 0:
            train_accuracy = accuracy.eval(feed_dict={
                x:batch_xs, y_: batch_ys, keep_prob: 1.0})
            print "\n\t%d/%d, training accuracy %g" % (i+1, N, train_accuracy),
        elif ((i+1) % 10) == 0:
            print '.',

        # Train model with batch
        sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys, keep_prob: 0.5})

    print "Finished training."

    # Save model checkpoint
    save_path = saver.save(sess, "saved_models/model_%d.ckpt" % N)
    print "Model saved in file: ", save_path

else:
    # Restore model from checkpoint
    model_name = "saved_models/model_%d.ckpt" % N
    print "Loading model '%s'" % model_name
    saver.restore(sess, model_name)
    print "Model restored."
    
# Testing
print "Accuracy: %g\n" % accuracy.eval(feed_dict={x: test_dataset.images,
                                                  y_: test_dataset.labels,
                                                  keep_prob: 1.0})
Setting up CNN...
Training for 10000 steps...
. . . . . . . . . 
	100/10000, training accuracy 0.97 . . . . . . . . . 
	200/10000, training accuracy 0.98 . . . . . . . . . 
	300/10000, training accuracy 0.99 . . . . . . . . . 
	400/10000, training accuracy 0.97 . . . . . . . . . 
	500/10000, training accuracy 1 . . . . . . . . . 
	600/10000, training accuracy 0.98 . . . . . . . . . 
	700/10000, training accuracy 0.99 . . . . . . . . . 
	800/10000, training accuracy 1 . . . . . . . . . 
	900/10000, training accuracy 0.99 . . . . . . . . . 
	1000/10000, training accuracy 0.99 . . . . . . . . . 
	1100/10000, training accuracy 1 . . . . . . . . . 
	1200/10000, training accuracy 0.99 . . . . . . . . . 
	1300/10000, training accuracy 1 . . . . . . . . . 
	1400/10000, training accuracy 1 . . . . . . . . . 
	1500/10000, training accuracy 1 . . . . . . . . . 
	1600/10000, training accuracy 1 . . . . . . . . . 
	1700/10000, training accuracy 1 . . . . . . . . . 
	1800/10000, training accuracy 1 . . . . . . . . . 
	1900/10000, training accuracy 1 . . . . . . . . . 
	2000/10000, training accuracy 1 . . . . . . . . . 
	2100/10000, training accuracy 1 . . . . . . . . . 
	2200/10000, training accuracy 1 . . . . . . . . . 
	2300/10000, training accuracy 1 . . . . . . . . . 
	2400/10000, training accuracy 1 . . . . . . . . . 
	2500/10000, training accuracy 1 . . . . . . . . . 
	2600/10000, training accuracy 1 . . . . . . . . . 
	2700/10000, training accuracy 1 . . . . . . . . . 
	2800/10000, training accuracy 1 . . . . . . . . . 
	2900/10000, training accuracy 1 . . . . . . . . . 
	3000/10000, training accuracy 1 . . . . . . . . . 
	3100/10000, training accuracy 1 . . . . . . . . . 
	3200/10000, training accuracy 1 . . . . . . . . . 
	3300/10000, training accuracy 1 . . . . . . . . . 
	3400/10000, training accuracy 1 . . . . . . . . . 
	3500/10000, training accuracy 1 . . . . . . . . . 
	3600/10000, training accuracy 1 . . . . . . . . . 
	3700/10000, training accuracy 1 . . . . . . . . . 
	3800/10000, training accuracy 1 . . . . . . . . . 
	3900/10000, training accuracy 1 . . . . . . . . . 
	4000/10000, training accuracy 1 . . . . . . . . . 
	4100/10000, training accuracy 1 . . . . . . . . . 
	4200/10000, training accuracy 1 . . . . . . . . . 
	4300/10000, training accuracy 1 . . . . . . . . . 
	4400/10000, training accuracy 1 . . . . . . . . . 
	4500/10000, training accuracy 1 . . . . . . . . . 
	4600/10000, training accuracy 1 . . . . . . . . . 
	4700/10000, training accuracy 1 . . . . . . . . . 
	4800/10000, training accuracy 1 . . . . . . . . . 
	4900/10000, training accuracy 1 . . . . . . . . . 
	5000/10000, training accuracy 1 . . . . . . . . . 
	5100/10000, training accuracy 1 . . . . . . . . . 
	5200/10000, training accuracy 1 . . . . . . . . . 
	5300/10000, training accuracy 1 . . . . . . . . . 
	5400/10000, training accuracy 1 . . . . . . . . . 
	5500/10000, training accuracy 1 . . . . . . . . . 
	5600/10000, training accuracy 1 . . . . . . . . . 
	5700/10000, training accuracy 1 . . . . . . . . . 
	5800/10000, training accuracy 1 . . . . . . . . . 
	5900/10000, training accuracy 1 . . . . . . . . . 
	6000/10000, training accuracy 1 . . . . . . . . . 
	6100/10000, training accuracy 1 . . . . . . . . . 
	6200/10000, training accuracy 1 . . . . . . . . . 
	6300/10000, training accuracy 1 . . . . . . . . . 
	6400/10000, training accuracy 1 . . . . . . . . . 
	6500/10000, training accuracy 1 . . . . . . . . . 
	6600/10000, training accuracy 1 . . . . . . . . . 
	6700/10000, training accuracy 1 . . . . . . . . . 
	6800/10000, training accuracy 1 . . . . . . . . . 
	6900/10000, training accuracy 1 . . . . . . . . . 
	7000/10000, training accuracy 1 . . . . . . . . . 
	7100/10000, training accuracy 1 . . . . . . . . . 
	7200/10000, training accuracy 1 . . . . . . . . . 
	7300/10000, training accuracy 1 . . . . . . . . . 
	7400/10000, training accuracy 1 . . . . . . . . . 
	7500/10000, training accuracy 1 . . . . . . . . . 
	7600/10000, training accuracy 1 . . . . . . . . . 
	7700/10000, training accuracy 1 . . . . . . . . . 
	7800/10000, training accuracy 1 . . . . . . . . . 
	7900/10000, training accuracy 1 . . . . . . . . . 
	8000/10000, training accuracy 1 . . . . . . . . . 
	8100/10000, training accuracy 1 . . . . . . . . . 
	8200/10000, training accuracy 1 . . . . . . . . . 
	8300/10000, training accuracy 1 . . . . . . . . . 
	8400/10000, training accuracy 1 . . . . . . . . . 
	8500/10000, training accuracy 1 . . . . . . . . . 
	8600/10000, training accuracy 1 . . . . . . . . . 
	8700/10000, training accuracy 1 . . . . . . . . . 
	8800/10000, training accuracy 1 . . . . . . . . . 
	8900/10000, training accuracy 1 . . . . . . . . . 
	9000/10000, training accuracy 1 . . . . . . . . . 
	9100/10000, training accuracy 1 . . . . . . . . . 
	9200/10000, training accuracy 1 . . . . . . . . . 
	9300/10000, training accuracy 1 . . . . . . . . . 
	9400/10000, training accuracy 1 . . . . . . . . . 
	9500/10000, training accuracy 1 . . . . . . . . . 
	9600/10000, training accuracy 1 . . . . . . . . . 
	9700/10000, training accuracy 1 . . . . . . . . . 
	9800/10000, training accuracy 1 . . . . . . . . . 
	9900/10000, training accuracy 1 . . . . . . . . . 
	10000/10000, training accuracy 1 Finished training.
Model saved in file:  saved_models/model_10000.ckpt
Accuracy: 1

Let's have a look at the failure cases to get a sense of any mistakes

mistakes = tf.where(~correct_prediction)
mistake_indices = sess.run(mistakes, feed_dict={x: test_dataset.images,
                                                y_: test_dataset.labels,
                                               keep_prob: 1.0}).flatten()

guess_prob, guessed = sess.run([y_conv, tf.argmax(y_conv,1)], feed_dict={x: test_dataset.images, keep_prob: 1.0})


if mistake_indices.size > 0:
    print "%d mistakes:" % mistake_indices.size
    for idx in np.random.choice(mistake_indices, 5, replace=False):
        a,b = test_dataset.labels[idx], guessed[idx]
        print "---"
        print "\t#%d | Actual: '%s', Guessed: '%s'" % (idx, hf.label2Name(a),hf.labelIndex2Name(b))
        print "Actual:",a
        print " Guess:",guess_prob[idx,:]
        hf.display_array(np.reshape(test_dataset.images[idx,:],[32,32]))
else:
    print "%d mistakes" % mistake_indices.size
0 mistakes
It looks like it's been learning that pieces have black borders, and since this pieceSet didn't, and it was a small part of the training set, it just fails and thinks we're looking at blank squares, more training data! From the label probabilities, it did a reasonable job of thinking the pieces were white, and their second best guesses tended to be close to the right answer, the blank spaces just won out.

Also, lets look at several random selections, including successes.

for idx in np.random.choice(test_dataset.num_examples,5,replace=False):
    a,b = test_dataset.labels[idx], guessed[idx]
    print "#%d | Actual: '%s', Guessed: '%s'" % (idx, hf.label2Name(a),hf.labelIndex2Name(b))
    hf.display_array(np.reshape(test_dataset.images[idx,:],[32,32]))
#619 | Actual: ' ', Guessed: ' '

#526 | Actual: 'b', Guessed: 'b'

#133 | Actual: 'P', Guessed: 'P'

#165 | Actual: 'N', Guessed: 'N'

#712 | Actual: 'R', Guessed: 'R'