Capstone Project

Image Classification of Dog Breeds

Problem Statement:

Using images of Boston Bulls, Beagles, and Boxers from ImageNet, predict Boomer's mix of breeds.

Import Necessary Libraries

In [1]:
import warnings
warnings.filterwarnings('ignore')

%reload_ext autotime
In [2]:
from os import listdir
from keras.utils import np_utils
from imutils import paths

import keras as ks
from keras import backend as K
import cv2
import numpy as np

from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from skimage import restoration
Using TensorFlow backend.
time: 2.44 s

Part 1: Get Images from ImageNet

I found an amazing repo with CLI commands to download images and crop using the provided bounding boxes from ImageNet.

In [ ]:
%%bash
git clone --recursive https://github.com/tzutalin/ImageNet_Utils.git
cd ImageNet_Utils

# Download images of the three breeds using their synset ID
# Boston: n02096585
# Beagle: n02088364
# Boxer:  n02108089

./downloadutils.py --downloadOriginalImages --wnid n02096585
./downloadutils.py --downloadOriginalImages --wnid n02088364
./downloadutils.py --downloadOriginalImages --wnid n02108089


# Download Bounding Boxes

./downloadutils.py --downloadBoundingBox --wnid n02096585
./downloadutils.py --downloadBoundingBox --wnid n02088364
./downloadutils.py --downloadBoundingBox --wnid n02108089


# Crop Images by Bounding Box XML

./bbox_helper.py --save_boundingbox --bxmldir n02096585/
./bbox_helper.py --save_boundingbox --bxmldir n02088364/
./bbox_helper.py --save_boundingbox --bxmldir n02108089/


# Create Train, Test subfolders for each breed

mkdir data/{train/{n02096585,n02088364,n02108089},test/{n02096585,n02088364,n02108089}}
In [2]:
# Determine the number of images to create a test set 
# consisting of 30% of each breed

test_n02096585 = len(listdir('data/n02096585'))*.3
test_n02088364 = len(listdir('data/n02088364'))*.3
test_n02108089 = len(listdir('data/n02108089'))*.3

#310, 393, 953 for train
print(test_n02096585,test_n02088364,test_n02108089)
#93, 118, 286 for test
496.2 567.6 599.4
In [ ]:
%%bash

# Randomly select 30% of each breed's images and move to test folder

shuf -zen93 data/n02088364/*  | xargs -0 mv -t data/test/n02088364
shuf -zen118 data/n02096585/*  | xargs -0 mv -t data/test/n02096585
shuf -zen286 data/n02108089/*  | xargs -0 mv -t data/test/n02108089


# Use remaining 70% as train folder

mv data/n02088364 data/train
mv data/n02096585 data/train
mv data/n02108089 data/train

Part 2: Image Augmentation

Import images

adapted from source

In [112]:
# grab the list of images that we'll be describing
print("[INFO] describing images...")

## train ##
imagePaths = list(paths.list_images("data/train"))

# initialize the data matrix and labels list
trainData = []
trainLabels = []

# loop over the input images
for (i, imagePath) in enumerate(imagePaths):
    # load the image and extract the class label (assuming that our
    # path as the format: /path/to/dataset/{class}.{image_num}.jpg
    image = cv2.imread(imagePath)
    label = imagePath.split(os.path.sep)[-1].split(".")[0]

    # construct a feature vector raw pixel intensities, then update
    # the data matrix and labels list
    image = cv2.resize(image, (28,28))
    trainData.append(image)
    trainLabels.append(label)

    # show an update every 200 images
    if i > 0 and i % 200 == 0:
        print("[INFO] processed {}/{}".format(i, len(imagePaths)))
        
print("[INFO] image processing complete")


## test ##
imagePaths = list(paths.list_images("data/test"))

# initialize the data matrix and labels list
testData = []
testLabels = []

# loop over the input images
for (i, imagePath) in enumerate(imagePaths):
    # load the image and extract the class label (assuming that our
    # path as the format: /path/to/dataset/{class}.{image_num}.jpg
    image = cv2.imread(imagePath)
    label = imagePath.split(os.path.sep)[-1].split(".")[0]

    # construct a feature vector raw pixel intensities, then update
    # the data matrix and labels list
    image = cv2.resize(image, (28,28))
    testData.append(image)
    testLabels.append(label)

    # show an update every 200 images
    if i > 0 and i % 200 == 0:
        print("[INFO] processed {}/{}".format(i, len(imagePaths)))
        
print("[INFO] image processing complete")
[INFO] describing images...
[INFO] processed 200/3882
[INFO] processed 400/3882
[INFO] processed 600/3882
[INFO] processed 800/3882
[INFO] processed 1000/3882
[INFO] processed 1200/3882
[INFO] processed 1400/3882
[INFO] processed 1600/3882
[INFO] processed 1800/3882
[INFO] processed 2000/3882
[INFO] processed 2200/3882
[INFO] processed 2400/3882
[INFO] processed 2600/3882
[INFO] processed 2800/3882
[INFO] processed 3000/3882
[INFO] processed 3200/3882
[INFO] processed 3400/3882
[INFO] processed 3600/3882
[INFO] processed 3800/3882
[INFO] image processing complete
[INFO] processed 200/1662
[INFO] processed 400/1662
[INFO] processed 600/1662
[INFO] processed 800/1662
[INFO] processed 1000/1662
[INFO] processed 1200/1662
[INFO] processed 1400/1662
[INFO] processed 1600/1662
[INFO] image processing complete
In [113]:
#take out unique file identifers so that theyre all set to synset id
trainLabels = [i[0:9] for i in trainLabels]
testLabels = [i[0:9] for i in testLabels]

# encode the labels, converting them from strings to integers
le = LabelEncoder()
trainLabels = le.fit_transform(trainLabels)
testLabels = le.fit_transform(testLabels)

# scale the input image pixels to the range [0, 1], then transform
# the labels into vectors in the range [0, 3] 
trainData = np.array(trainData) / 255.0
trainLabels = np_utils.to_categorical(trainLabels, 3)

testData = np.array(testData) / 255.0
testLabels = np_utils.to_categorical(testLabels, 3)

Perform Image Augmentation & Save Images

adapted from [source]

In [3]:
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
import os
from os import listdir
from keras import backend as K
K.set_image_dim_ordering('tf')
time: 126 ms
In [115]:
# Save augmented images to file

# define data preparation
batch_size = 16


def image_augmentation(method,prefix,msg):

    # perform the specified augmentation
    datagen = method
    datagen.fit(trainData)
    i = 0

    generator = datagen.flow_from_directory('data/train/', target_size=(100,100),
        shuffle=False, batch_size=batch_size,
        save_to_dir='data/train',save_prefix=prefix)
   
    for batch in generator:
        i += 1
        if i > 20: # save 20 images
            break  # otherwise the generator would loop indefinitely
    
    images = generator.filenames
    classes = generator.classes
    print("Class Indices:",generator.class_indices)
    print(msg)
    print(len(listdir('data/train/'))-3," total augmented images")
    
    return images,classes

The following was actually run individually for each class due to issues in where images were saved and in how they were not named according to class.

In [118]:
# Flip Images
flip_imgs, flip_classes = image_augmentation(ImageDataGenerator(horizontal_flip=True, vertical_flip=True),'flip',"Saved flipped images")
# Shift Images
shift_imgs, shift_classes =image_augmentation(ImageDataGenerator(width_shift_range=0.2, height_shift_range=0.2),'shift',"Saved shifted images")
# Rotate Images
rotated_imgs, rotated_classes = image_augmentation(ImageDataGenerator(rotation_range=90),'rotate',"Saved rotated images")
# Center, Normalize Images
norm_imgs, norm_classes = image_augmentation(ImageDataGenerator(featurewise_center=True, featurewise_std_normalization=True),'norm',"Saved normalized images")
Found 1399 images belonging to 1 classes.
Class Indices: {'n02108089': 0}
Saved flipped images
334  total augmented images
Found 1399 images belonging to 1 classes.
Class Indices: {'n02108089': 0}
Saved shifted images
670  total augmented images
Found 1399 images belonging to 1 classes.
Class Indices: {'n02108089': 0}
Saved rotated images
1006  total augmented images
Found 1399 images belonging to 1 classes.
Class Indices: {'n02108089': 0}
Saved normalized images
1342  total augmented images

Re-import all images, along with augmented ones

In [4]:
def image_to_feature_vector(image, size=(32, 32)):
    # resize the image to a fixed size, then flatten the image into
    # a list of raw pixel intensities
    return cv2.resize(image, size).flatten()
time: 1.42 ms
In [5]:
print("[INFO] describing images...")
## train ##
imagePaths = list(paths.list_images("data/train"))
# initialize the data matrix and labels list
trainData = []
trainLabels = []
# loop over the input images
for (i, imagePath) in enumerate(imagePaths):
    image = cv2.imread(imagePath)
    label = imagePath.split(os.path.sep)[-1].split(".")[0]
    
    image = cv2.resize(image, (32,32))
    trainData.append(image)
    
    trainLabels.append(label)
    if i > 0 and i % 200 == 0:
        print("[INFO] processed {}/{}".format(i, len(imagePaths)))
        
print("[INFO] image processing complete")


## test ##
imagePaths = list(paths.list_images("data/test"))
testData = []
testLabels = []
for (i, imagePath) in enumerate(imagePaths):
    image = cv2.imread(imagePath)
    label = imagePath.split(os.path.sep)[-1].split(".")[0]

    image = cv2.resize(image, (32,32))
    testData.append(image)
    
    testLabels.append(label)
    if i > 0 and i % 200 == 0:
        print("[INFO] processed {}/{}".format(i, len(imagePaths)))
        
print("[INFO] image processing complete")
[INFO] describing images...
[INFO] processed 200/7914
[INFO] processed 400/7914
[INFO] processed 600/7914
[INFO] processed 800/7914
[INFO] processed 1000/7914
[INFO] processed 1200/7914
[INFO] processed 1400/7914
[INFO] processed 1600/7914
[INFO] processed 1800/7914
[INFO] processed 2000/7914
[INFO] processed 2200/7914
[INFO] processed 2400/7914
[INFO] processed 2600/7914
[INFO] processed 2800/7914
[INFO] processed 3000/7914
[INFO] processed 3200/7914
[INFO] processed 3400/7914
[INFO] processed 3600/7914
[INFO] processed 3800/7914
[INFO] processed 4000/7914
[INFO] processed 4200/7914
[INFO] processed 4400/7914
[INFO] processed 4600/7914
[INFO] processed 4800/7914
[INFO] processed 5000/7914
[INFO] processed 5200/7914
[INFO] processed 5400/7914
[INFO] processed 5600/7914
[INFO] processed 5800/7914
[INFO] processed 6000/7914
[INFO] processed 6200/7914
[INFO] processed 6400/7914
[INFO] processed 6600/7914
[INFO] processed 6800/7914
[INFO] processed 7000/7914
[INFO] processed 7200/7914
[INFO] processed 7400/7914
[INFO] processed 7600/7914
[INFO] processed 7800/7914
[INFO] image processing complete
[INFO] processed 200/1662
[INFO] processed 400/1662
[INFO] processed 600/1662
[INFO] processed 800/1662
[INFO] processed 1000/1662
[INFO] processed 1200/1662
[INFO] processed 1400/1662
[INFO] processed 1600/1662
[INFO] image processing complete
time: 9.67 s
In [6]:
#take out unique file identifers so that theyre all set to synset id
trainLabels = [i[0:9] for i in trainLabels]
testFiles = testLabels
testLabels = [i[0:9] for i in testLabels]
testFolders = testLabels

# encode the labels, converting them from strings to integers
le = LabelEncoder()
trainLabels = le.fit_transform(trainLabels)
testLabels = le.fit_transform(testLabels)

# scale the input image pixels to the range [0, 1], then transform
# the labels into vectors in the range [0, 3]
trainData = np.array(trainData) / 255.0
trainLabels = np_utils.to_categorical(trainLabels, 3)

testData = np.array(testData) / 255.0
testLabels = np_utils.to_categorical(testLabels, 3)

print("[INFO] Cell Finished.")
[INFO] Cell Finished.
time: 168 ms

Part 3: Modeling

In [7]:
from keras.models import Sequential
from keras.layers.core import Flatten
from keras.layers import Activation, Dense, Dropout
from keras.optimizers import SGD

from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D
time: 2.84 ms

Create Convolutional Neural Network

pretty sure adapted from this [source](http://machinelearningmastery.com/object-recognition-convolutional-neural-networks-keras-deep-learning-library/)

In [9]:
depth = 3
height = 32
width = 32
classes = 3
time: 1.3 ms
In [10]:
model = Sequential()

pool_size = (3,3)
strides = (3,3)

model.add(Convolution2D(32, (3, 3), activation='relu', padding='same', input_shape=(height, width, depth) ,data_format="channels_last"))
model.add(Dropout(0.5))

model.add(Convolution2D(32, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=pool_size,strides=strides))

model.add(Convolution2D(64, (3, 3), activation='relu', padding='same'))
model.add(Dropout(0.5))

model.add(Convolution2D(64, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=pool_size,strides=strides))

model.add(Convolution2D(128, (3, 3), activation='relu', padding='same'))
model.add(Dropout(0.5))

model.add(Convolution2D(128, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=pool_size,strides=strides))

model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation='softmax'))
time: 217 ms
In [11]:
# train, fit the model
K.set_image_dim_ordering('tf')
print("[INFO] compiling model...")

adam = ks.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

model.compile(loss="categorical_crossentropy", optimizer=adam,
    metrics=["accuracy"])

model.fit(trainData, trainLabels, epochs=500, batch_size=128, verbose=1)
[INFO] compiling model...
Epoch 1/500
7914/7914 [==============================] - 3s - loss: 1.1007 - acc: 0.3351      
Epoch 2/500
7914/7914 [==============================] - 2s - loss: 1.0326 - acc: 0.4527     
Epoch 3/500
7914/7914 [==============================] - 2s - loss: 0.9515 - acc: 0.5010     
Epoch 4/500
7914/7914 [==============================] - 2s - loss: 0.9258 - acc: 0.5275     
Epoch 5/500
7914/7914 [==============================] - 2s - loss: 0.8922 - acc: 0.5483     
Epoch 6/500
7914/7914 [==============================] - 2s - loss: 0.8783 - acc: 0.5609     
Epoch 7/500
7914/7914 [==============================] - 2s - loss: 0.8483 - acc: 0.5770     
Epoch 8/500
7914/7914 [==============================] - 2s - loss: 0.8409 - acc: 0.5848     
Epoch 9/500
7914/7914 [==============================] - 2s - loss: 0.8152 - acc: 0.6008     
Epoch 10/500
7914/7914 [==============================] - 2s - loss: 0.7979 - acc: 0.6207     
Epoch 11/500
7914/7914 [==============================] - 2s - loss: 0.7891 - acc: 0.6197     
Epoch 12/500
7914/7914 [==============================] - 2s - loss: 0.7765 - acc: 0.6356     
Epoch 13/500
7914/7914 [==============================] - 2s - loss: 0.7734 - acc: 0.6504     
Epoch 14/500
7914/7914 [==============================] - 2s - loss: 0.7401 - acc: 0.6596     
Epoch 15/500
7914/7914 [==============================] - 2s - loss: 0.7384 - acc: 0.6734     
Epoch 16/500
7914/7914 [==============================] - 2s - loss: 0.7150 - acc: 0.6825     
Epoch 17/500
7914/7914 [==============================] - 2s - loss: 0.7017 - acc: 0.6865     
Epoch 18/500
7914/7914 [==============================] - 2s - loss: 0.7010 - acc: 0.6935     
Epoch 19/500
7914/7914 [==============================] - 2s - loss: 0.6812 - acc: 0.7070     
Epoch 20/500
7914/7914 [==============================] - 2s - loss: 0.6783 - acc: 0.7060     
Epoch 21/500
7914/7914 [==============================] - 2s - loss: 0.6611 - acc: 0.7202     
Epoch 22/500
7914/7914 [==============================] - 2s - loss: 0.6400 - acc: 0.7386     
Epoch 23/500
7914/7914 [==============================] - 2s - loss: 0.6338 - acc: 0.7357     
Epoch 24/500
7914/7914 [==============================] - 2s - loss: 0.6158 - acc: 0.7482     
Epoch 25/500
7914/7914 [==============================] - 2s - loss: 0.5985 - acc: 0.7470     
Epoch 26/500
7914/7914 [==============================] - 2s - loss: 0.6277 - acc: 0.7400     
Epoch 27/500
7914/7914 [==============================] - 2s - loss: 0.5800 - acc: 0.7660     
Epoch 28/500
7914/7914 [==============================] - 2s - loss: 0.5905 - acc: 0.7590     
Epoch 29/500
7914/7914 [==============================] - 2s - loss: 0.5706 - acc: 0.7679     
Epoch 30/500
7914/7914 [==============================] - 2s - loss: 0.5511 - acc: 0.7837     
Epoch 31/500
7914/7914 [==============================] - 2s - loss: 0.5611 - acc: 0.7705     
Epoch 32/500
7914/7914 [==============================] - 2s - loss: 0.5317 - acc: 0.7911     
Epoch 33/500
7914/7914 [==============================] - 2s - loss: 0.5333 - acc: 0.7867     
Epoch 34/500
7914/7914 [==============================] - 2s - loss: 0.5398 - acc: 0.7857     
Epoch 35/500
7914/7914 [==============================] - 2s - loss: 0.5112 - acc: 0.8049     
Epoch 36/500
7914/7914 [==============================] - 2s - loss: 0.5215 - acc: 0.7959     
Epoch 37/500
7914/7914 [==============================] - 2s - loss: 0.5124 - acc: 0.7947     
Epoch 38/500
7914/7914 [==============================] - 2s - loss: 0.5112 - acc: 0.7983     
Epoch 39/500
7914/7914 [==============================] - 2s - loss: 0.4926 - acc: 0.8091     
Epoch 40/500
7914/7914 [==============================] - 2s - loss: 0.4755 - acc: 0.8130     
Epoch 41/500
7914/7914 [==============================] - 2s - loss: 0.4788 - acc: 0.8130     
Epoch 42/500
7914/7914 [==============================] - 2s - loss: 0.4833 - acc: 0.8063     
Epoch 43/500
7914/7914 [==============================] - 2s - loss: 0.4733 - acc: 0.8180     
Epoch 44/500
7914/7914 [==============================] - 2s - loss: 0.4642 - acc: 0.8194     
Epoch 45/500
7914/7914 [==============================] - 2s - loss: 0.4691 - acc: 0.8170     
Epoch 46/500
7914/7914 [==============================] - 2s - loss: 0.4551 - acc: 0.8222     
Epoch 47/500
7914/7914 [==============================] - 2s - loss: 0.4523 - acc: 0.8246     
Epoch 48/500
7914/7914 [==============================] - 2s - loss: 0.4374 - acc: 0.8302     
Epoch 49/500
7914/7914 [==============================] - 2s - loss: 0.4504 - acc: 0.8242     
Epoch 50/500
7914/7914 [==============================] - 2s - loss: 0.4463 - acc: 0.8269     
Epoch 51/500
7914/7914 [==============================] - 2s - loss: 0.4418 - acc: 0.8282     
Epoch 52/500
7914/7914 [==============================] - 2s - loss: 0.4373 - acc: 0.8337     
Epoch 53/500
7914/7914 [==============================] - 2s - loss: 0.4358 - acc: 0.8347     
Epoch 54/500
7914/7914 [==============================] - 2s - loss: 0.4233 - acc: 0.8378     
Epoch 55/500
7914/7914 [==============================] - 2s - loss: 0.4301 - acc: 0.8340     
Epoch 56/500
7914/7914 [==============================] - 2s - loss: 0.4235 - acc: 0.8380     
Epoch 57/500
7914/7914 [==============================] - 2s - loss: 0.4068 - acc: 0.8467     
Epoch 58/500
7914/7914 [==============================] - 2s - loss: 0.4093 - acc: 0.8428     
Epoch 59/500
7914/7914 [==============================] - 2s - loss: 0.4007 - acc: 0.8453     
Epoch 60/500
7914/7914 [==============================] - 2s - loss: 0.3897 - acc: 0.8506     
Epoch 61/500
7914/7914 [==============================] - 2s - loss: 0.4018 - acc: 0.8461     
Epoch 62/500
7914/7914 [==============================] - 2s - loss: 0.3884 - acc: 0.8490     
Epoch 63/500
7914/7914 [==============================] - 2s - loss: 0.3862 - acc: 0.8544     
Epoch 64/500
7914/7914 [==============================] - 2s - loss: 0.3725 - acc: 0.8687     
Epoch 65/500
7914/7914 [==============================] - 2s - loss: 0.3877 - acc: 0.8525     
Epoch 66/500
7914/7914 [==============================] - 2s - loss: 0.3736 - acc: 0.8529     
Epoch 67/500
7914/7914 [==============================] - 2s - loss: 0.3672 - acc: 0.8620     
Epoch 68/500
7914/7914 [==============================] - 2s - loss: 0.3754 - acc: 0.8592     
Epoch 69/500
7914/7914 [==============================] - 2s - loss: 0.3634 - acc: 0.8615     
Epoch 70/500
7914/7914 [==============================] - 2s - loss: 0.3698 - acc: 0.8639     
Epoch 71/500
7914/7914 [==============================] - 2s - loss: 0.3538 - acc: 0.8728     
Epoch 72/500
7914/7914 [==============================] - 2s - loss: 0.3497 - acc: 0.8723     
Epoch 73/500
7914/7914 [==============================] - 2s - loss: 0.3529 - acc: 0.8710     
Epoch 74/500
7914/7914 [==============================] - 2s - loss: 0.3528 - acc: 0.8677     
Epoch 75/500
7914/7914 [==============================] - 2s - loss: 0.3567 - acc: 0.8683     
Epoch 76/500
7914/7914 [==============================] - 2s - loss: 0.3635 - acc: 0.8672     
Epoch 77/500
7914/7914 [==============================] - 2s - loss: 0.3412 - acc: 0.8747     
Epoch 78/500
7914/7914 [==============================] - 2s - loss: 0.3458 - acc: 0.8726     
Epoch 79/500
7914/7914 [==============================] - 2s - loss: 0.3514 - acc: 0.8699     
Epoch 80/500
7914/7914 [==============================] - 2s - loss: 0.3368 - acc: 0.8767     
Epoch 81/500
7914/7914 [==============================] - 2s - loss: 0.3478 - acc: 0.8731     
Epoch 82/500
7914/7914 [==============================] - 2s - loss: 0.3284 - acc: 0.8757     
Epoch 83/500
7914/7914 [==============================] - 2s - loss: 0.3244 - acc: 0.8807     
Epoch 84/500
7914/7914 [==============================] - 2s - loss: 0.3321 - acc: 0.8776     
Epoch 85/500
7914/7914 [==============================] - 2s - loss: 0.3254 - acc: 0.8807     
Epoch 86/500
7914/7914 [==============================] - 2s - loss: 0.3237 - acc: 0.8827     
Epoch 87/500
7914/7914 [==============================] - 2s - loss: 0.3398 - acc: 0.8747     
Epoch 88/500
7914/7914 [==============================] - 2s - loss: 0.3185 - acc: 0.8859     
Epoch 89/500
7914/7914 [==============================] - 2s - loss: 0.3356 - acc: 0.8778     
Epoch 90/500
7914/7914 [==============================] - 2s - loss: 0.3224 - acc: 0.8813     
Epoch 91/500
7914/7914 [==============================] - 2s - loss: 0.3235 - acc: 0.8801     
Epoch 92/500
7914/7914 [==============================] - 2s - loss: 0.3156 - acc: 0.8839     
Epoch 93/500
7914/7914 [==============================] - 2s - loss: 0.3085 - acc: 0.8872     
Epoch 94/500
7914/7914 [==============================] - 2s - loss: 0.3087 - acc: 0.8862     
Epoch 95/500
7914/7914 [==============================] - 2s - loss: 0.3113 - acc: 0.8860     
Epoch 96/500
7914/7914 [==============================] - 2s - loss: 0.3021 - acc: 0.8934     
Epoch 97/500
7914/7914 [==============================] - 2s - loss: 0.3272 - acc: 0.8792     
Epoch 98/500
7914/7914 [==============================] - 2s - loss: 0.3159 - acc: 0.8863     
Epoch 99/500
7914/7914 [==============================] - 2s - loss: 0.2976 - acc: 0.8921     
Epoch 100/500
7914/7914 [==============================] - 2s - loss: 0.3013 - acc: 0.8887     
Epoch 101/500
7914/7914 [==============================] - 2s - loss: 0.2933 - acc: 0.8931     
Epoch 102/500
7914/7914 [==============================] - 2s - loss: 0.2940 - acc: 0.8951     
Epoch 103/500
7914/7914 [==============================] - 2s - loss: 0.2925 - acc: 0.8950     
Epoch 104/500
7914/7914 [==============================] - 2s - loss: 0.2857 - acc: 0.8950     
Epoch 105/500
7914/7914 [==============================] - 2s - loss: 0.2969 - acc: 0.8920     
Epoch 106/500
7914/7914 [==============================] - 2s - loss: 0.2898 - acc: 0.8936     
Epoch 107/500
7914/7914 [==============================] - 2s - loss: 0.2795 - acc: 0.9012     
Epoch 108/500
7914/7914 [==============================] - 2s - loss: 0.2858 - acc: 0.8956     
Epoch 109/500
7914/7914 [==============================] - 2s - loss: 0.2851 - acc: 0.8970     
Epoch 110/500
7914/7914 [==============================] - 2s - loss: 0.2893 - acc: 0.8944     
Epoch 111/500
7914/7914 [==============================] - 2s - loss: 0.2883 - acc: 0.8961     
Epoch 112/500
7914/7914 [==============================] - 2s - loss: 0.2633 - acc: 0.9067     
Epoch 113/500
7914/7914 [==============================] - 2s - loss: 0.2926 - acc: 0.8958     
Epoch 114/500
7914/7914 [==============================] - 2s - loss: 0.2836 - acc: 0.8966     
Epoch 115/500
7914/7914 [==============================] - 2s - loss: 0.3015 - acc: 0.8877     
Epoch 116/500
7914/7914 [==============================] - 2s - loss: 0.2743 - acc: 0.9033     
Epoch 117/500
7914/7914 [==============================] - 2s - loss: 0.2869 - acc: 0.8975     
Epoch 118/500
7914/7914 [==============================] - 2s - loss: 0.2724 - acc: 0.9025     
Epoch 119/500
7914/7914 [==============================] - 2s - loss: 0.2664 - acc: 0.9023     
Epoch 120/500
7914/7914 [==============================] - 2s - loss: 0.2787 - acc: 0.8963     
Epoch 121/500
7914/7914 [==============================] - 2s - loss: 0.2871 - acc: 0.8922     
Epoch 122/500
7914/7914 [==============================] - 2s - loss: 0.2546 - acc: 0.9104     
Epoch 123/500
7914/7914 [==============================] - 2s - loss: 0.2590 - acc: 0.9021     
Epoch 124/500
7914/7914 [==============================] - 2s - loss: 0.2581 - acc: 0.9067     
Epoch 125/500
7914/7914 [==============================] - 2s - loss: 0.2537 - acc: 0.9050     
Epoch 126/500
7914/7914 [==============================] - 2s - loss: 0.2654 - acc: 0.9052     
Epoch 127/500
7914/7914 [==============================] - 2s - loss: 0.2700 - acc: 0.9028     
Epoch 128/500
7914/7914 [==============================] - 2s - loss: 0.2654 - acc: 0.8984     
Epoch 129/500
7914/7914 [==============================] - 2s - loss: 0.2591 - acc: 0.9079     
Epoch 130/500
7914/7914 [==============================] - 2s - loss: 0.2501 - acc: 0.9098     
Epoch 131/500
7914/7914 [==============================] - 2s - loss: 0.2655 - acc: 0.9031     
Epoch 132/500
7914/7914 [==============================] - 2s - loss: 0.2501 - acc: 0.9093     
Epoch 133/500
7914/7914 [==============================] - 2s - loss: 0.2624 - acc: 0.9047     
Epoch 134/500
7914/7914 [==============================] - 2s - loss: 0.2537 - acc: 0.9098     
Epoch 135/500
7914/7914 [==============================] - 2s - loss: 0.2538 - acc: 0.9080     
Epoch 136/500
7914/7914 [==============================] - 2s - loss: 0.2612 - acc: 0.9059     
Epoch 137/500
7914/7914 [==============================] - 2s - loss: 0.2373 - acc: 0.9139     
Epoch 138/500
7914/7914 [==============================] - 2s - loss: 0.2539 - acc: 0.9100     
Epoch 139/500
7914/7914 [==============================] - 2s - loss: 0.2593 - acc: 0.9025     
Epoch 140/500
7914/7914 [==============================] - 2s - loss: 0.2445 - acc: 0.9115     
Epoch 141/500
7914/7914 [==============================] - 2s - loss: 0.2442 - acc: 0.9095     
Epoch 142/500
7914/7914 [==============================] - 2s - loss: 0.2512 - acc: 0.9088     
Epoch 143/500
7914/7914 [==============================] - 2s - loss: 0.2349 - acc: 0.9162     
Epoch 144/500
7914/7914 [==============================] - 2s - loss: 0.2375 - acc: 0.9129     
Epoch 145/500
7914/7914 [==============================] - 2s - loss: 0.2377 - acc: 0.9177     
Epoch 146/500
7914/7914 [==============================] - 2s - loss: 0.2385 - acc: 0.9151     
Epoch 147/500
7914/7914 [==============================] - 2s - loss: 0.2447 - acc: 0.9113     
Epoch 148/500
7914/7914 [==============================] - 2s - loss: 0.2544 - acc: 0.9069     
Epoch 149/500
7914/7914 [==============================] - 2s - loss: 0.2321 - acc: 0.9182     
Epoch 150/500
7914/7914 [==============================] - 2s - loss: 0.2247 - acc: 0.9190     
Epoch 151/500
7914/7914 [==============================] - 2s - loss: 0.2379 - acc: 0.9162     
Epoch 152/500
7914/7914 [==============================] - 2s - loss: 0.2285 - acc: 0.9188     
Epoch 153/500
7914/7914 [==============================] - 2s - loss: 0.2396 - acc: 0.9099     
Epoch 154/500
7914/7914 [==============================] - 2s - loss: 0.2288 - acc: 0.9146     
Epoch 155/500
7914/7914 [==============================] - 2s - loss: 0.2400 - acc: 0.9148     
Epoch 156/500
7914/7914 [==============================] - 2s - loss: 0.2374 - acc: 0.9121     
Epoch 157/500
7914/7914 [==============================] - 2s - loss: 0.2371 - acc: 0.9175     
Epoch 158/500
7914/7914 [==============================] - 2s - loss: 0.2300 - acc: 0.9184     
Epoch 159/500
7914/7914 [==============================] - 2s - loss: 0.2338 - acc: 0.9158     
Epoch 160/500
7914/7914 [==============================] - 2s - loss: 0.2264 - acc: 0.9203     
Epoch 161/500
7914/7914 [==============================] - 2s - loss: 0.2267 - acc: 0.9233     
Epoch 162/500
7914/7914 [==============================] - 2s - loss: 0.2470 - acc: 0.9086     
Epoch 163/500
7914/7914 [==============================] - 2s - loss: 0.2353 - acc: 0.9169     
Epoch 164/500
7914/7914 [==============================] - 2s - loss: 0.2117 - acc: 0.9224     
Epoch 165/500
7914/7914 [==============================] - 2s - loss: 0.2318 - acc: 0.9170     
Epoch 166/500
7914/7914 [==============================] - 2s - loss: 0.2137 - acc: 0.9234     
Epoch 167/500
7914/7914 [==============================] - 2s - loss: 0.2159 - acc: 0.9213     
Epoch 168/500
7914/7914 [==============================] - 2s - loss: 0.2115 - acc: 0.9220     
Epoch 169/500
7914/7914 [==============================] - 2s - loss: 0.2134 - acc: 0.9265     
Epoch 170/500
7914/7914 [==============================] - 2s - loss: 0.2266 - acc: 0.9177     
Epoch 171/500
7914/7914 [==============================] - 2s - loss: 0.2237 - acc: 0.9205     
Epoch 172/500
7914/7914 [==============================] - 2s - loss: 0.2030 - acc: 0.9284     
Epoch 173/500
7914/7914 [==============================] - 2s - loss: 0.2263 - acc: 0.9234     
Epoch 174/500
7914/7914 [==============================] - 2s - loss: 0.2185 - acc: 0.9233     
Epoch 175/500
7914/7914 [==============================] - 2s - loss: 0.2153 - acc: 0.9208     
Epoch 176/500
7914/7914 [==============================] - 2s - loss: 0.2057 - acc: 0.9281     
Epoch 177/500
7914/7914 [==============================] - 2s - loss: 0.2090 - acc: 0.9268     
Epoch 178/500
7914/7914 [==============================] - 2s - loss: 0.2149 - acc: 0.9220     
Epoch 179/500
7914/7914 [==============================] - 2s - loss: 0.2255 - acc: 0.9160     
Epoch 180/500
7914/7914 [==============================] - 2s - loss: 0.2172 - acc: 0.9210     
Epoch 181/500
7914/7914 [==============================] - 2s - loss: 0.2237 - acc: 0.9212     
Epoch 182/500
7914/7914 [==============================] - 2s - loss: 0.1944 - acc: 0.9290     
Epoch 183/500
7914/7914 [==============================] - 2s - loss: 0.2058 - acc: 0.9278     
Epoch 184/500
7914/7914 [==============================] - 2s - loss: 0.2192 - acc: 0.9214     
Epoch 185/500
7914/7914 [==============================] - 2s - loss: 0.1955 - acc: 0.9301     
Epoch 186/500
7914/7914 [==============================] - 2s - loss: 0.1908 - acc: 0.9277     
Epoch 187/500
7914/7914 [==============================] - 2s - loss: 0.1979 - acc: 0.9295     
Epoch 188/500
7914/7914 [==============================] - 2s - loss: 0.2089 - acc: 0.9258     
Epoch 189/500
7914/7914 [==============================] - 2s - loss: 0.1995 - acc: 0.9294     
Epoch 190/500
7914/7914 [==============================] - 2s - loss: 0.1984 - acc: 0.9303     
Epoch 191/500
7914/7914 [==============================] - 2s - loss: 0.2017 - acc: 0.9273     
Epoch 192/500
7914/7914 [==============================] - 2s - loss: 0.2103 - acc: 0.9265     
Epoch 193/500
7914/7914 [==============================] - 2s - loss: 0.1976 - acc: 0.9271     
Epoch 194/500
7914/7914 [==============================] - 2s - loss: 0.1953 - acc: 0.9300     
Epoch 195/500
7914/7914 [==============================] - 2s - loss: 0.1973 - acc: 0.9287     
Epoch 196/500
7914/7914 [==============================] - 2s - loss: 0.1910 - acc: 0.9327     
Epoch 197/500
7914/7914 [==============================] - 2s - loss: 0.2051 - acc: 0.9258     
Epoch 198/500
7914/7914 [==============================] - 2s - loss: 0.1986 - acc: 0.9286     
Epoch 199/500
7914/7914 [==============================] - 2s - loss: 0.2153 - acc: 0.9233     
Epoch 200/500
7914/7914 [==============================] - 2s - loss: 0.2014 - acc: 0.9284     
Epoch 201/500
7914/7914 [==============================] - 2s - loss: 0.2075 - acc: 0.9261     
Epoch 202/500
7914/7914 [==============================] - 2s - loss: 0.1954 - acc: 0.9305     
Epoch 203/500
7914/7914 [==============================] - 2s - loss: 0.1860 - acc: 0.9352     
Epoch 204/500
7914/7914 [==============================] - 2s - loss: 0.1943 - acc: 0.9281     
Epoch 205/500
7914/7914 [==============================] - 2s - loss: 0.1918 - acc: 0.9320     
Epoch 206/500
7914/7914 [==============================] - 2s - loss: 0.1988 - acc: 0.9262     
Epoch 207/500
7914/7914 [==============================] - 2s - loss: 0.1997 - acc: 0.9315     
Epoch 208/500
7914/7914 [==============================] - 2s - loss: 0.1937 - acc: 0.9284     
Epoch 209/500
7914/7914 [==============================] - 2s - loss: 0.2080 - acc: 0.9311     
Epoch 210/500
7914/7914 [==============================] - 2s - loss: 0.1859 - acc: 0.9359     
Epoch 211/500
7914/7914 [==============================] - 2s - loss: 0.1953 - acc: 0.9309     
Epoch 212/500
7914/7914 [==============================] - 2s - loss: 0.1934 - acc: 0.9306     
Epoch 213/500
7914/7914 [==============================] - 2s - loss: 0.1981 - acc: 0.9290     
Epoch 214/500
7914/7914 [==============================] - 2s - loss: 0.1940 - acc: 0.9333     
Epoch 215/500
7914/7914 [==============================] - 2s - loss: 0.1885 - acc: 0.9340     
Epoch 216/500
7914/7914 [==============================] - 2s - loss: 0.1948 - acc: 0.9296     
Epoch 217/500
7914/7914 [==============================] - 2s - loss: 0.1936 - acc: 0.9332     
Epoch 218/500
7914/7914 [==============================] - 2s - loss: 0.1993 - acc: 0.9296     
Epoch 219/500
7914/7914 [==============================] - 2s - loss: 0.1815 - acc: 0.9364     
Epoch 220/500
7914/7914 [==============================] - 2s - loss: 0.1900 - acc: 0.9316     
Epoch 221/500
7914/7914 [==============================] - 2s - loss: 0.1804 - acc: 0.9332     
Epoch 222/500
7914/7914 [==============================] - 2s - loss: 0.1766 - acc: 0.9343     
Epoch 223/500
7914/7914 [==============================] - 2s - loss: 0.1976 - acc: 0.9310     
Epoch 224/500
7914/7914 [==============================] - 2s - loss: 0.2065 - acc: 0.9276     
Epoch 225/500
7914/7914 [==============================] - 2s - loss: 0.1819 - acc: 0.9368     
Epoch 226/500
7914/7914 [==============================] - 2s - loss: 0.1934 - acc: 0.9309     
Epoch 227/500
7914/7914 [==============================] - 2s - loss: 0.1749 - acc: 0.9406     
Epoch 228/500
7914/7914 [==============================] - 2s - loss: 0.1854 - acc: 0.9356     
Epoch 229/500
7914/7914 [==============================] - 2s - loss: 0.1743 - acc: 0.9390     
Epoch 230/500
7914/7914 [==============================] - 2s - loss: 0.2006 - acc: 0.9292     
Epoch 231/500
7914/7914 [==============================] - 2s - loss: 0.1881 - acc: 0.9367     
Epoch 232/500
7914/7914 [==============================] - 2s - loss: 0.1753 - acc: 0.9397     
Epoch 233/500
7914/7914 [==============================] - 2s - loss: 0.1780 - acc: 0.9364     
Epoch 234/500
7914/7914 [==============================] - 2s - loss: 0.1990 - acc: 0.9309     
Epoch 235/500
7914/7914 [==============================] - 2s - loss: 0.1736 - acc: 0.9387     
Epoch 236/500
7914/7914 [==============================] - 2s - loss: 0.1768 - acc: 0.9342     
Epoch 237/500
7914/7914 [==============================] - 2s - loss: 0.1870 - acc: 0.9335     
Epoch 238/500
7914/7914 [==============================] - 2s - loss: 0.1859 - acc: 0.9311     
Epoch 239/500
7914/7914 [==============================] - 2s - loss: 0.1770 - acc: 0.9367     
Epoch 240/500
7914/7914 [==============================] - 2s - loss: 0.1828 - acc: 0.9353     
Epoch 241/500
7914/7914 [==============================] - 2s - loss: 0.1857 - acc: 0.9378     
Epoch 242/500
7914/7914 [==============================] - 2s - loss: 0.1823 - acc: 0.9367     
Epoch 243/500
7914/7914 [==============================] - 2s - loss: 0.1883 - acc: 0.9329     
Epoch 244/500
7914/7914 [==============================] - 2s - loss: 0.1874 - acc: 0.9369     
Epoch 245/500
7914/7914 [==============================] - 2s - loss: 0.1705 - acc: 0.9409     
Epoch 246/500
7914/7914 [==============================] - 2s - loss: 0.1797 - acc: 0.9367     
Epoch 247/500
7914/7914 [==============================] - 2s - loss: 0.1683 - acc: 0.9445     
Epoch 248/500
7914/7914 [==============================] - 2s - loss: 0.1795 - acc: 0.9366     
Epoch 249/500
7914/7914 [==============================] - 2s - loss: 0.1739 - acc: 0.9395     
Epoch 250/500
7914/7914 [==============================] - 2s - loss: 0.1789 - acc: 0.9358     
Epoch 251/500
7914/7914 [==============================] - 2s - loss: 0.1806 - acc: 0.9372     
Epoch 252/500
7914/7914 [==============================] - 2s - loss: 0.1649 - acc: 0.9423     
Epoch 253/500
7914/7914 [==============================] - 2s - loss: 0.1850 - acc: 0.9357     
Epoch 254/500
7914/7914 [==============================] - 2s - loss: 0.1672 - acc: 0.9433     
Epoch 255/500
7914/7914 [==============================] - 2s - loss: 0.1668 - acc: 0.9438     
Epoch 256/500
7914/7914 [==============================] - 2s - loss: 0.1923 - acc: 0.9319     
Epoch 257/500
7914/7914 [==============================] - 2s - loss: 0.1679 - acc: 0.9387     
Epoch 258/500
7914/7914 [==============================] - 2s - loss: 0.1621 - acc: 0.9426     
Epoch 259/500
7914/7914 [==============================] - 2s - loss: 0.1592 - acc: 0.9444     
Epoch 260/500
7914/7914 [==============================] - 2s - loss: 0.1729 - acc: 0.9400     
Epoch 261/500
7914/7914 [==============================] - 2s - loss: 0.1797 - acc: 0.9400     
Epoch 262/500
7914/7914 [==============================] - 2s - loss: 0.1780 - acc: 0.9406     
Epoch 263/500
7914/7914 [==============================] - 2s - loss: 0.1715 - acc: 0.9415     
Epoch 264/500
7914/7914 [==============================] - 2s - loss: 0.1589 - acc: 0.9436     
Epoch 265/500
7914/7914 [==============================] - 2s - loss: 0.1767 - acc: 0.9411     
Epoch 266/500
7914/7914 [==============================] - 2s - loss: 0.1841 - acc: 0.9344     
Epoch 267/500
7914/7914 [==============================] - 2s - loss: 0.1705 - acc: 0.9396     
Epoch 268/500
7914/7914 [==============================] - 2s - loss: 0.1664 - acc: 0.9429     
Epoch 269/500
7914/7914 [==============================] - 2s - loss: 0.1647 - acc: 0.9434     
Epoch 270/500
7914/7914 [==============================] - 2s - loss: 0.1671 - acc: 0.9426     
Epoch 271/500
7914/7914 [==============================] - 2s - loss: 0.1793 - acc: 0.9373     
Epoch 272/500
7914/7914 [==============================] - 2s - loss: 0.1731 - acc: 0.9412     
Epoch 273/500
7914/7914 [==============================] - 2s - loss: 0.1690 - acc: 0.9411     
Epoch 274/500
7914/7914 [==============================] - 2s - loss: 0.1682 - acc: 0.9453     
Epoch 275/500
7914/7914 [==============================] - 2s - loss: 0.1621 - acc: 0.9420     
Epoch 276/500
7914/7914 [==============================] - 2s - loss: 0.1645 - acc: 0.9415     
Epoch 277/500
7914/7914 [==============================] - 2s - loss: 0.1679 - acc: 0.9450     
Epoch 278/500
7914/7914 [==============================] - 2s - loss: 0.1686 - acc: 0.9385     
Epoch 279/500
7914/7914 [==============================] - 2s - loss: 0.1707 - acc: 0.9423     
Epoch 280/500
7914/7914 [==============================] - 2s - loss: 0.1919 - acc: 0.9344     
Epoch 281/500
7914/7914 [==============================] - 2s - loss: 0.1654 - acc: 0.9417     
Epoch 282/500
7914/7914 [==============================] - 2s - loss: 0.1606 - acc: 0.9433     
Epoch 283/500
7914/7914 [==============================] - 2s - loss: 0.1651 - acc: 0.9420     
Epoch 284/500
7914/7914 [==============================] - 2s - loss: 0.1592 - acc: 0.9458     
Epoch 285/500
7914/7914 [==============================] - 2s - loss: 0.1648 - acc: 0.9397     
Epoch 286/500
7914/7914 [==============================] - 2s - loss: 0.1620 - acc: 0.9445     
Epoch 287/500
7914/7914 [==============================] - 2s - loss: 0.1595 - acc: 0.9490     
Epoch 288/500
7914/7914 [==============================] - 2s - loss: 0.1643 - acc: 0.9419     
Epoch 289/500
7914/7914 [==============================] - 2s - loss: 0.1716 - acc: 0.9434     
Epoch 290/500
7914/7914 [==============================] - 2s - loss: 0.1620 - acc: 0.9458     
Epoch 291/500
7914/7914 [==============================] - 2s - loss: 0.1666 - acc: 0.9423     
Epoch 292/500
7914/7914 [==============================] - 2s - loss: 0.1745 - acc: 0.9378     
Epoch 293/500
7914/7914 [==============================] - 2s - loss: 0.1595 - acc: 0.9428     
Epoch 294/500
7914/7914 [==============================] - 2s - loss: 0.1561 - acc: 0.9441     
Epoch 295/500
7914/7914 [==============================] - 2s - loss: 0.1873 - acc: 0.9392     
Epoch 296/500
7914/7914 [==============================] - 2s - loss: 0.1649 - acc: 0.9438     
Epoch 297/500
7914/7914 [==============================] - 2s - loss: 0.1596 - acc: 0.9426     
Epoch 298/500
7914/7914 [==============================] - 2s - loss: 0.1631 - acc: 0.9454     
Epoch 299/500
7914/7914 [==============================] - 2s - loss: 0.1608 - acc: 0.9447     
Epoch 300/500
7914/7914 [==============================] - 2s - loss: 0.1674 - acc: 0.9425     
Epoch 301/500
7914/7914 [==============================] - 2s - loss: 0.1596 - acc: 0.9479     
Epoch 302/500
7914/7914 [==============================] - 2s - loss: 0.1576 - acc: 0.9471     
Epoch 303/500
7914/7914 [==============================] - 2s - loss: 0.1617 - acc: 0.9463     
Epoch 304/500
7914/7914 [==============================] - 2s - loss: 0.1464 - acc: 0.9481     
Epoch 305/500
7914/7914 [==============================] - 2s - loss: 0.1698 - acc: 0.9385     
Epoch 306/500
7914/7914 [==============================] - 2s - loss: 0.1507 - acc: 0.9464     
Epoch 307/500
7914/7914 [==============================] - 2s - loss: 0.1567 - acc: 0.9458     
Epoch 308/500
7914/7914 [==============================] - 2s - loss: 0.1572 - acc: 0.9460     
Epoch 309/500
7914/7914 [==============================] - 2s - loss: 0.1586 - acc: 0.9417     
Epoch 310/500
7914/7914 [==============================] - 2s - loss: 0.1492 - acc: 0.9508     
Epoch 311/500
7914/7914 [==============================] - 2s - loss: 0.1592 - acc: 0.9452     
Epoch 312/500
7914/7914 [==============================] - 2s - loss: 0.1587 - acc: 0.9433     
Epoch 313/500
7914/7914 [==============================] - 2s - loss: 0.1574 - acc: 0.9469     
Epoch 314/500
7914/7914 [==============================] - 2s - loss: 0.1630 - acc: 0.9438     
Epoch 315/500
7914/7914 [==============================] - 2s - loss: 0.1499 - acc: 0.9508     
Epoch 316/500
7914/7914 [==============================] - 2s - loss: 0.1452 - acc: 0.9491     
Epoch 317/500
7914/7914 [==============================] - 2s - loss: 0.1604 - acc: 0.9448     
Epoch 318/500
7914/7914 [==============================] - 2s - loss: 0.1565 - acc: 0.9448     
Epoch 319/500
7914/7914 [==============================] - 2s - loss: 0.1600 - acc: 0.9471     
Epoch 320/500
7914/7914 [==============================] - 2s - loss: 0.1567 - acc: 0.9488     
Epoch 321/500
7914/7914 [==============================] - 2s - loss: 0.1591 - acc: 0.9447     
Epoch 322/500
7914/7914 [==============================] - 2s - loss: 0.1664 - acc: 0.9405     
Epoch 323/500
7914/7914 [==============================] - 2s - loss: 0.1557 - acc: 0.9482     
Epoch 324/500
7914/7914 [==============================] - 2s - loss: 0.1671 - acc: 0.9440     
Epoch 325/500
7914/7914 [==============================] - 2s - loss: 0.1527 - acc: 0.9490     
Epoch 326/500
7914/7914 [==============================] - 2s - loss: 0.1617 - acc: 0.9457     
Epoch 327/500
7914/7914 [==============================] - 2s - loss: 0.1548 - acc: 0.9478     
Epoch 328/500
7914/7914 [==============================] - 2s - loss: 0.1601 - acc: 0.9436     
Epoch 329/500
7914/7914 [==============================] - 2s - loss: 0.1564 - acc: 0.9484     
Epoch 330/500
7914/7914 [==============================] - 2s - loss: 0.1452 - acc: 0.9496     
Epoch 331/500
7914/7914 [==============================] - 2s - loss: 0.1519 - acc: 0.9468     
Epoch 332/500
7914/7914 [==============================] - 2s - loss: 0.1401 - acc: 0.9520     
Epoch 333/500
7914/7914 [==============================] - 2s - loss: 0.1551 - acc: 0.9481     
Epoch 334/500
7914/7914 [==============================] - 2s - loss: 0.1533 - acc: 0.9469     
Epoch 335/500
7914/7914 [==============================] - 2s - loss: 0.1451 - acc: 0.9477     
Epoch 336/500
7914/7914 [==============================] - 2s - loss: 0.1502 - acc: 0.9510     
Epoch 337/500
7914/7914 [==============================] - 2s - loss: 0.1440 - acc: 0.9492     
Epoch 338/500
7914/7914 [==============================] - 2s - loss: 0.1516 - acc: 0.9469     
Epoch 339/500
7914/7914 [==============================] - 2s - loss: 0.1553 - acc: 0.9457     
Epoch 340/500
7914/7914 [==============================] - 2s - loss: 0.1506 - acc: 0.9469     
Epoch 341/500
7914/7914 [==============================] - 2s - loss: 0.1558 - acc: 0.9441     
Epoch 342/500
7914/7914 [==============================] - 2s - loss: 0.1434 - acc: 0.9521     
Epoch 343/500
7914/7914 [==============================] - 2s - loss: 0.1561 - acc: 0.9472     
Epoch 344/500
7914/7914 [==============================] - 2s - loss: 0.1456 - acc: 0.9512     
Epoch 345/500
7914/7914 [==============================] - 2s - loss: 0.1354 - acc: 0.9495     
Epoch 346/500
7914/7914 [==============================] - 2s - loss: 0.1425 - acc: 0.9506     
Epoch 347/500
7914/7914 [==============================] - 2s - loss: 0.1406 - acc: 0.9520     
Epoch 348/500
7914/7914 [==============================] - 2s - loss: 0.1573 - acc: 0.9472     
Epoch 349/500
7914/7914 [==============================] - 2s - loss: 0.1420 - acc: 0.9498     
Epoch 350/500
7914/7914 [==============================] - 2s - loss: 0.1437 - acc: 0.9481     
Epoch 351/500
7914/7914 [==============================] - 2s - loss: 0.1328 - acc: 0.9563     
Epoch 352/500
7914/7914 [==============================] - 2s - loss: 0.1574 - acc: 0.9479     
Epoch 353/500
7914/7914 [==============================] - 2s - loss: 0.1542 - acc: 0.9486     
Epoch 354/500
7914/7914 [==============================] - 2s - loss: 0.1550 - acc: 0.9457     
Epoch 355/500
7914/7914 [==============================] - 2s - loss: 0.1329 - acc: 0.9520     
Epoch 356/500
7914/7914 [==============================] - 2s - loss: 0.1434 - acc: 0.9526     
Epoch 357/500
7914/7914 [==============================] - 2s - loss: 0.1498 - acc: 0.9464     
Epoch 358/500
7914/7914 [==============================] - 2s - loss: 0.1561 - acc: 0.9460     
Epoch 359/500
7914/7914 [==============================] - 2s - loss: 0.1502 - acc: 0.9490     
Epoch 360/500
7914/7914 [==============================] - 2s - loss: 0.1600 - acc: 0.9492     
Epoch 361/500
7914/7914 [==============================] - 2s - loss: 0.1550 - acc: 0.9455     
Epoch 362/500
7914/7914 [==============================] - 2s - loss: 0.1417 - acc: 0.9532     
Epoch 363/500
7914/7914 [==============================] - 2s - loss: 0.1449 - acc: 0.9507     
Epoch 364/500
7914/7914 [==============================] - 2s - loss: 0.1316 - acc: 0.9548     
Epoch 365/500
7914/7914 [==============================] - 2s - loss: 0.1342 - acc: 0.9541     
Epoch 366/500
7914/7914 [==============================] - 2s - loss: 0.1476 - acc: 0.9493     
Epoch 367/500
7914/7914 [==============================] - 2s - loss: 0.1465 - acc: 0.9525     
Epoch 368/500
7914/7914 [==============================] - 2s - loss: 0.1390 - acc: 0.9516     
Epoch 369/500
7914/7914 [==============================] - 2s - loss: 0.1501 - acc: 0.9490     
Epoch 370/500
7914/7914 [==============================] - 2s - loss: 0.1487 - acc: 0.9488     
Epoch 371/500
7914/7914 [==============================] - 2s - loss: 0.1312 - acc: 0.9554     
Epoch 372/500
7914/7914 [==============================] - 2s - loss: 0.1384 - acc: 0.9521     
Epoch 373/500
7914/7914 [==============================] - 2s - loss: 0.1388 - acc: 0.9551     
Epoch 374/500
7914/7914 [==============================] - 2s - loss: 0.1363 - acc: 0.9529     
Epoch 375/500
7914/7914 [==============================] - 2s - loss: 0.1501 - acc: 0.9514     
Epoch 376/500
7914/7914 [==============================] - 2s - loss: 0.1427 - acc: 0.9502     
Epoch 377/500
7914/7914 [==============================] - 2s - loss: 0.1268 - acc: 0.9570     
Epoch 378/500
7914/7914 [==============================] - 2s - loss: 0.1330 - acc: 0.9529     
Epoch 379/500
7914/7914 [==============================] - 2s - loss: 0.1444 - acc: 0.9503     
Epoch 380/500
7914/7914 [==============================] - 2s - loss: 0.1508 - acc: 0.9487     
Epoch 381/500
7914/7914 [==============================] - 2s - loss: 0.1386 - acc: 0.9545     
Epoch 382/500
7914/7914 [==============================] - 2s - loss: 0.1395 - acc: 0.9510     
Epoch 383/500
7914/7914 [==============================] - 2s - loss: 0.1439 - acc: 0.9520     
Epoch 384/500
7914/7914 [==============================] - 2s - loss: 0.1508 - acc: 0.9463     
Epoch 385/500
7914/7914 [==============================] - 2s - loss: 0.1546 - acc: 0.9469     
Epoch 386/500
7914/7914 [==============================] - 2s - loss: 0.1598 - acc: 0.9454     
Epoch 387/500
7914/7914 [==============================] - 2s - loss: 0.1289 - acc: 0.9532     
Epoch 388/500
7914/7914 [==============================] - 2s - loss: 0.1541 - acc: 0.9466     
Epoch 389/500
7914/7914 [==============================] - 2s - loss: 0.1426 - acc: 0.9530     
Epoch 390/500
7914/7914 [==============================] - 2s - loss: 0.1543 - acc: 0.9449     
Epoch 391/500
7914/7914 [==============================] - 2s - loss: 0.1401 - acc: 0.9520     
Epoch 392/500
7914/7914 [==============================] - 2s - loss: 0.1290 - acc: 0.9567     
Epoch 393/500
7914/7914 [==============================] - 2s - loss: 0.1389 - acc: 0.9524     
Epoch 394/500
7914/7914 [==============================] - 2s - loss: 0.1472 - acc: 0.9488     
Epoch 395/500
7914/7914 [==============================] - 2s - loss: 0.1352 - acc: 0.9551     
Epoch 396/500
7914/7914 [==============================] - 2s - loss: 0.1431 - acc: 0.9531     
Epoch 397/500
7914/7914 [==============================] - 2s - loss: 0.1515 - acc: 0.9522     
Epoch 398/500
7914/7914 [==============================] - 2s - loss: 0.1472 - acc: 0.9535     
Epoch 399/500
7914/7914 [==============================] - 2s - loss: 0.1505 - acc: 0.9500     
Epoch 400/500
7914/7914 [==============================] - 2s - loss: 0.1441 - acc: 0.9539     
Epoch 401/500
7914/7914 [==============================] - 2s - loss: 0.1455 - acc: 0.9511     
Epoch 402/500
7914/7914 [==============================] - 2s - loss: 0.1357 - acc: 0.9556     
Epoch 403/500
7914/7914 [==============================] - 2s - loss: 0.1404 - acc: 0.9541     
Epoch 404/500
7914/7914 [==============================] - 2s - loss: 0.1272 - acc: 0.9567     
Epoch 405/500
7914/7914 [==============================] - 2s - loss: 0.1318 - acc: 0.9573     
Epoch 406/500
7914/7914 [==============================] - 2s - loss: 0.1360 - acc: 0.9482     
Epoch 407/500
7914/7914 [==============================] - 2s - loss: 0.1345 - acc: 0.9543     
Epoch 408/500
7914/7914 [==============================] - 2s - loss: 0.1357 - acc: 0.9558     
Epoch 409/500
7914/7914 [==============================] - 2s - loss: 0.1453 - acc: 0.9517     
Epoch 410/500
7914/7914 [==============================] - 2s - loss: 0.1456 - acc: 0.9493     
Epoch 411/500
7914/7914 [==============================] - 2s - loss: 0.1493 - acc: 0.9508     
Epoch 412/500
7914/7914 [==============================] - 2s - loss: 0.1473 - acc: 0.9512     
Epoch 413/500
7914/7914 [==============================] - 2s - loss: 0.1343 - acc: 0.9569     
Epoch 414/500
7914/7914 [==============================] - 2s - loss: 0.1434 - acc: 0.9516     
Epoch 415/500
7914/7914 [==============================] - 2s - loss: 0.1414 - acc: 0.9506     
Epoch 416/500
7914/7914 [==============================] - 2s - loss: 0.1230 - acc: 0.9598     
Epoch 417/500
7914/7914 [==============================] - 2s - loss: 0.1241 - acc: 0.9568     
Epoch 418/500
7914/7914 [==============================] - 2s - loss: 0.1400 - acc: 0.9535     
Epoch 419/500
7914/7914 [==============================] - 2s - loss: 0.1218 - acc: 0.9580     
Epoch 420/500
7914/7914 [==============================] - 2s - loss: 0.1205 - acc: 0.9579     
Epoch 421/500
7914/7914 [==============================] - 2s - loss: 0.1528 - acc: 0.9484     
Epoch 422/500
7914/7914 [==============================] - 2s - loss: 0.1363 - acc: 0.9562     
Epoch 423/500
7914/7914 [==============================] - 2s - loss: 0.1403 - acc: 0.9556     
Epoch 424/500
7914/7914 [==============================] - 2s - loss: 0.1512 - acc: 0.9488     
Epoch 425/500
7914/7914 [==============================] - 2s - loss: 0.1333 - acc: 0.9524     
Epoch 426/500
7914/7914 [==============================] - 2s - loss: 0.1380 - acc: 0.9539     
Epoch 427/500
7914/7914 [==============================] - 2s - loss: 0.1397 - acc: 0.9548     
Epoch 428/500
7914/7914 [==============================] - 2s - loss: 0.1347 - acc: 0.9539     
Epoch 429/500
7914/7914 [==============================] - 2s - loss: 0.1302 - acc: 0.9567     
Epoch 430/500
7914/7914 [==============================] - 2s - loss: 0.1469 - acc: 0.9491     
Epoch 431/500
7914/7914 [==============================] - 2s - loss: 0.1288 - acc: 0.9559     
Epoch 432/500
7914/7914 [==============================] - 2s - loss: 0.1469 - acc: 0.9527     
Epoch 433/500
7914/7914 [==============================] - 2s - loss: 0.1296 - acc: 0.9546     
Epoch 434/500
7914/7914 [==============================] - 2s - loss: 0.1299 - acc: 0.9549     
Epoch 435/500
7914/7914 [==============================] - 2s - loss: 0.1318 - acc: 0.9553     
Epoch 436/500
7914/7914 [==============================] - 2s - loss: 0.1464 - acc: 0.9526     
Epoch 437/500
7914/7914 [==============================] - 2s - loss: 0.1152 - acc: 0.9606     
Epoch 438/500
7914/7914 [==============================] - 2s - loss: 0.1290 - acc: 0.9563     
Epoch 439/500
7914/7914 [==============================] - 2s - loss: 0.1305 - acc: 0.9584     
Epoch 440/500
7914/7914 [==============================] - 2s - loss: 0.1359 - acc: 0.9550     
Epoch 441/500
7914/7914 [==============================] - 2s - loss: 0.1221 - acc: 0.9593     
Epoch 442/500
7914/7914 [==============================] - 2s - loss: 0.1356 - acc: 0.9536     
Epoch 443/500
7914/7914 [==============================] - 2s - loss: 0.1307 - acc: 0.9551     
Epoch 444/500
7914/7914 [==============================] - 2s - loss: 0.1445 - acc: 0.9497     
Epoch 445/500
7914/7914 [==============================] - 2s - loss: 0.1280 - acc: 0.9568     
Epoch 446/500
7914/7914 [==============================] - 2s - loss: 0.1328 - acc: 0.9555     
Epoch 447/500
7914/7914 [==============================] - 2s - loss: 0.1345 - acc: 0.9572     
Epoch 448/500
7914/7914 [==============================] - 2s - loss: 0.1194 - acc: 0.9584     
Epoch 449/500
7914/7914 [==============================] - 2s - loss: 0.1245 - acc: 0.9580     
Epoch 450/500
7914/7914 [==============================] - 2s - loss: 0.1346 - acc: 0.9572     
Epoch 451/500
7914/7914 [==============================] - 2s - loss: 0.1332 - acc: 0.9559     
Epoch 452/500
7914/7914 [==============================] - 2s - loss: 0.1331 - acc: 0.9577     
Epoch 453/500
7914/7914 [==============================] - 2s - loss: 0.1298 - acc: 0.9569     
Epoch 454/500
7914/7914 [==============================] - 2s - loss: 0.1308 - acc: 0.9568     
Epoch 455/500
7914/7914 [==============================] - 2s - loss: 0.1511 - acc: 0.9512     
Epoch 456/500
7914/7914 [==============================] - 2s - loss: 0.1307 - acc: 0.9592     
Epoch 457/500
7914/7914 [==============================] - 2s - loss: 0.1352 - acc: 0.9558     
Epoch 458/500
7914/7914 [==============================] - 2s - loss: 0.1206 - acc: 0.9625     
Epoch 459/500
7914/7914 [==============================] - 2s - loss: 0.1382 - acc: 0.9538     
Epoch 460/500
7914/7914 [==============================] - 2s - loss: 0.1453 - acc: 0.9564     
Epoch 461/500
7914/7914 [==============================] - 2s - loss: 0.1302 - acc: 0.9555     
Epoch 462/500
7914/7914 [==============================] - 2s - loss: 0.1224 - acc: 0.9591     
Epoch 463/500
7914/7914 [==============================] - 2s - loss: 0.1318 - acc: 0.9565     
Epoch 464/500
7914/7914 [==============================] - 2s - loss: 0.1385 - acc: 0.9531     
Epoch 465/500
7914/7914 [==============================] - 2s - loss: 0.1156 - acc: 0.9613     
Epoch 466/500
7914/7914 [==============================] - 2s - loss: 0.1327 - acc: 0.9572     
Epoch 467/500
7914/7914 [==============================] - 2s - loss: 0.1328 - acc: 0.9551     
Epoch 468/500
7914/7914 [==============================] - 2s - loss: 0.1329 - acc: 0.9540     
Epoch 469/500
7914/7914 [==============================] - 2s - loss: 0.1262 - acc: 0.9575     
Epoch 470/500
7914/7914 [==============================] - 2s - loss: 0.1354 - acc: 0.9555     
Epoch 471/500
7914/7914 [==============================] - 2s - loss: 0.1329 - acc: 0.9558     
Epoch 472/500
7914/7914 [==============================] - 2s - loss: 0.1279 - acc: 0.9594     
Epoch 473/500
7914/7914 [==============================] - 2s - loss: 0.1309 - acc: 0.9580     
Epoch 474/500
7914/7914 [==============================] - 2s - loss: 0.1272 - acc: 0.9559     
Epoch 475/500
7914/7914 [==============================] - 2s - loss: 0.1234 - acc: 0.9598     
Epoch 476/500
7914/7914 [==============================] - 2s - loss: 0.1361 - acc: 0.9578     
Epoch 477/500
7914/7914 [==============================] - 2s - loss: 0.1447 - acc: 0.9560     
Epoch 478/500
7914/7914 [==============================] - 2s - loss: 0.1226 - acc: 0.9606     
Epoch 479/500
7914/7914 [==============================] - 2s - loss: 0.1328 - acc: 0.9584     
Epoch 480/500
7914/7914 [==============================] - 2s - loss: 0.1249 - acc: 0.9606     
Epoch 481/500
7914/7914 [==============================] - 2s - loss: 0.1241 - acc: 0.9573     
Epoch 482/500
7914/7914 [==============================] - 2s - loss: 0.1323 - acc: 0.9544     
Epoch 483/500
7914/7914 [==============================] - 2s - loss: 0.1252 - acc: 0.9592     
Epoch 484/500
7914/7914 [==============================] - 2s - loss: 0.1182 - acc: 0.9594     
Epoch 485/500
7914/7914 [==============================] - 2s - loss: 0.1169 - acc: 0.9586     
Epoch 486/500
7914/7914 [==============================] - 2s - loss: 0.1265 - acc: 0.9583     
Epoch 487/500
7914/7914 [==============================] - 2s - loss: 0.1152 - acc: 0.9611     
Epoch 488/500
7914/7914 [==============================] - 2s - loss: 0.1289 - acc: 0.9573     
Epoch 489/500
7914/7914 [==============================] - 2s - loss: 0.1342 - acc: 0.9555     
Epoch 490/500
7914/7914 [==============================] - 2s - loss: 0.1420 - acc: 0.9539     
Epoch 491/500
7914/7914 [==============================] - 2s - loss: 0.1135 - acc: 0.9616     
Epoch 492/500
7914/7914 [==============================] - 2s - loss: 0.1150 - acc: 0.9618     
Epoch 493/500
7914/7914 [==============================] - 2s - loss: 0.1278 - acc: 0.9591     
Epoch 494/500
7914/7914 [==============================] - 2s - loss: 0.1561 - acc: 0.9471     
Epoch 495/500
7914/7914 [==============================] - 2s - loss: 0.1342 - acc: 0.9545     
Epoch 496/500
7914/7914 [==============================] - 2s - loss: 0.1347 - acc: 0.9570     
Epoch 497/500
7914/7914 [==============================] - 2s - loss: 0.1327 - acc: 0.9539     
Epoch 498/500
7914/7914 [==============================] - 2s - loss: 0.1175 - acc: 0.9627     
Epoch 499/500
7914/7914 [==============================] - 2s - loss: 0.1177 - acc: 0.9610     
Epoch 500/500
7914/7914 [==============================] - 2s - loss: 0.1220 - acc: 0.9618     
Out[11]:
<keras.callbacks.History at 0x7f37bf49ef98>
time: 19min 47s
In [12]:
# show the accuracy on the testing set
print("[INFO] evaluating on testing set...")
(loss, accuracy) = model.evaluate(testData, testLabels,
    batch_size=64, verbose=1)
print("[INFO] loss={:.4f}, accuracy: {:.4f}%".format(loss,
    accuracy * 100))
[INFO] evaluating on testing set...
1600/1662 [===========================>..] - ETA: 0s[INFO] loss=0.5387, accuracy: 81.5283%
time: 307 ms

Results

In [10]:
from matplotlib import pyplot as plt
from PIL import Image
import skimage.io as io
time: 1.07 s
In [11]:
# get predictions for each test image

imagePaths = list(paths.list_images("data/test"))
test_preds = []

for i in range(0, len(imagePaths)):
    
    # classify the digit
    probs = model.predict(testData[np.newaxis, i])
    preds = [round(i*100,5) for i in probs[0]]
    # record actual breed
    if testLabels[i][0]==1.0:
        actual='Beagle'
    elif testLabels[i][1]==1.0:
        actual='Boston'
    else:
        actual='Boxer'
    test_preds.append([imagePaths[i],preds[0],preds[1],preds[2],actual])
    
# Boston: n02096585 = 1
# Beagle: n02088364 = 0
# Boxer:  n02108089 = 2
time: 5.12 s
In [12]:
import pandas as pd

test_preds = pd.DataFrame(test_preds,columns=['Img','Beagle','Boston','Boxer','Actual'])

# determine breed with highest probability
test_preds['max']=''

for i in range(0,len(test_preds)):
    a,b,c = test_preds[['Beagle','Boston','Boxer']].ix[i]
    if (a>b) & (a>c):
        test_preds['max'].ix[i]='Beagle'
    elif b>c:
        test_preds['max'].ix[i]='Boston'
    else:
        test_preds['max'].ix[i]='Boxer'
time: 1min 58s
In [13]:
# count true and false positives

TP_Boxer = 0
TP_Beagle = 0
TP_Boston = 0

FP_Boxer = 0
FP_Beagle = 0
FP_Boston = 0

for i in range(0,len(test_preds)):
    if (test_preds['max'].ix[i]=='Boxer'):
        if (test_preds.Actual.ix[i]=='Boxer'):
            TP_Boxer+=1
        else:
            FP_Boxer+=1
    if (test_preds['max'].ix[i]=='Beagle'):
        if (test_preds.Actual.ix[i]=='Beagle'):
            TP_Beagle+=1
        else:
            FP_Beagle+=1
    if (test_preds['max'].ix[i]=='Boston'):
        if (test_preds.Actual.ix[i]=='Boston'):
            TP_Boston+=1
        else:
            FP_Boston+=1
time: 257 ms
In [14]:
print('True, False Positives by Breed:')
print('Boxer', (TP_Boxer, FP_Boxer))
print('Beagle', (TP_Beagle, FP_Beagle))
print('Boston', (TP_Boston, FP_Boston))
True, False Positives by Breed:
Boxer (463, 108)
Beagle (436, 63)
Boston (456, 136)
time: 2.89 ms
In [15]:
total = len(testData)
from sklearn.metrics import confusion_matrix, classification_report

true_labels = le.fit_transform(testFolders)
predicted_labels = [0 if dog=='Beagle' else 1 if dog=='Boston' else 2 for dog in test_preds['max'].tolist()]

cm = confusion_matrix(true_labels, predicted_labels, labels=[0,1,2])
cm = pd.DataFrame(cm,columns=['Beagle','Boston','Boxer'],index=['Predicted Beagle','Predicted Boston','Predicted Boxer'])


print("Classification Report")
print(classification_report(true_labels, predicted_labels))
print()
print("Confusion Matrix")
cm
Classification Report
             precision    recall  f1-score   support

          0       0.87      0.77      0.82       567
          1       0.77      0.92      0.84       496
          2       0.81      0.77      0.79       599

avg / total       0.82      0.82      0.81      1662


Confusion Matrix
Out[15]:
Beagle Boston Boxer
Predicted Beagle 436 51 80
Predicted Boston 12 456 28
Predicted Boxer 51 85 463
time: 23.9 ms
In [16]:
def plots(ims, figsize=(12,6), rows=1, interp=False, titles=None):
    if type(ims[0]) is np.ndarray:
        ims = np.array(ims).astype(np.uint8)
        if (ims.shape[-1] != 3):
            ims = ims.transpose((0,2,3,1))
    f = plt.figure(figsize=figsize)
    for i in range(len(ims)):
        sp = f.add_subplot(rows, len(ims)//rows, i+1)
        sp.axis('Off')
        if titles is not None:
            sp.set_title(titles[i], fontsize=16)
        plt.imshow(ims[i], interpolation=None if interp else 'none')
time: 7.29 ms
In [48]:
%matplotlib inline
from keras.preprocessing import image


f = plt.figure(figsize=(30,90))
rows = 5


path = 'data/test/'


imgs= []
test_summary =[]
pics = np.random.choice(range(len(testData)),20)

for i,j in enumerate(pics):
    sp = f.add_subplot(rows, len(testData)//rows, i+1)
    sp.axis('Off')

    # classify the digit
    probs = model.predict(testData[np.newaxis, i])
    picJPEG = path+testFiles[j][0:9]+'/'+testFiles[j]+'.JPEG'
    picjpeg = path+testFiles[j][0:9]+'/'+testFiles[j]+'.jpeg'
    try:
        image = io.imread(picJPEG)
    except:
        image = io.imread(picjpeg)
    preds = [round(i*100,2) for i in probs[0]]
    test_summary.append([testFiles[j],preds[0],preds[1],preds[2]])

        f.tight_layout(pad=0.1)
    
    im = cv2.resize(image, (200,200))
    imgs.append(im)

test_summary = pd.DataFrame(test_summary,columns=['File','Beagle','Boston','Boxer'])
time: 5.47 s
In [52]:
# determine breed with highest probability
test_summary['max']=''

for i in range(0,len(test_summary)):
    a,b,c = test_summary[['Beagle','Boston','Boxer']].ix[i]
    if (a>b) & (a>c):
        test_summary['max'].ix[i]='Beagle'
    elif b>c:
        test_summary['max'].ix[i]='Boston'
    else:
        test_summary['max'].ix[i]='Boxer'
time: 2.21 s

Look at the predicted breeds for some of the test images

In [53]:
plots(imgs,figsize=(16,16), titles=test_summary['max'], rows=5)
time: 2.45 s

Final Test: Boomer

In [39]:
## test ##
imagePaths = list(paths.list_images("Boomer"))
boomerData = []
boomerFiles = []
# testLabels = []
for (i, imagePath) in enumerate(imagePaths):
    image = cv2.imread(imagePath)
    image = cv2.resize(image, (32,32))
    boomerData.append(image)
    boomerFiles.append(imagePath)
    if i > 0 and i % 10 == 0:
        print("[INFO] processed {}/{}".format(i, len(imagePaths)))

boomerData = np.array(boomerData) / 255.0
print("[INFO] image processing complete")
[INFO] processed 10/32
[INFO] processed 20/32
[INFO] processed 30/32
[INFO] image processing complete
time: 6.63 s
In [71]:
%matplotlib inline
boomer = []

i = 0
for boom in boomerData:
    # classify the digit
    probs = model.predict(boomerData[np.newaxis, i])    
    image = io.imread(boomerFiles[i])
    preds = [round(i*100,5) for i in probs[0]]
    boomer.append([boomerFiles[i],preds[0],preds[1],preds[2]])
    i+=1
rows = 8
boomer = pd.DataFrame(boomer,columns=['File','Beagle','Boston','Boxer'])
time: 8.13 s
In [105]:
f = plt.figure(figsize=(30,90))
rows = 16
for i in range(len(boomerData)):
        sp = f.add_subplot(rows, len(boomerData)//rows, i+1)
        sp.axis('Off')

        sp.set_title("Beagle = {}\\Boston = {}\\Boxer = {}".format(round(boomer.Beagle.ix[i],2), round(boomer.Boston.ix[i],2), round(boomer.Boxer.ix[i],2)), fontsize=16)
        f.tight_layout(pad=0.1)
#         plt.figure(figsize=(8,8))

        im = cv2.imread(boomerFiles[i])
        im = cv2.resize(im, (200,200))


        plt.imshow(im)
    
# Beagle: n02088364 = 0    
# Boston: n02096585 = 1
# Boxer:  n02108089 = 2
time: 19.3 s
In [103]:
import pandas as pd

# determine the breed with the highest probability
boomer['max']=''

for i in range(0,len(boomer)):
    a,b,c = boomer[['Beagle','Boston','Boxer']].ix[i]
    if (a>b) & (a>c):
        boomer['max'].ix[i]='Beagle'
    elif b>c:
        boomer['max'].ix[i]='Boston'
    else:
        boomer['max'].ix[i]='Boxer'
time: 5.61 s
In [104]:
boomer['max'].groupby(boomer['max']).count()
Out[104]:
max
Beagle     1
Boston    13
Boxer     18
Name: max, dtype: int64
time: 5.54 ms

Evaluation:

I'm not very satisfied by my model, considering I have a biased opinion that Boomer is most definitely part Beagle. He has the same floppy ears and white tipped tail! I might have to do some thorough examination of the Beagle training photos to ensure that enough images show the ears and tail.

Sorry Boomer; still don't know what breed your dad was.

In [ ]: