Transfer Learning

Most of the time you won't want to train a whole convolutional network yourself. Modern ConvNets training on huge datasets like ImageNet take weeks on multiple GPUs. Instead, most people use a pretrained network either as a fixed feature extractor, or as an initial network to fine tune. In this notebook, you'll be using VGGNet trained on the ImageNet dataset as a feature extractor. Below is a diagram of the VGGNet architecture.

VGGNet is great because it's simple and has great performance, coming in second in the ImageNet competition. The idea here is that we keep all the convolutional layers, but replace the final fully connected layers with our own classifier. This way we can use VGGNet as a feature extractor for our images then easily train a simple classifier on top of that. What we'll do is take the first fully connected layer with 4096 units, including thresholding with ReLUs. We can use those values as a code for each image, then build a classifier on top of those codes.

You can read more about transfer learning from the CS231n course notes.

Pretrained VGGNet

We'll be using a pretrained network from https://github.com/machrisaa/tensorflow-vgg. Make sure to clone this repository to the directory you're working from. You'll also want to rename it so it has an underscore instead of a dash.

git clone https://github.com/machrisaa/tensorflow-vgg.git tensorflow_vgg

This is a really nice implementation of VGGNet, quite easy to work with. The network has already been trained and the parameters are available from this link. You'll need to clone the repo into the folder containing this notebook. Then download the parameter file using the next cell.


In [1]:
from urllib.request import urlretrieve
from os.path import isfile, isdir
from tqdm import tqdm

vgg_dir = 'tensorflow_vgg/'
# Make sure vgg exists
if not isdir(vgg_dir):
    raise Exception("VGG directory doesn't exist!")

class DLProgress(tqdm):
    last_block = 0

    def hook(self, block_num=1, block_size=1, total_size=None):
        self.total = total_size
        self.update((block_num - self.last_block) * block_size)
        self.last_block = block_num

if not isfile(vgg_dir + "vgg16.npy"):
    with DLProgress(unit='B', unit_scale=True, miniters=1, desc='VGG16 Parameters') as pbar:
        urlretrieve(
            'https://s3.amazonaws.com/content.udacity-data.com/nd101/vgg16.npy',
            vgg_dir + 'vgg16.npy',
            pbar.hook)
else:
    print("Parameter file already exists!")


Parameter file already exists!

Flower power

Here we'll be using VGGNet to classify images of flowers. To get the flower dataset, run the cell below. This dataset comes from the TensorFlow inception tutorial.


In [2]:
import tarfile

dataset_folder_path = 'flower_photos'

class DLProgress(tqdm):
    last_block = 0

    def hook(self, block_num=1, block_size=1, total_size=None):
        self.total = total_size
        self.update((block_num - self.last_block) * block_size)
        self.last_block = block_num

if not isfile('flower_photos.tar.gz'):
    with DLProgress(unit='B', unit_scale=True, miniters=1, desc='Flowers Dataset') as pbar:
        urlretrieve(
            'http://download.tensorflow.org/example_images/flower_photos.tgz',
            'flower_photos.tar.gz',
            pbar.hook)

if not isdir(dataset_folder_path):
    with tarfile.open('flower_photos.tar.gz') as tar:
        tar.extractall()
        tar.close()

ConvNet Codes

Below, we'll run through all the images in our dataset and get codes for each of them. That is, we'll run the images through the VGGNet convolutional layers and record the values of the first fully connected layer. We can then write these to a file for later when we build our own classifier.

Here we're using the vgg16 module from tensorflow_vgg. The network takes images of size $224 \times 224 \times 3$ as input. Then it has 5 sets of convolutional layers. The network implemented here has this structure (copied from the source code):

self.conv1_1 = self.conv_layer(bgr, "conv1_1")
self.conv1_2 = self.conv_layer(self.conv1_1, "conv1_2")
self.pool1 = self.max_pool(self.conv1_2, 'pool1')

self.conv2_1 = self.conv_layer(self.pool1, "conv2_1")
self.conv2_2 = self.conv_layer(self.conv2_1, "conv2_2")
self.pool2 = self.max_pool(self.conv2_2, 'pool2')

self.conv3_1 = self.conv_layer(self.pool2, "conv3_1")
self.conv3_2 = self.conv_layer(self.conv3_1, "conv3_2")
self.conv3_3 = self.conv_layer(self.conv3_2, "conv3_3")
self.pool3 = self.max_pool(self.conv3_3, 'pool3')

self.conv4_1 = self.conv_layer(self.pool3, "conv4_1")
self.conv4_2 = self.conv_layer(self.conv4_1, "conv4_2")
self.conv4_3 = self.conv_layer(self.conv4_2, "conv4_3")
self.pool4 = self.max_pool(self.conv4_3, 'pool4')

self.conv5_1 = self.conv_layer(self.pool4, "conv5_1")
self.conv5_2 = self.conv_layer(self.conv5_1, "conv5_2")
self.conv5_3 = self.conv_layer(self.conv5_2, "conv5_3")
self.pool5 = self.max_pool(self.conv5_3, 'pool5')

self.fc6 = self.fc_layer(self.pool5, "fc6")
self.relu6 = tf.nn.relu(self.fc6)

So what we want are the values of the first fully connected layer, after being ReLUd (self.relu6). To build the network, we use

with tf.Session() as sess:
    vgg = vgg16.Vgg16()
    input_ = tf.placeholder(tf.float32, [None, 224, 224, 3])
    with tf.name_scope("content_vgg"):
        vgg.build(input_)

This creates the vgg object, then builds the graph with vgg.build(input_). Then to get the values from the layer,

feed_dict = {input_: images}
codes = sess.run(vgg.relu6, feed_dict=feed_dict)

In [3]:
import os

import numpy as np
import tensorflow as tf

from tensorflow_vgg import vgg16
from tensorflow_vgg import utils

In [4]:
data_dir = 'flower_photos/'
contents = os.listdir(data_dir)
classes = [each for each in contents if os.path.isdir(data_dir + each)]

Below I'm running images through the VGG network in batches.

Exercise: Below, build the VGG network. Also get the codes from the first fully connected layer (make sure you get the ReLUd values).


In [5]:
# Set the batch size higher if you can fit in in your GPU memory
batch_size = 10
codes_list = []
labels = []
batch = []

codes = None

with tf.Session() as sess:
    
    # TODO: Build the vgg network here
    vgg = vgg16.Vgg16()
    input_ = tf.placeholder(tf.float32, [None, 224, 224, 3])
    with tf.name_scope("content_vgg"):
        vgg.build(input_)
    
    
    for each in classes:
        print("Starting {} images".format(each))
        class_path = data_dir + each
        files = os.listdir(class_path)
        for ii, file in enumerate(files, 1):
            # Add images to the current batch
            # utils.load_image crops the input images for us, from the center
            img = utils.load_image(os.path.join(class_path, file))
            batch.append(img.reshape((1, 224, 224, 3)))
            labels.append(each)
            
            # Running the batch through the network to get the codes
            if ii % batch_size == 0 or ii == len(files):
                
                # Image batch to pass to VGG network
                images = np.concatenate(batch)
                
                # TODO: Get the values from the relu6 layer of the VGG network
                feed_dict = {input_: images}
                codes_batch = sess.run(vgg.relu6, feed_dict=feed_dict)
                
                # Here I'm building an array of the codes
                if codes is None:
                    codes = codes_batch
                else:
                    codes = np.concatenate((codes, codes_batch))
                
                # Reset to start building the next batch
                batch = []
                print('{} images processed'.format(ii))


/home/carnd/deep-learning/transfer-learning/tensorflow_vgg/vgg16.npy
npy file loaded
build model started
build model finished: 0s
Starting dandelion images
10 images processed
20 images processed
30 images processed
40 images processed
50 images processed
60 images processed
70 images processed
80 images processed
90 images processed
100 images processed
110 images processed
120 images processed
130 images processed
140 images processed
150 images processed
160 images processed
170 images processed
180 images processed
190 images processed
200 images processed
210 images processed
220 images processed
230 images processed
240 images processed
250 images processed
260 images processed
270 images processed
280 images processed
290 images processed
300 images processed
310 images processed
320 images processed
330 images processed
340 images processed
350 images processed
360 images processed
370 images processed
380 images processed
390 images processed
400 images processed
410 images processed
420 images processed
430 images processed
440 images processed
450 images processed
460 images processed
470 images processed
480 images processed
490 images processed
500 images processed
510 images processed
520 images processed
530 images processed
540 images processed
550 images processed
560 images processed
570 images processed
580 images processed
590 images processed
600 images processed
610 images processed
620 images processed
630 images processed
640 images processed
650 images processed
660 images processed
670 images processed
680 images processed
690 images processed
700 images processed
710 images processed
720 images processed
730 images processed
740 images processed
750 images processed
760 images processed
770 images processed
780 images processed
790 images processed
800 images processed
810 images processed
820 images processed
830 images processed
840 images processed
850 images processed
860 images processed
870 images processed
880 images processed
890 images processed
898 images processed
Starting roses images
10 images processed
20 images processed
30 images processed
40 images processed
50 images processed
60 images processed
70 images processed
80 images processed
90 images processed
100 images processed
110 images processed
120 images processed
130 images processed
140 images processed
150 images processed
160 images processed
170 images processed
180 images processed
190 images processed
200 images processed
210 images processed
220 images processed
230 images processed
240 images processed
250 images processed
260 images processed
270 images processed
280 images processed
290 images processed
300 images processed
310 images processed
320 images processed
330 images processed
340 images processed
350 images processed
360 images processed
370 images processed
380 images processed
390 images processed
400 images processed
410 images processed
420 images processed
430 images processed
440 images processed
450 images processed
460 images processed
470 images processed
480 images processed
490 images processed
500 images processed
510 images processed
520 images processed
530 images processed
540 images processed
550 images processed
560 images processed
570 images processed
580 images processed
590 images processed
600 images processed
610 images processed
620 images processed
630 images processed
640 images processed
641 images processed
Starting daisy images
10 images processed
20 images processed
30 images processed
40 images processed
50 images processed
60 images processed
70 images processed
80 images processed
90 images processed
100 images processed
110 images processed
120 images processed
130 images processed
140 images processed
150 images processed
160 images processed
170 images processed
180 images processed
190 images processed
200 images processed
210 images processed
220 images processed
230 images processed
240 images processed
250 images processed
260 images processed
270 images processed
280 images processed
290 images processed
300 images processed
310 images processed
320 images processed
330 images processed
340 images processed
350 images processed
360 images processed
370 images processed
380 images processed
390 images processed
400 images processed
410 images processed
420 images processed
430 images processed
440 images processed
450 images processed
460 images processed
470 images processed
480 images processed
490 images processed
500 images processed
510 images processed
520 images processed
530 images processed
540 images processed
550 images processed
560 images processed
570 images processed
580 images processed
590 images processed
600 images processed
610 images processed
620 images processed
630 images processed
633 images processed
Starting tulips images
10 images processed
20 images processed
30 images processed
40 images processed
50 images processed
60 images processed
70 images processed
80 images processed
90 images processed
100 images processed
110 images processed
120 images processed
130 images processed
140 images processed
150 images processed
160 images processed
170 images processed
180 images processed
190 images processed
200 images processed
210 images processed
220 images processed
230 images processed
240 images processed
250 images processed
260 images processed
270 images processed
280 images processed
290 images processed
300 images processed
310 images processed
320 images processed
330 images processed
340 images processed
350 images processed
360 images processed
370 images processed
380 images processed
390 images processed
400 images processed
410 images processed
420 images processed
430 images processed
440 images processed
450 images processed
460 images processed
470 images processed
480 images processed
490 images processed
500 images processed
510 images processed
520 images processed
530 images processed
540 images processed
550 images processed
560 images processed
570 images processed
580 images processed
590 images processed
600 images processed
610 images processed
620 images processed
630 images processed
640 images processed
650 images processed
660 images processed
670 images processed
680 images processed
690 images processed
700 images processed
710 images processed
720 images processed
730 images processed
740 images processed
750 images processed
760 images processed
770 images processed
780 images processed
790 images processed
799 images processed
Starting sunflowers images
10 images processed
20 images processed
30 images processed
40 images processed
50 images processed
60 images processed
70 images processed
80 images processed
90 images processed
100 images processed
110 images processed
120 images processed
130 images processed
140 images processed
150 images processed
160 images processed
170 images processed
180 images processed
190 images processed
200 images processed
210 images processed
220 images processed
230 images processed
240 images processed
250 images processed
260 images processed
270 images processed
280 images processed
290 images processed
300 images processed
310 images processed
320 images processed
330 images processed
340 images processed
350 images processed
360 images processed
370 images processed
380 images processed
390 images processed
400 images processed
410 images processed
420 images processed
430 images processed
440 images processed
450 images processed
460 images processed
470 images processed
480 images processed
490 images processed
500 images processed
510 images processed
520 images processed
530 images processed
540 images processed
550 images processed
560 images processed
570 images processed
580 images processed
590 images processed
600 images processed
610 images processed
620 images processed
630 images processed
640 images processed
650 images processed
660 images processed
670 images processed
680 images processed
690 images processed
699 images processed

In [6]:
# write codes to file
with open('codes', 'w') as f:
    codes.tofile(f)
    
# write labels to file
import csv
with open('labels', 'w') as f:
    writer = csv.writer(f, delimiter='\n')
    writer.writerow(labels)

Building the Classifier

Now that we have codes for all the images, we can build a simple classifier on top of them. The codes behave just like normal input into a simple neural network. Below I'm going to have you do most of the work.


In [7]:
# read codes and labels from file
import csv

with open('labels') as f:
    reader = csv.reader(f, delimiter='\n')
    labels = np.array([each for each in reader if len(each) > 0]).squeeze()
with open('codes') as f:
    codes = np.fromfile(f, dtype=np.float32)
    codes = codes.reshape((len(labels), -1))

Data prep

As usual, now we need to one-hot encode our labels and create validation/test sets. First up, creating our labels!

Exercise: From scikit-learn, use LabelBinarizer to create one-hot encoded vectors from the labels.


In [11]:
from sklearn import preprocessing
lb = preprocessing.LabelBinarizer()
# lb.fit(labels)
labels_vecs = lb.fit_transform(labels) # Your one-hot encoded labels array here

Now you'll want to create your training, validation, and test sets. An important thing to note here is that our labels and data aren't randomized yet. We'll want to shuffle our data so the validation and test sets contain data from all classes. Otherwise, you could end up with testing sets that are all one class. Typically, you'll also want to make sure that each smaller set has the same the distribution of classes as it is for the whole data set. The easiest way to accomplish both these goals is to use StratifiedShuffleSplit from scikit-learn.

You can create the splitter like so:

ss = StratifiedShuffleSplit(n_splits=1, test_size=0.2)

Then split the data with

splitter = ss.split(x, y)

ss.split returns a generator of indices. You can pass the indices into the arrays to get the split sets. The fact that it's a generator means you either need to iterate over it, or use next(splitter) to get the indices. Be sure to read the documentation and the user guide.

Exercise: Use StratifiedShuffleSplit to split the codes and labels into training, validation, and test sets.


In [21]:
from sklearn.model_selection import StratifiedShuffleSplit
ss = StratifiedShuffleSplit(n_splits=1, test_size=0.2)

for train_index, test_index in ss.split(codes, labels_vecs):
#     print("TRAIN:", train_index, "TEST:", test_index)
    train_x, test_x_full = codes[train_index], codes[test_index]
    train_y, test_y_full = labels_vecs[train_index], labels_vecs[test_index]

# train_x, train_y =
splitting_idx = int(len(test_x_full)/2)

val_x, val_y = test_x_full[:splitting_idx],test_y_full[:splitting_idx]
test_x, test_y = test_x_full[splitting_idx:],test_y_full[splitting_idx:]

In [20]:
print("Train shapes (x, y):", train_x.shape, train_y.shape)
print("Validation shapes (x, y):", val_x.shape, val_y.shape)
print("Test shapes (x, y):", test_x.shape, test_y.shape)


Train shapes (x, y): (2936, 4096) (2936, 5)
Validation shapes (x, y): (367, 4096) (367, 5)
Test shapes (x, y): (367, 4096) (367, 5)

