DevCon Demo

In [1]:
import os
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

from skimage import io



caffe_root = '/home/ubuntu/caffe/' 
import sys
sys.path.insert(0, caffe_root + 'python')
sys.path.append('/usr/local/lib/python2.7/dist-packages/')

import caffe
import dlib

plt.rcParams['figure.figsize'] = (10, 10)
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
/home/ubuntu/caffe/python/caffe/pycaffe.py:13: RuntimeWarning: to-Python converter for boost::shared_ptr<caffe::Net<float> > already registered; second conversion method ignored.
  from ._caffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, \
/home/ubuntu/caffe/python/caffe/pycaffe.py:13: RuntimeWarning: to-Python converter for boost::shared_ptr<caffe::Blob<float> > already registered; second conversion method ignored.
  from ._caffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, \
/home/ubuntu/caffe/python/caffe/pycaffe.py:13: RuntimeWarning: to-Python converter for boost::shared_ptr<caffe::Solver<float> > already registered; second conversion method ignored.
  from ._caffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, \

Loading the mean image

In [2]:
mean_filename='./age_gender_mean.binaryproto'
proto_data = open(mean_filename, "rb").read()
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)
mean  = caffe.io.blobproto_to_array(a)[0]

Loading the age network

In [3]:
age_net_pretrained='./age_net.caffemodel'
age_net_model_file='./deploy_age.prototxt'
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))

Loading the gender network

In [4]:
gender_net_pretrained='./gender_net.caffemodel'
gender_net_model_file='./deploy_gender.prototxt'
gender_net = caffe.Classifier(gender_net_model_file, gender_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))

Loading the emotions network

In [5]:
mean_filename='./emotions_mean.binaryproto'
proto_data = open(mean_filename, "rb").read()
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)
mean  = caffe.io.blobproto_to_array(a)[0]

emotions_net_pretrained='./emotions_net.caffemodel'
emotions_net_model_file='./deploy_emotions.prototxt'
emotions_net = caffe.Classifier(emotions_net_model_file, emotions_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))

Labels

In [6]:
age_list=['(0, 2)','(4, 6)','(8, 12)','(15, 20)','(25, 32)','(38, 43)','(48, 53)','(60, 100)']
gender_list=['Male','Female']
emotions_list = [ 'Angry' , 'Disgust' , 'Fear' , 'Happy'  , 'Neutral' ,  'Sad' , 'Surprise']

Reading and plotting the input image

In [7]:
example_image = './uri2.jpg'
input_image = caffe.io.load_image(example_image)
_ = plt.imshow(input_image)
In [8]:
detector = dlib.get_frontal_face_detector()
img = io.imread(example_image)
faces = detector(img)
In [9]:
cropped_face = input_image[faces[0].left():faces[0].right(),faces[0].top():faces[0].bottom(),:]
cropped_face_big = input_image[faces[0].left()-30:faces[0].right() + 30,faces[0].top()-30:faces[0].bottom()+30,:]
In [10]:
plt.imshow(cropped_face_big)
Out[10]:
<matplotlib.image.AxesImage at 0x7f2acd4eb9d0>

Age prediction

In [11]:
prediction = age_net.predict([cropped_face_big]) 

print 'predicted age:', age_list[prediction[0].argmax()]
predicted age: (38, 43)

Gender prediction

In [12]:
prediction = gender_net.predict([cropped_face_big]) 

print 'predicted gender:', gender_list[prediction[0].argmax()]
predicted gender: Male

Emotion prediction

In [13]:
prediction = emotions_net.predict([cropped_face],oversample=True)
print 'predicted emotion is {0}'.format(emotions_list[prediction.argmax()])
predicted emotion is Happy

Filters visualizations

Based on a similar notebook by Caffe's authors.

In [14]:
def showimage(im):
    if im.ndim == 3:
        im = im[:, :, ::-1]
    plt.set_cmap('jet')
    plt.imshow(im)
    

def vis_square(data, padsize=1, padval=0):
    data -= data.min()
    data /= data.max()
    
    # force the number of filters to be square
    n = int(np.ceil(np.sqrt(data.shape[0])))
    padding = ((0, n ** 2 - data.shape[0]), (0, padsize), (0, padsize)) + ((0, 0),) * (data.ndim - 3)
    data = np.pad(data, padding, mode='constant', constant_values=(padval, padval))
    
    # tile the filters into an image
    data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))
    data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])
    
    showimage(data)
In [15]:
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))

prediction = age_net.predict([cropped_face_big]) 

Input image

In [16]:
_ = plt.imshow(cropped_face_big)

The first conv layer filters, conv1

Notice some filters resemble edge detector filters

In [17]:
filters = age_net.params['conv1'][0].data[:49]
vis_square(filters.transpose(0, 2, 3, 1))

The first Conv layer output, conv1 (rectified responses of the filters above)

Notice the response of specific filters, e.g. the onese that resemble edge detectors

In [18]:
feat = age_net.blobs['conv1'].data[0][ :49]
vis_square(feat, padval=1)
In [ ]: