NN Item Category Prediction

Is resnet 50 doing a reasonable job at classifying these images?

  • loop through a set of images, predict and print out their resnet labels

In [3]:
import sys 
import os
sys.path.append(os.getcwd()+'/../')

# our lib
from lib.resnet50 import ResNet50
from lib.imagenet_utils import preprocess_input, decode_predictions

#keras 
from keras.preprocessing import image
from keras.models import Model

# sklearn
import sklearn
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import permutation_test_score

# other
import numpy as np
import glob
import pandas as pd
import ntpath

# plotting
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline


Using TensorFlow backend.

In [4]:
def preprocess_img(img_path):
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    return(x,img)

In [5]:
def perf_measure(y_actual, y_hat):
    TP = 0
    FP = 0
    TN = 0
    FN = 0

    for i in range(len(y_hat)): 
        if y_actual[i]==y_hat[i]==1:
           TP += 1
    for i in range(len(y_hat)): 
        if (y_hat[i]==1) and (y_actual[i]!=y_hat[i]):
           FP += 1
    for i in range(len(y_hat)): 
        if y_actual[i]==y_hat[i]==0:
           TN += 1
    for i in range(len(y_hat)): 
        if (y_hat[i]==0) and (y_actual[i]!=y_hat[i]):
           FN += 1

    return(TP, FP, TN, FN)

In [6]:
img_paths = glob.glob('../original_img/BAIYI*')
img_paths[0:3]


Out[6]:
['../original_img/BAIYI-B1008N289-5.jpg',
 '../original_img/BAIYI-B1008N299-5.jpg',
 '../original_img/BAIYI-B1010N356-5.jpg']

load baiyi brand


In [7]:
# instantiate model 
classifier_model = ResNet50(include_top=True, weights='imagenet') #this will pull the weights from the folder


/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:165: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (7, 7), strides=(2, 2), name="conv1")`
  x = Convolution2D(64, 7, 7, subsample=(2, 2), name='conv1')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:90: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (1, 1), strides=(1, 1), name="res2a_branch2a")`
  name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:95: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (3, 3), padding="same", name="res2a_branch2b")`
  name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:99: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1), name="res2a_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:103: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1), strides=(1, 1), name="res2a_branch1")`
  name=conv_name_base + '1')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:106: UserWarning: The `merge` function is deprecated and will be removed after 08/2017. Use instead layers from `keras.layers.merge`, e.g. `add`, `concatenate`, etc.
  x = merge([x, shortcut], mode='sum')
/Users/chris/anaconda/envs/virtenv/lib/python2.7/site-packages/keras/legacy/layers.py:456: UserWarning: The `Merge` layer is deprecated and will be removed after 08/2017. Use instead layers from `keras.layers.merge`, e.g. `add`, `concatenate`, etc.
  name=name)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (1, 1), name="res2b_branch2a")`
  x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:56: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (3, 3), padding="same", name="res2b_branch2b")`
  border_mode='same', name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:60: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1), name="res2b_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:63: UserWarning: The `merge` function is deprecated and will be removed after 08/2017. Use instead layers from `keras.layers.merge`, e.g. `add`, `concatenate`, etc.
  x = merge([x, input_tensor], mode='sum')
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (1, 1), name="res2c_branch2a")`
  x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:56: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(64, (3, 3), padding="same", name="res2c_branch2b")`
  border_mode='same', name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:60: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1), name="res2c_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:90: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (1, 1), strides=(2, 2), name="res3a_branch2a")`
  name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:95: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (3, 3), padding="same", name="res3a_branch2b")`
  name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:99: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (1, 1), name="res3a_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:103: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (1, 1), strides=(2, 2), name="res3a_branch1")`
  name=conv_name_base + '1')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (1, 1), name="res3b_branch2a")`
  x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:56: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (3, 3), padding="same", name="res3b_branch2b")`
  border_mode='same', name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:60: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (1, 1), name="res3b_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (1, 1), name="res3c_branch2a")`
  x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:56: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (3, 3), padding="same", name="res3c_branch2b")`
  border_mode='same', name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:60: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (1, 1), name="res3c_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (1, 1), name="res3d_branch2a")`
  x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:56: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(128, (3, 3), padding="same", name="res3d_branch2b")`
  border_mode='same', name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:60: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(512, (1, 1), name="res3d_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:90: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1), strides=(2, 2), name="res4a_branch2a")`
  name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:95: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (3, 3), padding="same", name="res4a_branch2b")`
  name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:99: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(1024, (1, 1), name="res4a_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:103: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(1024, (1, 1), strides=(2, 2), name="res4a_branch1")`
  name=conv_name_base + '1')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1), name="res4b_branch2a")`
  x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:56: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (3, 3), padding="same", name="res4b_branch2b")`
  border_mode='same', name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:60: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(1024, (1, 1), name="res4b_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1), name="res4c_branch2a")`
  x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:56: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (3, 3), padding="same", name="res4c_branch2b")`
  border_mode='same', name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:60: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(1024, (1, 1), name="res4c_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1), name="res4d_branch2a")`
  x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:56: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (3, 3), padding="same", name="res4d_branch2b")`
  border_mode='same', name=conv_name_base + '2b')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:60: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(1024, (1, 1), name="res4d_branch2c")`
  x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)
/Users/chris/Desktop/CDIPS_Recommender/notebooks/../lib/resnet50.py:51: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(256, (1, 1),
limit_output extension: Maximum message size of 10000 exceeded with 10596 characters

In [8]:
# predict labels 
list_of_listed_predictions = []
for img_path in img_paths:
    x,img = preprocess_img(img_path) # preprocess
    predictions = classifier_model.predict(x) # predict labels 
    decoded_predictions = decode_predictions(predictions)[0] # decode label
    decoded_predictions_less = [p[1:3] for p in decoded_predictions] # remove the first tag
    listed_predictions = ' \n '.join([str(x) for x in decoded_predictions_less]) # combine as a big string
    list_of_listed_predictions.append(listed_predictions)

In [9]:
list_of_listed_predictions[0:3]


Out[9]:
["(u'miniskirt', 0.50684178) \n (u'pajama', 0.38959837) \n (u'cowboy_boot', 0.029757397) \n (u'gown', 0.012776351) \n (u'overskirt', 0.0056670494)",
 "(u'miniskirt', 0.7834428) \n (u'cowboy_boot', 0.18969896) \n (u'sunglasses', 0.0030272522) \n (u'feather_boa', 0.0021650565) \n (u'suit', 0.0019254024)",
 "(u'miniskirt', 0.90721846) \n (u'velvet', 0.034521211) \n (u'overskirt', 0.026562247) \n (u'hoopskirt', 0.019950993) \n (u'fur_coat', 0.0015607165)"]

In [13]:
img_path


Out[13]:
'../original_img/BAIYI-B1061N026-5.jpg'

In [14]:
# create HTML file 
newfile = '../figures/ResNet_Category_Predictions.html'
with open(newfile, 'w') as outfile:
    outfile.write("<!DOCTYPE html><html><head><style>")
    outfile.write("table.app {border:1px solid #d4d4d4;}")
    
    # open table
    outfile.write("#circle {border-radius:50% 50% 50% 50%;}</style></head><body background-color: transparent;><table class='app'>")
    
    # write image #
    for i,img_path in enumerate(img_paths):
        outfile.write("<tr>")
        outfile.write("<td><img id='circle' src='" + img_path + "' style='height:150px; width:150px' /></td>")

        outfile.write("<td><p>"+list_of_listed_predictions[i]+"</p>")
        outfile.write("</tr>")
    
    # close table. 
    outfile.write("</table></body>")

In [15]:
%%bash 
jupyter nbconvert --to html Labeling_Pictures_with_ResNet50.ipynb && mv Labeling_Pictures_with_ResNet50.html ../notebook_htmls/Labeling_Pictures_with_ResNet50_v1.html


[NbConvertApp] Converting notebook Labeling_Pictures_with_ResNet50.ipynb to html
[NbConvertApp] Writing 280398 bytes to Labeling_Pictures_with_ResNet50.html