If you did it right, you should see these sizes for the training sets:

Train shapes (x, y): (2936, 4096) (2936, 5)
Validation shapes (x, y): (367, 4096) (367, 5)
Test shapes (x, y): (367, 4096) (367, 5)

Classifier layers

Once you have the convolutional codes, you just need to build a classfier from some fully connected layers. You use the codes as the inputs and the image labels as targets. Otherwise the classifier is a typical neural network.

Exercise: With the codes and labels loaded, build the classifier. Consider the codes as your inputs, each of them are 4096D vectors. You'll want to use a hidden layer and an output layer as your classifier. Remember that the output layer needs to have one unit for each class and a softmax activation function. Use the cross entropy to calculate the cost.


In [27]:
inputs_ = tf.placeholder(tf.float32, shape=[None, codes.shape[1]])
labels_ = tf.placeholder(tf.int64, shape=[None, labels_vecs.shape[1]])

# TODO: Classifier layers and operations
nn = tf.contrib.layers.fully_connected(inputs_, 512)
logits =tf.contrib.layers.fully_connected(nn, labels_vecs.shape[1] , activation_fn = None)# output layer logits
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels_)) # cross entropy loss

optimizer = tf.train.AdamOptimizer().minimize(cost) # training optimizer

# Operations for validation/test accuracy
predicted = tf.nn.softmax(logits)
correct_pred = tf.equal(tf.argmax(predicted, 1), tf.argmax(labels_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

Batches!

Here is just a simple way to do batches. I've written it so that it includes all the data. Sometimes you'll throw out some data at the end to make sure you have full batches. Here I just extend the last batch to include the remaining data.


In [28]:
def get_batches(x, y, n_batches=10):
    """ Return a generator that yields batches from arrays x and y. """
    batch_size = len(x)//n_batches
    
    for ii in range(0, n_batches*batch_size, batch_size):
        # If we're not on the last batch, grab data with size batch_size
        if ii != (n_batches-1)*batch_size:
            X, Y = x[ii: ii+batch_size], y[ii: ii+batch_size] 
        # On the last batch, grab the rest of the data
        else:
            X, Y = x[ii:], y[ii:]
        # I love generators
        yield X, Y

Training

Here, we'll train the network.

Exercise: So far we've been providing the training code for you. Here, I'm going to give you a bit more of a challenge and have you write the code to train the network. Of course, you'll be able to see my solution if you need help. Use the get_batches function I wrote before to get your batches like for x, y in get_batches(train_x, train_y). Or write your own!


In [38]:
saver = tf.train.Saver()
epochs = 50
batch_size = 10
iteration=0

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(epochs):
        for batch_features, batch_labels in get_batches(train_x, train_y, batch_size):
            sess.run(optimizer, feed_dict={
                inputs_: batch_features,
                labels_: batch_labels})
            loss= sess.run(cost, feed_dict={
                inputs_: batch_features,
                labels_: batch_labels})
            print("Epoch: {}/{}".format(epoch+1, epochs),
                  "Iteration: {}".format(iteration),
                  "Training loss: {:.5f}".format(loss))
            iteration += 1
            
            if iteration % 5 == 0:
                feed = {inputs_: val_x,
                        labels_: val_y}
                val_acc = sess.run(accuracy, feed_dict=feed)
                print("Epoch: {}/{}".format(epoch, epochs),
                      "Iteration: {}".format(iteration),
                      "Validation Acc: {:.4f}".format(val_acc))
    # TODO: Your training code here
    saver.save(sess, "checkpoints/flowers.ckpt")


Epoch: 1/50 Iteration: 0 Training loss: 27.82333
Epoch: 1/50 Iteration: 1 Training loss: 16.84016
Epoch: 1/50 Iteration: 2 Training loss: 6.27603
Epoch: 1/50 Iteration: 3 Training loss: 3.10037
Epoch: 1/50 Iteration: 4 Training loss: 5.68972
Epoch: 0/50 Iteration: 5 Validation Acc: 0.5668
Epoch: 1/50 Iteration: 5 Training loss: 4.77329
Epoch: 1/50 Iteration: 6 Training loss: 3.84696
Epoch: 1/50 Iteration: 7 Training loss: 2.24617
Epoch: 1/50 Iteration: 8 Training loss: 2.13020
Epoch: 1/50 Iteration: 9 Training loss: 1.33031
Epoch: 0/50 Iteration: 10 Validation Acc: 0.8038
Epoch: 2/50 Iteration: 10 Training loss: 1.44731
Epoch: 2/50 Iteration: 11 Training loss: 0.80523
Epoch: 2/50 Iteration: 12 Training loss: 0.72929
Epoch: 2/50 Iteration: 13 Training loss: 0.72601
Epoch: 2/50 Iteration: 14 Training loss: 0.69458
Epoch: 1/50 Iteration: 15 Validation Acc: 0.8338
Epoch: 2/50 Iteration: 15 Training loss: 0.82053
Epoch: 2/50 Iteration: 16 Training loss: 0.91136
Epoch: 2/50 Iteration: 17 Training loss: 0.57511
Epoch: 2/50 Iteration: 18 Training loss: 0.41904
Epoch: 2/50 Iteration: 19 Training loss: 0.32189
Epoch: 1/50 Iteration: 20 Validation Acc: 0.8828
Epoch: 3/50 Iteration: 20 Training loss: 0.25706
Epoch: 3/50 Iteration: 21 Training loss: 0.22195
Epoch: 3/50 Iteration: 22 Training loss: 0.35614
Epoch: 3/50 Iteration: 23 Training loss: 0.37851
Epoch: 3/50 Iteration: 24 Training loss: 0.31815
Epoch: 2/50 Iteration: 25 Validation Acc: 0.8883
Epoch: 3/50 Iteration: 25 Training loss: 0.25447
Epoch: 3/50 Iteration: 26 Training loss: 0.32284
Epoch: 3/50 Iteration: 27 Training loss: 0.19990
Epoch: 3/50 Iteration: 28 Training loss: 0.17327
Epoch: 3/50 Iteration: 29 Training loss: 0.16726
Epoch: 2/50 Iteration: 30 Validation Acc: 0.8828
Epoch: 4/50 Iteration: 30 Training loss: 0.15012
Epoch: 4/50 Iteration: 31 Training loss: 0.15625
Epoch: 4/50 Iteration: 32 Training loss: 0.17592
Epoch: 4/50 Iteration: 33 Training loss: 0.19196
Epoch: 4/50 Iteration: 34 Training loss: 0.12224
Epoch: 3/50 Iteration: 35 Validation Acc: 0.8937
Epoch: 4/50 Iteration: 35 Training loss: 0.11626
Epoch: 4/50 Iteration: 36 Training loss: 0.22343
Epoch: 4/50 Iteration: 37 Training loss: 0.10562
Epoch: 4/50 Iteration: 38 Training loss: 0.10609
Epoch: 4/50 Iteration: 39 Training loss: 0.10217
Epoch: 3/50 Iteration: 40 Validation Acc: 0.9183
Epoch: 5/50 Iteration: 40 Training loss: 0.08004
Epoch: 5/50 Iteration: 41 Training loss: 0.06746
Epoch: 5/50 Iteration: 42 Training loss: 0.10276
Epoch: 5/50 Iteration: 43 Training loss: 0.10174
Epoch: 5/50 Iteration: 44 Training loss: 0.10115
Epoch: 4/50 Iteration: 45 Validation Acc: 0.9237
Epoch: 5/50 Iteration: 45 Training loss: 0.06639
Epoch: 5/50 Iteration: 46 Training loss: 0.12790
Epoch: 5/50 Iteration: 47 Training loss: 0.07151
Epoch: 5/50 Iteration: 48 Training loss: 0.07533
Epoch: 5/50 Iteration: 49 Training loss: 0.05937
Epoch: 4/50 Iteration: 50 Validation Acc: 0.9264
Epoch: 6/50 Iteration: 50 Training loss: 0.05367
Epoch: 6/50 Iteration: 51 Training loss: 0.04614
Epoch: 6/50 Iteration: 52 Training loss: 0.05897
Epoch: 6/50 Iteration: 53 Training loss: 0.07356
Epoch: 6/50 Iteration: 54 Training loss: 0.05051
Epoch: 5/50 Iteration: 55 Validation Acc: 0.9210
Epoch: 6/50 Iteration: 55 Training loss: 0.03812
Epoch: 6/50 Iteration: 56 Training loss: 0.09738
Epoch: 6/50 Iteration: 57 Training loss: 0.04072
Epoch: 6/50 Iteration: 58 Training loss: 0.04629
Epoch: 6/50 Iteration: 59 Training loss: 0.03917
Epoch: 5/50 Iteration: 60 Validation Acc: 0.9346
Epoch: 7/50 Iteration: 60 Training loss: 0.03451
Epoch: 7/50 Iteration: 61 Training loss: 0.02517
Epoch: 7/50 Iteration: 62 Training loss: 0.03319
Epoch: 7/50 Iteration: 63 Training loss: 0.04691
Epoch: 7/50 Iteration: 64 Training loss: 0.03772
Epoch: 6/50 Iteration: 65 Validation Acc: 0.9346
Epoch: 7/50 Iteration: 65 Training loss: 0.02575
Epoch: 7/50 Iteration: 66 Training loss: 0.06997
Epoch: 7/50 Iteration: 67 Training loss: 0.02840
Epoch: 7/50 Iteration: 68 Training loss: 0.03057
Epoch: 7/50 Iteration: 69 Training loss: 0.02633
Epoch: 6/50 Iteration: 70 Validation Acc: 0.9346
Epoch: 8/50 Iteration: 70 Training loss: 0.02293
Epoch: 8/50 Iteration: 71 Training loss: 0.01813
Epoch: 8/50 Iteration: 72 Training loss: 0.02109
Epoch: 8/50 Iteration: 73 Training loss: 0.03140
Epoch: 8/50 Iteration: 74 Training loss: 0.02210
Epoch: 7/50 Iteration: 75 Validation Acc: 0.9319
Epoch: 8/50 Iteration: 75 Training loss: 0.01822
Epoch: 8/50 Iteration: 76 Training loss: 0.04994
Epoch: 8/50 Iteration: 77 Training loss: 0.01944
Epoch: 8/50 Iteration: 78 Training loss: 0.02230
Epoch: 8/50 Iteration: 79 Training loss: 0.01950
Epoch: 7/50 Iteration: 80 Validation Acc: 0.9319
Epoch: 9/50 Iteration: 80 Training loss: 0.01648
Epoch: 9/50 Iteration: 81 Training loss: 0.01218
Epoch: 9/50 Iteration: 82 Training loss: 0.01536
Epoch: 9/50 Iteration: 83 Training loss: 0.02113
Epoch: 9/50 Iteration: 84 Training loss: 0.01531
Epoch: 8/50 Iteration: 85 Validation Acc: 0.9319
Epoch: 9/50 Iteration: 85 Training loss: 0.01376
Epoch: 9/50 Iteration: 86 Training loss: 0.03355
Epoch: 9/50 Iteration: 87 Training loss: 0.01490
Epoch: 9/50 Iteration: 88 Training loss: 0.01730
Epoch: 9/50 Iteration: 89 Training loss: 0.01497
Epoch: 8/50 Iteration: 90 Validation Acc: 0.9319
Epoch: 10/50 Iteration: 90 Training loss: 0.01186
Epoch: 10/50 Iteration: 91 Training loss: 0.00927
Epoch: 10/50 Iteration: 92 Training loss: 0.01167
Epoch: 10/50 Iteration: 93 Training loss: 0.01553
Epoch: 10/50 Iteration: 94 Training loss: 0.01162
Epoch: 9/50 Iteration: 95 Validation Acc: 0.9319
Epoch: 10/50 Iteration: 95 Training loss: 0.01039
Epoch: 10/50 Iteration: 96 Training loss: 0.02484
Epoch: 10/50 Iteration: 97 Training loss: 0.01165
Epoch: 10/50 Iteration: 98 Training loss: 0.01385
Epoch: 10/50 Iteration: 99 Training loss: 0.01187
Epoch: 9/50 Iteration: 100 Validation Acc: 0.9319
Epoch: 11/50 Iteration: 100 Training loss: 0.00905
Epoch: 11/50 Iteration: 101 Training loss: 0.00762
Epoch: 11/50 Iteration: 102 Training loss: 0.00961
Epoch: 11/50 Iteration: 103 Training loss: 0.01153
Epoch: 11/50 Iteration: 104 Training loss: 0.00934
Epoch: 10/50 Iteration: 105 Validation Acc: 0.9346
Epoch: 11/50 Iteration: 105 Training loss: 0.00827
Epoch: 11/50 Iteration: 106 Training loss: 0.01843
Epoch: 11/50 Iteration: 107 Training loss: 0.00969
Epoch: 11/50 Iteration: 108 Training loss: 0.01145
Epoch: 11/50 Iteration: 109 Training loss: 0.00951
Epoch: 10/50 Iteration: 110 Validation Acc: 0.9346
Epoch: 12/50 Iteration: 110 Training loss: 0.00748
Epoch: 12/50 Iteration: 111 Training loss: 0.00609
Epoch: 12/50 Iteration: 112 Training loss: 0.00770
Epoch: 12/50 Iteration: 113 Training loss: 0.00921
Epoch: 12/50 Iteration: 114 Training loss: 0.00754
Epoch: 11/50 Iteration: 115 Validation Acc: 0.9346
Epoch: 12/50 Iteration: 115 Training loss: 0.00672
Epoch: 12/50 Iteration: 116 Training loss: 0.01499
Epoch: 12/50 Iteration: 117 Training loss: 0.00789
Epoch: 12/50 Iteration: 118 Training loss: 0.00961
Epoch: 12/50 Iteration: 119 Training loss: 0.00796
Epoch: 11/50 Iteration: 120 Validation Acc: 0.9346
Epoch: 13/50 Iteration: 120 Training loss: 0.00617
Epoch: 13/50 Iteration: 121 Training loss: 0.00524
Epoch: 13/50 Iteration: 122 Training loss: 0.00648
Epoch: 13/50 Iteration: 123 Training loss: 0.00742
Epoch: 13/50 Iteration: 124 Training loss: 0.00624
Epoch: 12/50 Iteration: 125 Validation Acc: 0.9346
Epoch: 13/50 Iteration: 125 Training loss: 0.00567
Epoch: 13/50 Iteration: 126 Training loss: 0.01210
Epoch: 13/50 Iteration: 127 Training loss: 0.00664
Epoch: 13/50 Iteration: 128 Training loss: 0.00797
Epoch: 13/50 Iteration: 129 Training loss: 0.00666
Epoch: 12/50 Iteration: 130 Validation Acc: 0.9346
Epoch: 14/50 Iteration: 130 Training loss: 0.00529
Epoch: 14/50 Iteration: 131 Training loss: 0.00442
Epoch: 14/50 Iteration: 132 Training loss: 0.00548
Epoch: 14/50 Iteration: 133 Training loss: 0.00616
Epoch: 14/50 Iteration: 134 Training loss: 0.00551
Epoch: 13/50 Iteration: 135 Validation Acc: 0.9346
Epoch: 14/50 Iteration: 135 Training loss: 0.00475
Epoch: 14/50 Iteration: 136 Training loss: 0.01010
Epoch: 14/50 Iteration: 137 Training loss: 0.00576
Epoch: 14/50 Iteration: 138 Training loss: 0.00681
Epoch: 14/50 Iteration: 139 Training loss: 0.00577
Epoch: 13/50 Iteration: 140 Validation Acc: 0.9373
Epoch: 15/50 Iteration: 140 Training loss: 0.00453
Epoch: 15/50 Iteration: 141 Training loss: 0.00386
Epoch: 15/50 Iteration: 142 Training loss: 0.00479
Epoch: 15/50 Iteration: 143 Training loss: 0.00522
Epoch: 15/50 Iteration: 144 Training loss: 0.00468
Epoch: 14/50 Iteration: 145 Validation Acc: 0.9373
Epoch: 15/50 Iteration: 145 Training loss: 0.00411
Epoch: 15/50 Iteration: 146 Training loss: 0.00860
Epoch: 15/50 Iteration: 147 Training loss: 0.00492
Epoch: 15/50 Iteration: 148 Training loss: 0.00598
Epoch: 15/50 Iteration: 149 Training loss: 0.00500
Epoch: 14/50 Iteration: 150 Validation Acc: 0.9373
Epoch: 16/50 Iteration: 150 Training loss: 0.00399
Epoch: 16/50 Iteration: 151 Training loss: 0.00336
Epoch: 16/50 Iteration: 152 Training loss: 0.00417
Epoch: 16/50 Iteration: 153 Training loss: 0.00453
Epoch: 16/50 Iteration: 154 Training loss: 0.00414
Epoch: 15/50 Iteration: 155 Validation Acc: 0.9346
Epoch: 16/50 Iteration: 155 Training loss: 0.00356
Epoch: 16/50 Iteration: 156 Training loss: 0.00738
Epoch: 16/50 Iteration: 157 Training loss: 0.00434
Epoch: 16/50 Iteration: 158 Training loss: 0.00528
Epoch: 16/50 Iteration: 159 Training loss: 0.00445
Epoch: 15/50 Iteration: 160 Validation Acc: 0.9346
Epoch: 17/50 Iteration: 160 Training loss: 0.00346
Epoch: 17/50 Iteration: 161 Training loss: 0.00297
Epoch: 17/50 Iteration: 162 Training loss: 0.00371
Epoch: 17/50 Iteration: 163 Training loss: 0.00393
Epoch: 17/50 Iteration: 164 Training loss: 0.00370
Epoch: 16/50 Iteration: 165 Validation Acc: 0.9346
Epoch: 17/50 Iteration: 165 Training loss: 0.00313
Epoch: 17/50 Iteration: 166 Training loss: 0.00644
Epoch: 17/50 Iteration: 167 Training loss: 0.00385
Epoch: 17/50 Iteration: 168 Training loss: 0.00469
Epoch: 17/50 Iteration: 169 Training loss: 0.00398
Epoch: 16/50 Iteration: 170 Validation Acc: 0.9346
Epoch: 18/50 Iteration: 170 Training loss: 0.00309
Epoch: 18/50 Iteration: 171 Training loss: 0.00264
Epoch: 18/50 Iteration: 172 Training loss: 0.00335
Epoch: 18/50 Iteration: 173 Training loss: 0.00350
Epoch: 18/50 Iteration: 174 Training loss: 0.00335
Epoch: 17/50 Iteration: 175 Validation Acc: 0.9346
Epoch: 18/50 Iteration: 175 Training loss: 0.00279
Epoch: 18/50 Iteration: 176 Training loss: 0.00567
Epoch: 18/50 Iteration: 177 Training loss: 0.00342
Epoch: 18/50 Iteration: 178 Training loss: 0.00419
Epoch: 18/50 Iteration: 179 Training loss: 0.00358
Epoch: 17/50 Iteration: 180 Validation Acc: 0.9319
Epoch: 19/50 Iteration: 180 Training loss: 0.00275
Epoch: 19/50 Iteration: 181 Training loss: 0.00237
Epoch: 19/50 Iteration: 182 Training loss: 0.00299
Epoch: 19/50 Iteration: 183 Training loss: 0.00312
Epoch: 19/50 Iteration: 184 Training loss: 0.00298
Epoch: 18/50 Iteration: 185 Validation Acc: 0.9346
Epoch: 19/50 Iteration: 185 Training loss: 0.00253
Epoch: 19/50 Iteration: 186 Training loss: 0.00503
Epoch: 19/50 Iteration: 187 Training loss: 0.00307
Epoch: 19/50 Iteration: 188 Training loss: 0.00372
Epoch: 19/50 Iteration: 189 Training loss: 0.00323
Epoch: 18/50 Iteration: 190 Validation Acc: 0.9346
Epoch: 20/50 Iteration: 190 Training loss: 0.00247
Epoch: 20/50 Iteration: 191 Training loss: 0.00215
Epoch: 20/50 Iteration: 192 Training loss: 0.00272
Epoch: 20/50 Iteration: 193 Training loss: 0.00281
Epoch: 20/50 Iteration: 194 Training loss: 0.00271
Epoch: 19/50 Iteration: 195 Validation Acc: 0.9346
Epoch: 20/50 Iteration: 195 Training loss: 0.00226
Epoch: 20/50 Iteration: 196 Training loss: 0.00445
Epoch: 20/50 Iteration: 197 Training loss: 0.00278
Epoch: 20/50 Iteration: 198 Training loss: 0.00333
Epoch: 20/50 Iteration: 199 Training loss: 0.00292
Epoch: 19/50 Iteration: 200 Validation Acc: 0.9346
Epoch: 21/50 Iteration: 200 Training loss: 0.00224
Epoch: 21/50 Iteration: 201 Training loss: 0.00193
Epoch: 21/50 Iteration: 202 Training loss: 0.00247
Epoch: 21/50 Iteration: 203 Training loss: 0.00255
Epoch: 21/50 Iteration: 204 Training loss: 0.00245
Epoch: 20/50 Iteration: 205 Validation Acc: 0.9373
Epoch: 21/50 Iteration: 205 Training loss: 0.00201
Epoch: 21/50 Iteration: 206 Training loss: 0.00396
Epoch: 21/50 Iteration: 207 Training loss: 0.00253
Epoch: 21/50 Iteration: 208 Training loss: 0.00303
Epoch: 21/50 Iteration: 209 Training loss: 0.00268
Epoch: 20/50 Iteration: 210 Validation Acc: 0.9346
Epoch: 22/50 Iteration: 210 Training loss: 0.00203
Epoch: 22/50 Iteration: 211 Training loss: 0.00177
Epoch: 22/50 Iteration: 212 Training loss: 0.00231
Epoch: 22/50 Iteration: 213 Training loss: 0.00233
Epoch: 22/50 Iteration: 214 Training loss: 0.00227
Epoch: 21/50 Iteration: 215 Validation Acc: 0.9346
Epoch: 22/50 Iteration: 215 Training loss: 0.00188
Epoch: 22/50 Iteration: 216 Training loss: 0.00358
Epoch: 22/50 Iteration: 217 Training loss: 0.00229
Epoch: 22/50 Iteration: 218 Training loss: 0.00272
Epoch: 22/50 Iteration: 219 Training loss: 0.00245
Epoch: 21/50 Iteration: 220 Validation Acc: 0.9346
Epoch: 23/50 Iteration: 220 Training loss: 0.00183
Epoch: 23/50 Iteration: 221 Training loss: 0.00162
Epoch: 23/50 Iteration: 222 Training loss: 0.00206
Epoch: 23/50 Iteration: 223 Training loss: 0.00210
Epoch: 23/50 Iteration: 224 Training loss: 0.00206
Epoch: 22/50 Iteration: 225 Validation Acc: 0.9346
Epoch: 23/50 Iteration: 225 Training loss: 0.00167
Epoch: 23/50 Iteration: 226 Training loss: 0.00322
Epoch: 23/50 Iteration: 227 Training loss: 0.00209
Epoch: 23/50 Iteration: 228 Training loss: 0.00249
Epoch: 23/50 Iteration: 229 Training loss: 0.00225
Epoch: 22/50 Iteration: 230 Validation Acc: 0.9373
Epoch: 24/50 Iteration: 230 Training loss: 0.00167
Epoch: 24/50 Iteration: 231 Training loss: 0.00148
Epoch: 24/50 Iteration: 232 Training loss: 0.00193
Epoch: 24/50 Iteration: 233 Training loss: 0.00193
Epoch: 24/50 Iteration: 234 Training loss: 0.00188
Epoch: 23/50 Iteration: 235 Validation Acc: 0.9373
Epoch: 24/50 Iteration: 235 Training loss: 0.00153
Epoch: 24/50 Iteration: 236 Training loss: 0.00290
Epoch: 24/50 Iteration: 237 Training loss: 0.00187
Epoch: 24/50 Iteration: 238 Training loss: 0.00231
Epoch: 24/50 Iteration: 239 Training loss: 0.00208
Epoch: 23/50 Iteration: 240 Validation Acc: 0.9346
Epoch: 25/50 Iteration: 240 Training loss: 0.00153
Epoch: 25/50 Iteration: 241 Training loss: 0.00136
Epoch: 25/50 Iteration: 242 Training loss: 0.00177
Epoch: 25/50 Iteration: 243 Training loss: 0.00177
Epoch: 25/50 Iteration: 244 Training loss: 0.00172
Epoch: 24/50 Iteration: 245 Validation Acc: 0.9373
Epoch: 25/50 Iteration: 245 Training loss: 0.00141
Epoch: 25/50 Iteration: 246 Training loss: 0.00262
Epoch: 25/50 Iteration: 247 Training loss: 0.00167
Epoch: 25/50 Iteration: 248 Training loss: 0.00211
Epoch: 25/50 Iteration: 249 Training loss: 0.00191
Epoch: 24/50 Iteration: 250 Validation Acc: 0.9346
Epoch: 26/50 Iteration: 250 Training loss: 0.00138
Epoch: 26/50 Iteration: 251 Training loss: 0.00127
Epoch: 26/50 Iteration: 252 Training loss: 0.00161
Epoch: 26/50 Iteration: 253 Training loss: 0.00162
Epoch: 26/50 Iteration: 254 Training loss: 0.00156
Epoch: 25/50 Iteration: 255 Validation Acc: 0.9373
Epoch: 26/50 Iteration: 255 Training loss: 0.00130
Epoch: 26/50 Iteration: 256 Training loss: 0.00242
Epoch: 26/50 Iteration: 257 Training loss: 0.00154
Epoch: 26/50 Iteration: 258 Training loss: 0.00197
Epoch: 26/50 Iteration: 259 Training loss: 0.00178
Epoch: 25/50 Iteration: 260 Validation Acc: 0.9373
Epoch: 27/50 Iteration: 260 Training loss: 0.00128
Epoch: 27/50 Iteration: 261 Training loss: 0.00116
Epoch: 27/50 Iteration: 262 Training loss: 0.00153
Epoch: 27/50 Iteration: 263 Training loss: 0.00151
Epoch: 27/50 Iteration: 264 Training loss: 0.00144
Epoch: 26/50 Iteration: 265 Validation Acc: 0.9346
Epoch: 27/50 Iteration: 265 Training loss: 0.00118
Epoch: 27/50 Iteration: 266 Training loss: 0.00221
Epoch: 27/50 Iteration: 267 Training loss: 0.00140
Epoch: 27/50 Iteration: 268 Training loss: 0.00182
Epoch: 27/50 Iteration: 269 Training loss: 0.00164
Epoch: 26/50 Iteration: 270 Validation Acc: 0.9346
Epoch: 28/50 Iteration: 270 Training loss: 0.00118
Epoch: 28/50 Iteration: 271 Training loss: 0.00108
Epoch: 28/50 Iteration: 272 Training loss: 0.00142
Epoch: 28/50 Iteration: 273 Training loss: 0.00139
Epoch: 28/50 Iteration: 274 Training loss: 0.00135
Epoch: 27/50 Iteration: 275 Validation Acc: 0.9373
Epoch: 28/50 Iteration: 275 Training loss: 0.00111
Epoch: 28/50 Iteration: 276 Training loss: 0.00202
Epoch: 28/50 Iteration: 277 Training loss: 0.00127
Epoch: 28/50 Iteration: 278 Training loss: 0.00168
Epoch: 28/50 Iteration: 279 Training loss: 0.00154
Epoch: 27/50 Iteration: 280 Validation Acc: 0.9346
Epoch: 29/50 Iteration: 280 Training loss: 0.00109
Epoch: 29/50 Iteration: 281 Training loss: 0.00100
Epoch: 29/50 Iteration: 282 Training loss: 0.00129
Epoch: 29/50 Iteration: 283 Training loss: 0.00130
Epoch: 29/50 Iteration: 284 Training loss: 0.00124
Epoch: 28/50 Iteration: 285 Validation Acc: 0.9373
Epoch: 29/50 Iteration: 285 Training loss: 0.00102
Epoch: 29/50 Iteration: 286 Training loss: 0.00186
Epoch: 29/50 Iteration: 287 Training loss: 0.00119
Epoch: 29/50 Iteration: 288 Training loss: 0.00156
Epoch: 29/50 Iteration: 289 Training loss: 0.00142
Epoch: 28/50 Iteration: 290 Validation Acc: 0.9373
Epoch: 30/50 Iteration: 290 Training loss: 0.00101
Epoch: 30/50 Iteration: 291 Training loss: 0.00093
Epoch: 30/50 Iteration: 292 Training loss: 0.00120
Epoch: 30/50 Iteration: 293 Training loss: 0.00122
Epoch: 30/50 Iteration: 294 Training loss: 0.00114
Epoch: 29/50 Iteration: 295 Validation Acc: 0.9373
Epoch: 30/50 Iteration: 295 Training loss: 0.00095
Epoch: 30/50 Iteration: 296 Training loss: 0.00172
Epoch: 30/50 Iteration: 297 Training loss: 0.00110
Epoch: 30/50 Iteration: 298 Training loss: 0.00146
Epoch: 30/50 Iteration: 299 Training loss: 0.00132
Epoch: 29/50 Iteration: 300 Validation Acc: 0.9373
Epoch: 31/50 Iteration: 300 Training loss: 0.00095
Epoch: 31/50 Iteration: 301 Training loss: 0.00086
Epoch: 31/50 Iteration: 302 Training loss: 0.00112
Epoch: 31/50 Iteration: 303 Training loss: 0.00113
Epoch: 31/50 Iteration: 304 Training loss: 0.00107
Epoch: 30/50 Iteration: 305 Validation Acc: 0.9373
Epoch: 31/50 Iteration: 305 Training loss: 0.00088
Epoch: 31/50 Iteration: 306 Training loss: 0.00160
Epoch: 31/50 Iteration: 307 Training loss: 0.00102
Epoch: 31/50 Iteration: 308 Training loss: 0.00136
Epoch: 31/50 Iteration: 309 Training loss: 0.00124
Epoch: 30/50 Iteration: 310 Validation Acc: 0.9373
Epoch: 32/50 Iteration: 310 Training loss: 0.00089
Epoch: 32/50 Iteration: 311 Training loss: 0.00081
Epoch: 32/50 Iteration: 312 Training loss: 0.00105
Epoch: 32/50 Iteration: 313 Training loss: 0.00106
Epoch: 32/50 Iteration: 314 Training loss: 0.00101
Epoch: 31/50 Iteration: 315 Validation Acc: 0.9373
Epoch: 32/50 Iteration: 315 Training loss: 0.00082
Epoch: 32/50 Iteration: 316 Training loss: 0.00150
Epoch: 32/50 Iteration: 317 Training loss: 0.00094
Epoch: 32/50 Iteration: 318 Training loss: 0.00129
Epoch: 32/50 Iteration: 319 Training loss: 0.00116
Epoch: 31/50 Iteration: 320 Validation Acc: 0.9346
Epoch: 33/50 Iteration: 320 Training loss: 0.00084
Epoch: 33/50 Iteration: 321 Training loss: 0.00077
Epoch: 33/50 Iteration: 322 Training loss: 0.00098
Epoch: 33/50 Iteration: 323 Training loss: 0.00100
Epoch: 33/50 Iteration: 324 Training loss: 0.00095
Epoch: 32/50 Iteration: 325 Validation Acc: 0.9373
Epoch: 33/50 Iteration: 325 Training loss: 0.00077
Epoch: 33/50 Iteration: 326 Training loss: 0.00141
Epoch: 33/50 Iteration: 327 Training loss: 0.00090
Epoch: 33/50 Iteration: 328 Training loss: 0.00121
Epoch: 33/50 Iteration: 329 Training loss: 0.00109
Epoch: 32/50 Iteration: 330 Validation Acc: 0.9373
Epoch: 34/50 Iteration: 330 Training loss: 0.00078
Epoch: 34/50 Iteration: 331 Training loss: 0.00072
Epoch: 34/50 Iteration: 332 Training loss: 0.00093
Epoch: 34/50 Iteration: 333 Training loss: 0.00094
Epoch: 34/50 Iteration: 334 Training loss: 0.00090
Epoch: 33/50 Iteration: 335 Validation Acc: 0.9373
Epoch: 34/50 Iteration: 335 Training loss: 0.00072
Epoch: 34/50 Iteration: 336 Training loss: 0.00132
Epoch: 34/50 Iteration: 337 Training loss: 0.00085
Epoch: 34/50 Iteration: 338 Training loss: 0.00115
Epoch: 34/50 Iteration: 339 Training loss: 0.00103
Epoch: 33/50 Iteration: 340 Validation Acc: 0.9373
Epoch: 35/50 Iteration: 340 Training loss: 0.00074
Epoch: 35/50 Iteration: 341 Training loss: 0.00067
Epoch: 35/50 Iteration: 342 Training loss: 0.00088
Epoch: 35/50 Iteration: 343 Training loss: 0.00089
Epoch: 35/50 Iteration: 344 Training loss: 0.00084
Epoch: 34/50 Iteration: 345 Validation Acc: 0.9373
Epoch: 35/50 Iteration: 345 Training loss: 0.00068
Epoch: 35/50 Iteration: 346 Training loss: 0.00124
Epoch: 35/50 Iteration: 347 Training loss: 0.00080
Epoch: 35/50 Iteration: 348 Training loss: 0.00109
Epoch: 35/50 Iteration: 349 Training loss: 0.00098
Epoch: 34/50 Iteration: 350 Validation Acc: 0.9373
Epoch: 36/50 Iteration: 350 Training loss: 0.00070
Epoch: 36/50 Iteration: 351 Training loss: 0.00064
Epoch: 36/50 Iteration: 352 Training loss: 0.00085
Epoch: 36/50 Iteration: 353 Training loss: 0.00084
Epoch: 36/50 Iteration: 354 Training loss: 0.00080
Epoch: 35/50 Iteration: 355 Validation Acc: 0.9373
Epoch: 36/50 Iteration: 355 Training loss: 0.00063
Epoch: 36/50 Iteration: 356 Training loss: 0.00113
Epoch: 36/50 Iteration: 357 Training loss: 0.00077
Epoch: 36/50 Iteration: 358 Training loss: 0.00104
Epoch: 36/50 Iteration: 359 Training loss: 0.00092
Epoch: 35/50 Iteration: 360 Validation Acc: 0.9373
Epoch: 37/50 Iteration: 360 Training loss: 0.00065
Epoch: 37/50 Iteration: 361 Training loss: 0.00061
Epoch: 37/50 Iteration: 362 Training loss: 0.00081
Epoch: 37/50 Iteration: 363 Training loss: 0.00080
Epoch: 37/50 Iteration: 364 Training loss: 0.00076
Epoch: 36/50 Iteration: 365 Validation Acc: 0.9373
Epoch: 37/50 Iteration: 365 Training loss: 0.00060
Epoch: 37/50 Iteration: 366 Training loss: 0.00106
Epoch: 37/50 Iteration: 367 Training loss: 0.00072
Epoch: 37/50 Iteration: 368 Training loss: 0.00095
Epoch: 37/50 Iteration: 369 Training loss: 0.00087
Epoch: 36/50 Iteration: 370 Validation Acc: 0.9373
Epoch: 38/50 Iteration: 370 Training loss: 0.00062
Epoch: 38/50 Iteration: 371 Training loss: 0.00057
Epoch: 38/50 Iteration: 372 Training loss: 0.00074
Epoch: 38/50 Iteration: 373 Training loss: 0.00077
Epoch: 38/50 Iteration: 374 Training loss: 0.00072
Epoch: 37/50 Iteration: 375 Validation Acc: 0.9373
Epoch: 38/50 Iteration: 375 Training loss: 0.00058
Epoch: 38/50 Iteration: 376 Training loss: 0.00102
Epoch: 38/50 Iteration: 377 Training loss: 0.00071
Epoch: 38/50 Iteration: 378 Training loss: 0.00096
Epoch: 38/50 Iteration: 379 Training loss: 0.00085
Epoch: 37/50 Iteration: 380 Validation Acc: 0.9373
Epoch: 39/50 Iteration: 380 Training loss: 0.00061
Epoch: 39/50 Iteration: 381 Training loss: 0.00056
Epoch: 39/50 Iteration: 382 Training loss: 0.00075
Epoch: 39/50 Iteration: 383 Training loss: 0.00073
Epoch: 39/50 Iteration: 384 Training loss: 0.00068
Epoch: 38/50 Iteration: 385 Validation Acc: 0.9373
Epoch: 39/50 Iteration: 385 Training loss: 0.00054
Epoch: 39/50 Iteration: 386 Training loss: 0.00095
Epoch: 39/50 Iteration: 387 Training loss: 0.00065
Epoch: 39/50 Iteration: 388 Training loss: 0.00087
Epoch: 39/50 Iteration: 389 Training loss: 0.00079
Epoch: 38/50 Iteration: 390 Validation Acc: 0.9401
Epoch: 40/50 Iteration: 390 Training loss: 0.00057
Epoch: 40/50 Iteration: 391 Training loss: 0.00053
Epoch: 40/50 Iteration: 392 Training loss: 0.00067
Epoch: 40/50 Iteration: 393 Training loss: 0.00069
Epoch: 40/50 Iteration: 394 Training loss: 0.00064
Epoch: 39/50 Iteration: 395 Validation Acc: 0.9373
Epoch: 40/50 Iteration: 395 Training loss: 0.00051
Epoch: 40/50 Iteration: 396 Training loss: 0.00090
Epoch: 40/50 Iteration: 397 Training loss: 0.00062
Epoch: 40/50 Iteration: 398 Training loss: 0.00082
Epoch: 40/50 Iteration: 399 Training loss: 0.00075
Epoch: 39/50 Iteration: 400 Validation Acc: 0.9373
Epoch: 41/50 Iteration: 400 Training loss: 0.00053
Epoch: 41/50 Iteration: 401 Training loss: 0.00050
Epoch: 41/50 Iteration: 402 Training loss: 0.00064
Epoch: 41/50 Iteration: 403 Training loss: 0.00066
Epoch: 41/50 Iteration: 404 Training loss: 0.00061
Epoch: 40/50 Iteration: 405 Validation Acc: 0.9373
Epoch: 41/50 Iteration: 405 Training loss: 0.00048
Epoch: 41/50 Iteration: 406 Training loss: 0.00085
Epoch: 41/50 Iteration: 407 Training loss: 0.00058
Epoch: 41/50 Iteration: 408 Training loss: 0.00077
Epoch: 41/50 Iteration: 409 Training loss: 0.00072
Epoch: 40/50 Iteration: 410 Validation Acc: 0.9373
Epoch: 42/50 Iteration: 410 Training loss: 0.00050
Epoch: 42/50 Iteration: 411 Training loss: 0.00048
Epoch: 42/50 Iteration: 412 Training loss: 0.00062
Epoch: 42/50 Iteration: 413 Training loss: 0.00063
Epoch: 42/50 Iteration: 414 Training loss: 0.00057
Epoch: 41/50 Iteration: 415 Validation Acc: 0.9373
Epoch: 42/50 Iteration: 415 Training loss: 0.00045
Epoch: 42/50 Iteration: 416 Training loss: 0.00080
Epoch: 42/50 Iteration: 417 Training loss: 0.00056
Epoch: 42/50 Iteration: 418 Training loss: 0.00073
Epoch: 42/50 Iteration: 419 Training loss: 0.00068
Epoch: 41/50 Iteration: 420 Validation Acc: 0.9373
Epoch: 43/50 Iteration: 420 Training loss: 0.00048
Epoch: 43/50 Iteration: 421 Training loss: 0.00046
Epoch: 43/50 Iteration: 422 Training loss: 0.00058
Epoch: 43/50 Iteration: 423 Training loss: 0.00060
Epoch: 43/50 Iteration: 424 Training loss: 0.00055
Epoch: 42/50 Iteration: 425 Validation Acc: 0.9373
Epoch: 43/50 Iteration: 425 Training loss: 0.00043
Epoch: 43/50 Iteration: 426 Training loss: 0.00076
Epoch: 43/50 Iteration: 427 Training loss: 0.00053
Epoch: 43/50 Iteration: 428 Training loss: 0.00070
Epoch: 43/50 Iteration: 429 Training loss: 0.00065
Epoch: 42/50 Iteration: 430 Validation Acc: 0.9373
Epoch: 44/50 Iteration: 430 Training loss: 0.00045
Epoch: 44/50 Iteration: 431 Training loss: 0.00044
Epoch: 44/50 Iteration: 432 Training loss: 0.00055
Epoch: 44/50 Iteration: 433 Training loss: 0.00058
Epoch: 44/50 Iteration: 434 Training loss: 0.00052
Epoch: 43/50 Iteration: 435 Validation Acc: 0.9401
Epoch: 44/50 Iteration: 435 Training loss: 0.00041
Epoch: 44/50 Iteration: 436 Training loss: 0.00073
Epoch: 44/50 Iteration: 437 Training loss: 0.00051
Epoch: 44/50 Iteration: 438 Training loss: 0.00067
Epoch: 44/50 Iteration: 439 Training loss: 0.00063
Epoch: 43/50 Iteration: 440 Validation Acc: 0.9373
Epoch: 45/50 Iteration: 440 Training loss: 0.00044
Epoch: 45/50 Iteration: 441 Training loss: 0.00042
Epoch: 45/50 Iteration: 442 Training loss: 0.00054
Epoch: 45/50 Iteration: 443 Training loss: 0.00055
Epoch: 45/50 Iteration: 444 Training loss: 0.00050
Epoch: 44/50 Iteration: 445 Validation Acc: 0.9373
Epoch: 45/50 Iteration: 445 Training loss: 0.00039
Epoch: 45/50 Iteration: 446 Training loss: 0.00070
Epoch: 45/50 Iteration: 447 Training loss: 0.00049
Epoch: 45/50 Iteration: 448 Training loss: 0.00063
Epoch: 45/50 Iteration: 449 Training loss: 0.00059
Epoch: 44/50 Iteration: 450 Validation Acc: 0.9401
Epoch: 46/50 Iteration: 450 Training loss: 0.00042
Epoch: 46/50 Iteration: 451 Training loss: 0.00040
Epoch: 46/50 Iteration: 452 Training loss: 0.00051
Epoch: 46/50 Iteration: 453 Training loss: 0.00053
Epoch: 46/50 Iteration: 454 Training loss: 0.00048
Epoch: 45/50 Iteration: 455 Validation Acc: 0.9401
Epoch: 46/50 Iteration: 455 Training loss: 0.00038
Epoch: 46/50 Iteration: 456 Training loss: 0.00068
Epoch: 46/50 Iteration: 457 Training loss: 0.00047
Epoch: 46/50 Iteration: 458 Training loss: 0.00063
Epoch: 46/50 Iteration: 459 Training loss: 0.00058
Epoch: 45/50 Iteration: 460 Validation Acc: 0.9373
Epoch: 47/50 Iteration: 460 Training loss: 0.00041
Epoch: 47/50 Iteration: 461 Training loss: 0.00039
Epoch: 47/50 Iteration: 462 Training loss: 0.00050
Epoch: 47/50 Iteration: 463 Training loss: 0.00051
Epoch: 47/50 Iteration: 464 Training loss: 0.00046
Epoch: 46/50 Iteration: 465 Validation Acc: 0.9401
Epoch: 47/50 Iteration: 465 Training loss: 0.00036
Epoch: 47/50 Iteration: 466 Training loss: 0.00064
Epoch: 47/50 Iteration: 467 Training loss: 0.00045
Epoch: 47/50 Iteration: 468 Training loss: 0.00058
Epoch: 47/50 Iteration: 469 Training loss: 0.00053
Epoch: 46/50 Iteration: 470 Validation Acc: 0.9401
Epoch: 48/50 Iteration: 470 Training loss: 0.00039
Epoch: 48/50 Iteration: 471 Training loss: 0.00037
Epoch: 48/50 Iteration: 472 Training loss: 0.00046
Epoch: 48/50 Iteration: 473 Training loss: 0.00049
Epoch: 48/50 Iteration: 474 Training loss: 0.00044
Epoch: 47/50 Iteration: 475 Validation Acc: 0.9401
Epoch: 48/50 Iteration: 475 Training loss: 0.00035
Epoch: 48/50 Iteration: 476 Training loss: 0.00061
Epoch: 48/50 Iteration: 477 Training loss: 0.00043
Epoch: 48/50 Iteration: 478 Training loss: 0.00056
Epoch: 48/50 Iteration: 479 Training loss: 0.00051
Epoch: 47/50 Iteration: 480 Validation Acc: 0.9373
Epoch: 49/50 Iteration: 480 Training loss: 0.00036
Epoch: 49/50 Iteration: 481 Training loss: 0.00036
Epoch: 49/50 Iteration: 482 Training loss: 0.00045
Epoch: 49/50 Iteration: 483 Training loss: 0.00048
Epoch: 49/50 Iteration: 484 Training loss: 0.00042
Epoch: 48/50 Iteration: 485 Validation Acc: 0.9401
Epoch: 49/50 Iteration: 485 Training loss: 0.00033
Epoch: 49/50 Iteration: 486 Training loss: 0.00058
Epoch: 49/50 Iteration: 487 Training loss: 0.00041
Epoch: 49/50 Iteration: 488 Training loss: 0.00053
Epoch: 49/50 Iteration: 489 Training loss: 0.00049
Epoch: 48/50 Iteration: 490 Validation Acc: 0.9373
Epoch: 50/50 Iteration: 490 Training loss: 0.00035
Epoch: 50/50 Iteration: 491 Training loss: 0.00035
Epoch: 50/50 Iteration: 492 Training loss: 0.00044
Epoch: 50/50 Iteration: 493 Training loss: 0.00046
Epoch: 50/50 Iteration: 494 Training loss: 0.00040
Epoch: 49/50 Iteration: 495 Validation Acc: 0.9401
Epoch: 50/50 Iteration: 495 Training loss: 0.00032
Epoch: 50/50 Iteration: 496 Training loss: 0.00056
Epoch: 50/50 Iteration: 497 Training loss: 0.00040
Epoch: 50/50 Iteration: 498 Training loss: 0.00050
Epoch: 50/50 Iteration: 499 Training loss: 0.00047
Epoch: 49/50 Iteration: 500 Validation Acc: 0.9401

Testing

Below you see the test accuracy. You can also see the predictions returned for images.


In [39]:
with tf.Session() as sess:
    saver.restore(sess, tf.train.latest_checkpoint('checkpoints'))
    
    feed = {inputs_: test_x,
            labels_: test_y}
    test_acc = sess.run(accuracy, feed_dict=feed)
    print("Test accuracy: {:.4f}".format(test_acc))


Test accuracy: 0.9401

In [40]:
%matplotlib inline

import matplotlib.pyplot as plt
from scipy.ndimage import imread

Below, feel free to choose images and see how the trained classifier predicts the flowers in them.


In [41]:
test_img_path = 'flower_photos/roses/10894627425_ec76bbc757_n.jpg'
test_img = imread(test_img_path)
plt.imshow(test_img)


Out[41]:
<matplotlib.image.AxesImage at 0x7f25bea3a860>

In [42]:
# Run this cell if you don't have a vgg graph built
if 'vgg' in globals():
    print('"vgg" object already exists.  Will not create again.')
else:
    #create vgg
    with tf.Session() as sess:
        input_ = tf.placeholder(tf.float32, [None, 224, 224, 3])
        vgg = vgg16.Vgg16()
        vgg.build(input_)


"vgg" object already exists.  Will not create again.

In [43]:
with tf.Session() as sess:
    img = utils.load_image(test_img_path)
    img = img.reshape((1, 224, 224, 3))

    feed_dict = {input_: img}
    code = sess.run(vgg.relu6, feed_dict=feed_dict)
        
saver = tf.train.Saver()
with tf.Session() as sess:
    saver.restore(sess, tf.train.latest_checkpoint('checkpoints'))
    
    feed = {inputs_: code}
    prediction = sess.run(predicted, feed_dict=feed).squeeze()

In [44]:
plt.imshow(test_img)


Out[44]:
<matplotlib.image.AxesImage at 0x7f25bea75cf8>

In [45]:
plt.barh(np.arange(5), prediction)
_ = plt.yticks(np.arange(5), lb.classes_)



In [ ]: