In [1]:
import os
import sys
import tarfile
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

from six.moves import urllib

In [2]:
sess = tf.Session()

In [3]:
data_dir = 'temp'

if not os.path.exists(data_dir):
    os.makedirs(data_dir)

cifar10_url = 'http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz'

data_file = os.path.join(data_dir, 'cifar-10-binary.tar.gz')

if os.path.isfile(data_file):
    pass
else:
    def progress(block_num, block_size, total_size):
        progress_info = [cifar10_url, float(block_num * block_size) / float(total_size) * 100]
        print('\r Downloading {} - {:.2f}%'.format(*progress_info), end="")
    filepath, _ = urllib.request.urlretrieve(cifar10_url, data_file, progress)
    tarfile.open(filepath, 'r:gz').extractall(data_dir)


 Downloading http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz - 100.00%

In [4]:
batch_size = 128
output_every = 50
generations = 20000
eval_every = 500
image_height = 32
image_width = 32
crop_height = 24
crop_width = 24
num_channels = 3
num_targets = 10
extract_folder = 'cifar-10-batches-bin'

In [5]:
# Exponential Learning Rate Decay Params
learning_rate = 0.1
lr_decay = 0.1
num_gens_to_wait = 250.

In [6]:
image_vec_length = image_height * image_width * num_channels
record_length = 1 + image_vec_length

In [7]:
def read_cifar_files(filename_queue, distort_images=True):
    reader = tf.FixedLengthRecordReader(record_bytes=record_length)
    key, record_string = reader.read(filename_queue)
    record_bytes = tf.decode_raw(record_string, tf.uint8)
    
    image_label = tf.cast(tf.slice(record_bytes, [0], [1]), tf.int32)
    
    image_extracted = tf.reshape(tf.slice(record_bytes, [1], [image_vec_length]), [num_channels, image_height, image_width])
    
    image_uint8image = tf.transpose(image_extracted, [1, 2, 0])
    reshaped_image = tf.cast(image_uint8image, tf.float32)
    
    final_image = tf.image.resize_image_with_crop_or_pad(reshaped_image, crop_width, crop_height)
    
    if distort_images:
        final_image = tf.image.random_flip_left_right(final_image)
        final_image = tf.image.random_brightness(final_image, max_delta=63)
        final_image = tf.image.random_contrast(final_image, lower=0.2, upper=1.8)
        
    final_image = tf.image.per_image_standardization(final_image)
    return (final_image, image_label)

In [8]:
def input_pipline(batch_size, train_logical=True):
    if train_logical:
        files = [os.path.join(data_dir, extract_folder, 'data_batch_{}.bin'.format(i)) for i in range(1, 6)]
    else:
        files = [os.path.join(data_dir, extract_folder, 'test_batch.bin')]
        
    filename_queue = tf.train.string_input_producer(files)
    image, label = read_cifar_files(filename_queue)
    
    # In tensorflow document, recommended size: 
    # min_after_dequeue + (num_threads + a small safety margin) * batch_size
    min_after_dequeue = 5000 
    capacity = min_after_dequeue + 3 * batch_size
    example_batch, label_batch = tf.train.shuffle_batch(
        [image, label],
        batch_size=batch_size,
        capacity=capacity,
        min_after_dequeue=min_after_dequeue)
    
    return (example_batch, label_batch)

In [9]:
def cifar_cnn_model(input_images, batch_size, train_logical=True):
    def truncated_normal_var(name, shape, dtype):
        return (tf.get_variable(name=name, shape=shape, dtype=dtype,
                               initializer=tf.truncated_normal_initializer(stddev=0.05)))
    
    def zero_var(name, shape, dtype):
        return (tf.get_variable(name=name, shape=shape, dtype=dtype,
                               initializer=tf.constant_initializer(0.0)))
    
    with tf.variable_scope('conv1') as scope:
        conv1_kernel = truncated_normal_var(name='conv_kernel1',
                                            shape=[5, 5, 3, 64],
                                            dtype=tf.float32)
        
        conv1 = tf.nn.conv2d(input_images, conv1_kernel, [1, 1, 1, 1], padding='SAME')
        conv1_bias = zero_var(name='conv_bias1', shape=[64], dtype=tf.float32)
        
        conv1_add_bias = tf.nn.bias_add(conv1, conv1_bias)
        relu_conv1 = tf.nn.relu(conv1_add_bias)
        
    pool1 = tf.nn.max_pool(relu_conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME', name='pool_layer1')
    norm1 = tf.nn.lrn(pool1, depth_radius=5, bias=2.0, alpha=1e-3, beta=0.75, name='norm1')
    
    with tf.variable_scope('conv2') as scope:
        conv2_kernel = truncated_normal_var(name='conv_kernel2',
                                            shape=[5, 5, 64, 64],
                                            dtype=tf.float32)
        
        conv2 = tf.nn.conv2d(norm1, conv2_kernel, [1, 1, 1, 1], padding='SAME')
        conv2_bias = zero_var(name='conv_bias2', shape=[64], dtype=tf.float32)
        
        conv2_add_bias = tf.nn.bias_add(conv2, conv2_bias)
        relu_conv2 = tf.nn.relu(conv2_add_bias)
        
    pool2 = tf.nn.max_pool(relu_conv2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME', name='pool_layer2')
    norm2 = tf.nn.lrn(pool2, depth_radius=5, bias=2.0, alpha=1e-3, beta=0.75, name='norm2')
    
    reshaped_output = tf.reshape(norm2, [batch_size, -1])
    reshaped_dim = reshaped_output.get_shape()[1].value
    
    with tf.variable_scope('full1') as scope:
        full_weight1 = truncated_normal_var(name='full_mult1', shape=[reshaped_dim, 384], dtype=tf.float32)
        full_bias1 = zero_var(name='full_bias1', shape=[384], dtype=tf.float32)
        full_layer1 = tf.nn.relu(tf.add(tf.matmul(reshaped_output, full_weight1), full_bias1))
        
    with tf.variable_scope('full2') as scope:
        full_weight2 = truncated_normal_var(name='full_mult2', shape=[384, 192], dtype=tf.float32)
        full_bias2 = zero_var(name='full_bias2', shape=[192], dtype=tf.float32)
        full_layer2 = tf.nn.relu(tf.add(tf.matmul(full_layer1, full_weight2), full_bias2))
        
    with tf.variable_scope('full3') as scope:
        full_weight3 = truncated_normal_var(name='full_mult3', shape=[192, num_targets], dtype=tf.float32)
        full_bias3 = zero_var(name='full_bias3', shape=[num_targets], dtype=tf.float32)
        final_output = tf.add(tf.matmul(full_layer2, full_weight3), full_bias3)
        
    return (final_output)

In [10]:
def cifar_loss(logits, targets):
    targets = tf.squeeze(tf.cast(targets, tf.int32))
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=targets)
    cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')
    return (cross_entropy_mean)

In [11]:
def train_step(loss_value, generation_num):
    model_learning_rate = tf.train.exponential_decay(learning_rate, generation_num, num_gens_to_wait, lr_decay, staircase=True)
    optimizer = tf.train.GradientDescentOptimizer(model_learning_rate)
    train_step = optimizer.minimize(loss_value)
    
    return (train_step)

In [12]:
def accuracy_of_batch(logits, targets):
    targets = tf.squeeze(tf.cast(targets, tf.int32))
    batch_pred = tf.cast(tf.argmax(logits, 1), tf.int32)
    predict_correctly = tf.equal(batch_pred, targets)
    accuracy = tf.reduce_mean(tf.cast(predict_correctly, tf.float32))
    return (accuracy)

In [13]:
images, targets = input_pipline(batch_size, train_logical=True)
test_images, test_targets = input_pipline(batch_size, train_logical=False)

In [14]:
with tf.variable_scope('model_definition') as scope:
    model_output = cifar_cnn_model(images, batch_size)
    scope.reuse_variables()
    test_output = cifar_cnn_model(test_images, batch_size)

In [15]:
loss = cifar_loss(model_output, targets)
accuracy = accuracy_of_batch(test_output, test_targets)

generation_num = tf.Variable(0, trainable=False)
train_op = train_step(loss, generation_num)

In [16]:
init = tf.global_variables_initializer()
sess.run(init)

In [17]:
tf.train.start_queue_runners(sess=sess)


Out[17]:
[<Thread(Thread-4, started daemon 123145549590528)>,
 <Thread(Thread-5, started daemon 123145554845696)>,
 <Thread(Thread-6, started daemon 123145560100864)>,
 <Thread(Thread-7, started daemon 123145565356032)>]

In [18]:
train_loss = []
test_accuracy = []

for i in range(generations):
    _, loss_value = sess.run([train_op, loss])
    
    if (i+1) % output_every == 0:
        train_loss.append(loss_value)
        output = 'Generation {}: Loss = {:.5f}'.format((i+1), loss_value)
        print(output)
        
    if (i+1) % eval_every == 0:
        [temp_accuracy] = sess.run([accuracy])
        test_accuracy.append(temp_accuracy)
        acc_output = ' --- Test Accuracy= {:.2f}%.'.format(100.*temp_accuracy)
        print(acc_output)


Generation 50: Loss = 1.92457
Generation 100: Loss = 1.86472
Generation 150: Loss = 1.65734
Generation 200: Loss = 1.74366
Generation 250: Loss = 1.82194
Generation 300: Loss = 1.79592
Generation 350: Loss = 1.43502
Generation 400: Loss = 1.35306
Generation 450: Loss = 1.45037
Generation 500: Loss = 1.49546
 --- Test Accuracy= 56.25%.
Generation 550: Loss = 1.37202
Generation 600: Loss = 1.54253
Generation 650: Loss = 1.41182
Generation 700: Loss = 1.28541
Generation 750: Loss = 1.35896
Generation 800: Loss = 1.25353
Generation 850: Loss = 1.15399
Generation 900: Loss = 1.19973
Generation 950: Loss = 1.33850
Generation 1000: Loss = 1.16450
 --- Test Accuracy= 53.91%.
Generation 1050: Loss = 1.11620
Generation 1100: Loss = 1.32180
Generation 1150: Loss = 1.37570
Generation 1200: Loss = 1.05415
Generation 1250: Loss = 1.04877
Generation 1300: Loss = 0.95676
Generation 1350: Loss = 1.27770
Generation 1400: Loss = 1.00414
Generation 1450: Loss = 1.14115
Generation 1500: Loss = 1.06935
 --- Test Accuracy= 67.19%.
Generation 1550: Loss = 0.94274
Generation 1600: Loss = 1.05066
Generation 1650: Loss = 1.02126
Generation 1700: Loss = 0.99990
Generation 1750: Loss = 0.88402
Generation 1800: Loss = 0.88201
Generation 1850: Loss = 0.90980
Generation 1900: Loss = 0.97877
Generation 1950: Loss = 0.84149
Generation 2000: Loss = 0.86760
 --- Test Accuracy= 66.41%.
Generation 2050: Loss = 0.78003
Generation 2100: Loss = 0.85000
Generation 2150: Loss = 1.10407
Generation 2200: Loss = 0.90554
Generation 2250: Loss = 0.82713
Generation 2300: Loss = 0.80512
Generation 2350: Loss = 0.88380
Generation 2400: Loss = 0.78466
Generation 2450: Loss = 0.94450
Generation 2500: Loss = 0.83165
 --- Test Accuracy= 64.84%.
Generation 2550: Loss = 0.84370
Generation 2600: Loss = 0.73836
Generation 2650: Loss = 0.74949
Generation 2700: Loss = 0.71136
Generation 2750: Loss = 0.66462
Generation 2800: Loss = 0.74900
Generation 2850: Loss = 0.88319
Generation 2900: Loss = 0.70764
Generation 2950: Loss = 0.74990
Generation 3000: Loss = 0.84837
 --- Test Accuracy= 68.75%.
Generation 3050: Loss = 0.65379
Generation 3100: Loss = 0.87661
Generation 3150: Loss = 0.97396
Generation 3200: Loss = 0.81076
Generation 3250: Loss = 0.61285
Generation 3300: Loss = 0.76095
Generation 3350: Loss = 0.76042
Generation 3400: Loss = 0.82676
Generation 3450: Loss = 0.81349
Generation 3500: Loss = 0.69276
 --- Test Accuracy= 67.19%.
Generation 3550: Loss = 0.68188
Generation 3600: Loss = 0.59683
Generation 3650: Loss = 0.70060
Generation 3700: Loss = 0.70148
Generation 3750: Loss = 0.70073
Generation 3800: Loss = 0.60535
Generation 3850: Loss = 0.53680
Generation 3900: Loss = 0.63923
Generation 3950: Loss = 0.55713
Generation 4000: Loss = 0.68106
 --- Test Accuracy= 67.19%.
Generation 4050: Loss = 0.58435
Generation 4100: Loss = 0.71033
Generation 4150: Loss = 0.66315
Generation 4200: Loss = 0.61121
Generation 4250: Loss = 0.63144
Generation 4300: Loss = 0.55288
Generation 4350: Loss = 0.63605
Generation 4400: Loss = 0.55329
Generation 4450: Loss = 0.60555
Generation 4500: Loss = 0.52830
 --- Test Accuracy= 72.66%.
Generation 4550: Loss = 0.60255
Generation 4600: Loss = 0.42859
Generation 4650: Loss = 0.51289
Generation 4700: Loss = 0.46132
Generation 4750: Loss = 0.59292
Generation 4800: Loss = 0.62519
Generation 4850: Loss = 0.61662
Generation 4900: Loss = 0.58810
Generation 4950: Loss = 0.59964
Generation 5000: Loss = 0.60629
 --- Test Accuracy= 68.75%.
Generation 5050: Loss = 0.53605
Generation 5100: Loss = 0.40163
Generation 5150: Loss = 0.39820
Generation 5200: Loss = 0.53648
Generation 5250: Loss = 0.27409
Generation 5300: Loss = 0.61845
Generation 5350: Loss = 0.39259
Generation 5400: Loss = 0.54494
Generation 5450: Loss = 0.61948
Generation 5500: Loss = 0.56607
 --- Test Accuracy= 78.12%.
Generation 5550: Loss = 0.46491
Generation 5600: Loss = 0.46340
Generation 5650: Loss = 0.45239
Generation 5700: Loss = 0.60482
Generation 5750: Loss = 0.57529
Generation 5800: Loss = 0.52056
Generation 5850: Loss = 0.47477
Generation 5900: Loss = 0.42477
Generation 5950: Loss = 0.55306
Generation 6000: Loss = 0.55448
 --- Test Accuracy= 74.22%.
Generation 6050: Loss = 0.58334
Generation 6100: Loss = 0.34541
Generation 6150: Loss = 0.48879
Generation 6200: Loss = 0.52535
Generation 6250: Loss = 0.30591
Generation 6300: Loss = 0.45593
Generation 6350: Loss = 0.31183
Generation 6400: Loss = 0.35419
Generation 6450: Loss = 0.32687
Generation 6500: Loss = 0.37556
 --- Test Accuracy= 70.31%.
Generation 6550: Loss = 0.44024
Generation 6600: Loss = 0.59837
Generation 6650: Loss = 0.55450
Generation 6700: Loss = 0.38169
Generation 6750: Loss = 0.41364
Generation 6800: Loss = 0.35964
Generation 6850: Loss = 0.46137
Generation 6900: Loss = 0.50838
Generation 6950: Loss = 0.52482
Generation 7000: Loss = 0.27465
 --- Test Accuracy= 71.88%.
Generation 7050: Loss = 0.37894
Generation 7100: Loss = 0.54314
Generation 7150: Loss = 0.39373
Generation 7200: Loss = 0.44145
Generation 7250: Loss = 0.36048
Generation 7300: Loss = 0.42101
Generation 7350: Loss = 0.35862
Generation 7400: Loss = 0.33859
Generation 7450: Loss = 0.39534
Generation 7500: Loss = 0.25300
 --- Test Accuracy= 72.66%.
Generation 7550: Loss = 0.28687
Generation 7600: Loss = 0.40591
Generation 7650: Loss = 0.33776
Generation 7700: Loss = 0.36922
Generation 7750: Loss = 0.35419
Generation 7800: Loss = 0.40446
Generation 7850: Loss = 0.35344
Generation 7900: Loss = 0.36449
Generation 7950: Loss = 0.29276
Generation 8000: Loss = 0.40129
 --- Test Accuracy= 71.88%.
Generation 8050: Loss = 0.25634
Generation 8100: Loss = 0.26627
Generation 8150: Loss = 0.29031
Generation 8200: Loss = 0.27561
Generation 8250: Loss = 0.19904
Generation 8300: Loss = 0.25416
Generation 8350: Loss = 0.33219
Generation 8400: Loss = 0.36432
Generation 8450: Loss = 0.26976
Generation 8500: Loss = 0.34469
 --- Test Accuracy= 80.47%.
Generation 8550: Loss = 0.31937
Generation 8600: Loss = 0.47738
Generation 8650: Loss = 0.20861
Generation 8700: Loss = 0.21701
Generation 8750: Loss = 0.31615
Generation 8800: Loss = 0.38263
Generation 8850: Loss = 0.34262
Generation 8900: Loss = 0.15641
Generation 8950: Loss = 0.30732
Generation 9000: Loss = 0.13771
 --- Test Accuracy= 67.97%.
Generation 9050: Loss = 0.22457
Generation 9100: Loss = 0.29577
Generation 9150: Loss = 0.31152
Generation 9200: Loss = 0.23505
Generation 9250: Loss = 0.14800
Generation 9300: Loss = 0.27342
Generation 9350: Loss = 0.30985
Generation 9400: Loss = 0.20931
Generation 9450: Loss = 0.25761
Generation 9500: Loss = 0.26648
 --- Test Accuracy= 73.44%.
Generation 9550: Loss = 0.26873
Generation 9600: Loss = 0.20377
Generation 9650: Loss = 0.25629
Generation 9700: Loss = 0.25165
Generation 9750: Loss = 0.28824
Generation 9800: Loss = 0.27242
Generation 9850: Loss = 0.21726
Generation 9900: Loss = 0.19265
Generation 9950: Loss = 0.21225
Generation 10000: Loss = 0.15075
 --- Test Accuracy= 81.25%.
Generation 10050: Loss = 0.32554
Generation 10100: Loss = 0.23606
Generation 10150: Loss = 0.17914
Generation 10200: Loss = 0.15799
Generation 10250: Loss = 0.15721
Generation 10300: Loss = 0.22512
Generation 10350: Loss = 0.25476
Generation 10400: Loss = 0.18892
Generation 10450: Loss = 0.28069
Generation 10500: Loss = 0.21594
 --- Test Accuracy= 78.12%.
Generation 10550: Loss = 0.14673
Generation 10600: Loss = 0.19525
Generation 10650: Loss = 0.27473
Generation 10700: Loss = 0.16656
Generation 10750: Loss = 0.13959
Generation 10800: Loss = 0.21505
Generation 10850: Loss = 0.14838
Generation 10900: Loss = 0.16647
Generation 10950: Loss = 0.13928
Generation 11000: Loss = 0.09756
 --- Test Accuracy= 75.78%.
Generation 11050: Loss = 0.24454
Generation 11100: Loss = 0.19911
Generation 11150: Loss = 0.28060
Generation 11200: Loss = 0.14249
Generation 11250: Loss = 0.28696
Generation 11300: Loss = 0.15348
Generation 11350: Loss = 0.11135
Generation 11400: Loss = 0.20227
Generation 11450: Loss = 0.21576
Generation 11500: Loss = 0.15864
 --- Test Accuracy= 75.00%.
Generation 11550: Loss = 0.20092
Generation 11600: Loss = 0.28480
Generation 11650: Loss = 0.11461
Generation 11700: Loss = 0.08565
Generation 11750: Loss = 0.10153
Generation 11800: Loss = 0.09616
Generation 11850: Loss = 0.17244
Generation 11900: Loss = 0.07180
Generation 11950: Loss = 0.15573
Generation 12000: Loss = 0.09115
 --- Test Accuracy= 82.81%.
Generation 12050: Loss = 0.30784
Generation 12100: Loss = 0.10289
Generation 12150: Loss = 0.18767
Generation 12200: Loss = 0.14517
Generation 12250: Loss = 0.35517
Generation 12300: Loss = 0.13831
Generation 12350: Loss = 0.20856
Generation 12400: Loss = 0.17018
Generation 12450: Loss = 0.22771
Generation 12500: Loss = 0.10524
 --- Test Accuracy= 78.91%.
Generation 12550: Loss = 0.11495
Generation 12600: Loss = 0.09958
Generation 12650: Loss = 0.12845
Generation 12700: Loss = 0.20628
Generation 12750: Loss = 0.12966
Generation 12800: Loss = 0.11135
Generation 12850: Loss = 0.12088
Generation 12900: Loss = 0.10637
Generation 12950: Loss = 0.07723
Generation 13000: Loss = 0.03896
 --- Test Accuracy= 78.12%.
Generation 13050: Loss = 0.12895
Generation 13100: Loss = 0.11732
Generation 13150: Loss = 0.15389
Generation 13200: Loss = 0.12432
Generation 13250: Loss = 0.15132
Generation 13300: Loss = 0.08010
Generation 13350: Loss = 0.17835
Generation 13400: Loss = 0.22453
Generation 13450: Loss = 0.07884
Generation 13500: Loss = 0.06686
 --- Test Accuracy= 71.09%.
Generation 13550: Loss = 0.06971
Generation 13600: Loss = 0.09783
Generation 13650: Loss = 0.14029
Generation 13700: Loss = 0.11449
Generation 13750: Loss = 0.02917
Generation 13800: Loss = 0.14634
Generation 13850: Loss = 0.06475
Generation 13900: Loss = 0.07335
Generation 13950: Loss = 0.08473
Generation 14000: Loss = 0.09339
 --- Test Accuracy= 76.56%.
Generation 14050: Loss = 0.04859
Generation 14100: Loss = 0.06659
Generation 14150: Loss = 0.05999
Generation 14200: Loss = 0.05665
Generation 14250: Loss = 0.06077
Generation 14300: Loss = 0.09360
Generation 14350: Loss = 0.26514
Generation 14400: Loss = 0.14441
Generation 14450: Loss = 0.06325
Generation 14500: Loss = 0.06665
 --- Test Accuracy= 74.22%.
Generation 14550: Loss = 0.08282
Generation 14600: Loss = 0.02835
Generation 14650: Loss = 0.03619
Generation 14700: Loss = 0.05730
Generation 14750: Loss = 0.05443
Generation 14800: Loss = 0.12392
Generation 14850: Loss = 0.09216
Generation 14900: Loss = 0.10501
Generation 14950: Loss = 0.01093
Generation 15000: Loss = 0.09445
 --- Test Accuracy= 73.44%.
Generation 15050: Loss = 0.13820
Generation 15100: Loss = 0.13297
Generation 15150: Loss = 0.12486
Generation 15200: Loss = 0.10273
Generation 15250: Loss = 0.07077
Generation 15300: Loss = 0.03549
Generation 15350: Loss = 0.04890
Generation 15400: Loss = 0.03787
Generation 15450: Loss = 0.03619
Generation 15500: Loss = 0.07286
 --- Test Accuracy= 75.00%.
Generation 15550: Loss = 0.05869
Generation 15600: Loss = 0.04078
Generation 15650: Loss = 0.04308
Generation 15700: Loss = 0.08271
Generation 15750: Loss = 0.11693
Generation 15800: Loss = 0.09633
Generation 15850: Loss = 0.05532
Generation 15900: Loss = 0.03275
Generation 15950: Loss = 0.13561
Generation 16000: Loss = 0.07879
 --- Test Accuracy= 75.78%.
Generation 16050: Loss = 0.06640
Generation 16100: Loss = 0.05436
Generation 16150: Loss = 0.14250
Generation 16200: Loss = 0.03627
Generation 16250: Loss = 0.08884
Generation 16300: Loss = 0.10444
Generation 16350: Loss = 0.05243
Generation 16400: Loss = 0.06489
Generation 16450: Loss = 0.02470
Generation 16500: Loss = 0.04078
 --- Test Accuracy= 76.56%.
Generation 16550: Loss = 0.14758
Generation 16600: Loss = 0.03968
Generation 16650: Loss = 0.32499
Generation 16700: Loss = 0.11084
Generation 16750: Loss = 0.17660
Generation 16800: Loss = 0.07884
Generation 16850: Loss = 0.09353
Generation 16900: Loss = 0.01927
Generation 16950: Loss = 0.06720
Generation 17000: Loss = 0.12718
 --- Test Accuracy= 78.91%.
Generation 17050: Loss = 0.09310
Generation 17100: Loss = 0.06835
Generation 17150: Loss = 0.10600
Generation 17200: Loss = 0.07547
Generation 17250: Loss = 0.06910
Generation 17300: Loss = 0.06987
Generation 17350: Loss = 0.01963
Generation 17400: Loss = 0.11444
Generation 17450: Loss = 0.10796
Generation 17500: Loss = 0.13311
 --- Test Accuracy= 70.31%.
Generation 17550: Loss = 0.14407
Generation 17600: Loss = 0.04504
Generation 17650: Loss = 0.11252
Generation 17700: Loss = 0.18221
Generation 17750: Loss = 0.04212
Generation 17800: Loss = 0.03506
Generation 17850: Loss = 0.13334
Generation 17900: Loss = 0.11120
Generation 17950: Loss = 0.04497
Generation 18000: Loss = 0.08715
 --- Test Accuracy= 76.56%.
Generation 18050: Loss = 0.01959
Generation 18100: Loss = 0.07322
Generation 18150: Loss = 0.02271
Generation 18200: Loss = 0.03790
Generation 18250: Loss = 0.08926
Generation 18300: Loss = 0.02107
Generation 18350: Loss = 0.12780
Generation 18400: Loss = 0.03666
Generation 18450: Loss = 0.04406
Generation 18500: Loss = 0.07262
 --- Test Accuracy= 72.66%.
Generation 18550: Loss = 0.03714
Generation 18600: Loss = 0.02804
Generation 18650: Loss = 0.03008
Generation 18700: Loss = 0.06711
Generation 18750: Loss = 0.08509
Generation 18800: Loss = 0.01513
Generation 18850: Loss = 0.03301
Generation 18900: Loss = 0.05487
Generation 18950: Loss = 0.04824
Generation 19000: Loss = 0.05709
 --- Test Accuracy= 75.00%.
Generation 19050: Loss = 0.02015
Generation 19100: Loss = 0.01583
Generation 19150: Loss = 0.02068
Generation 19200: Loss = 0.03043
Generation 19250: Loss = 0.06258
Generation 19300: Loss = 0.03310
Generation 19350: Loss = 0.12279
Generation 19400: Loss = 0.12632
Generation 19450: Loss = 0.06343
Generation 19500: Loss = 0.07850
 --- Test Accuracy= 71.88%.
Generation 19550: Loss = 0.02340
Generation 19600: Loss = 0.03393
Generation 19650: Loss = 0.03927
Generation 19700: Loss = 0.03162
Generation 19750: Loss = 0.05268
Generation 19800: Loss = 0.14797
Generation 19850: Loss = 0.06011
Generation 19900: Loss = 0.11067
Generation 19950: Loss = 0.04774
Generation 20000: Loss = 0.10251
 --- Test Accuracy= 70.31%.

In [19]:
eval_indices = range(0, generations, eval_every)
output_indices = range(0, generations, output_every)

plt.plot(output_indices, train_loss, 'k-')
plt.title('Softmax Loss per Generation')
plt.xlabel('Generation')
plt.ylabel('Softmax Loss')
plt.show()

plt.plot(eval_indices, test_accuracy, 'k-')
plt.title('Test Accuracy')
plt.xlabel('Generation')
plt.ylabel('Accuracy')
plt.show()