This script is for computing the performance of the network on our sketchy benchmark.


In [1]:
import numpy as np
from pylab import *
%matplotlib inline
import os
import sys

caffe

First, we need to import caffe. You'll need to have caffe installed, as well as python interface for caffe.


In [2]:
#TODO: specify your caffe root folder here
caffe_root = "X:\caffe_siggraph/caffe-windows-master"
sys.path.insert(0, caffe_root+'/python')
import caffe

Now we can load up the network. You can change the path to your own network here. Make sure to use the matching deploy prototxt files and change the target layer to your layer name.


In [35]:
#TODO: change to your own network and deploying file
PRETRAINED_FILE = '../models/triplet_googlenet/triplet_googlenet_finegrain_final.caffemodel' 
sketch_model = '../models/triplet_googlenet/googlenet_sketchdeploy.prototxt'
image_model = '../models/triplet_googlenet/googlenet_imagedeploy.prototxt'




In [36]:
caffe.set_mode_gpu()
#caffe.set_mode_cpu()
sketch_net = caffe.Net(sketch_model, PRETRAINED_FILE, caffe.TEST)
img_net = caffe.Net(image_model, PRETRAINED_FILE, caffe.TEST)
sketch_net.blobs.keys()


Out[36]:
['data',
 'conv1/7x7_s2_s',
 'pool1/3x3_s2_s',
 'pool1/norm1_s',
 'conv2/3x3_reduce_s',
 'conv2/3x3_s',
 'conv2/norm2_s',
 'pool2/3x3_s2_s',
 'pool2/3x3_s2_s_pool2/3x3_s2_s_0_split_0',
 'pool2/3x3_s2_s_pool2/3x3_s2_s_0_split_1',
 'pool2/3x3_s2_s_pool2/3x3_s2_s_0_split_2',
 'pool2/3x3_s2_s_pool2/3x3_s2_s_0_split_3',
 'inception_3a/1x1_s',
 'inception_3a/3x3_reduce_s',
 'inception_3a/3x3_s',
 'inception_3a/5x5_reduce_s',
 'inception_3a/5x5_s',
 'inception_3a/pool_s',
 'inception_3a/pool_proj_s',
 'inception_3a/output_s',
 'inception_3a/output_s_inception_3a/output_s_0_split_0',
 'inception_3a/output_s_inception_3a/output_s_0_split_1',
 'inception_3a/output_s_inception_3a/output_s_0_split_2',
 'inception_3a/output_s_inception_3a/output_s_0_split_3',
 'inception_3b/1x1_s',
 'inception_3b/3x3_reduce_s',
 'inception_3b/3x3_s',
 'inception_3b/5x5_reduce_s',
 'inception_3b/5x5_s',
 'inception_3b/pool_s',
 'inception_3b/pool_proj_s',
 'inception_3b/output_s',
 'pool3/3x3_s2_s',
 'pool3/3x3_s2_s_pool3/3x3_s2_s_0_split_0',
 'pool3/3x3_s2_s_pool3/3x3_s2_s_0_split_1',
 'pool3/3x3_s2_s_pool3/3x3_s2_s_0_split_2',
 'pool3/3x3_s2_s_pool3/3x3_s2_s_0_split_3',
 'inception_4a/1x1_s',
 'inception_4a/3x3_reduce_s',
 'inception_4a/3x3_s',
 'inception_4a/5x5_reduce_s',
 'inception_4a/5x5_s',
 'inception_4a/pool_s',
 'inception_4a/pool_proj_s',
 'inception_4a/output_s',
 'inception_4a/output_s_inception_4a/output_s_0_split_0',
 'inception_4a/output_s_inception_4a/output_s_0_split_1',
 'inception_4a/output_s_inception_4a/output_s_0_split_2',
 'inception_4a/output_s_inception_4a/output_s_0_split_3',
 'inception_4a/output_s_inception_4a/output_s_0_split_4',
 'loss1/ave_pool_s',
 'loss1/conv_s',
 'loss1/fc_s',
 'inception_4b/1x1_s',
 'inception_4b/3x3_reduce_s',
 'inception_4b/3x3_s',
 'inception_4b/5x5_reduce_s',
 'inception_4b/5x5_s',
 'inception_4b/pool_s',
 'inception_4b/pool_proj_s',
 'inception_4b/output_s',
 'inception_4b/output_s_inception_4b/output_s_0_split_0',
 'inception_4b/output_s_inception_4b/output_s_0_split_1',
 'inception_4b/output_s_inception_4b/output_s_0_split_2',
 'inception_4b/output_s_inception_4b/output_s_0_split_3',
 'inception_4c/1x1_s',
 'inception_4c/3x3_reduce_s',
 'inception_4c/3x3_s',
 'inception_4c/5x5_reduce_s',
 'inception_4c/5x5_s',
 'inception_4c/pool_s',
 'inception_4c/pool_proj_s',
 'inception_4c/output_s',
 'inception_4c/output_s_inception_4c/output_s_0_split_0',
 'inception_4c/output_s_inception_4c/output_s_0_split_1',
 'inception_4c/output_s_inception_4c/output_s_0_split_2',
 'inception_4c/output_s_inception_4c/output_s_0_split_3',
 'inception_4d/1x1_s',
 'inception_4d/3x3_reduce_s',
 'inception_4d/3x3_s',
 'inception_4d/5x5_reduce_s',
 'inception_4d/5x5_s',
 'inception_4d/pool_s',
 'inception_4d/pool_proj_s',
 'inception_4d/output_s',
 'inception_4d/output_s_inception_4d/output_s_0_split_0',
 'inception_4d/output_s_inception_4d/output_s_0_split_1',
 'inception_4d/output_s_inception_4d/output_s_0_split_2',
 'inception_4d/output_s_inception_4d/output_s_0_split_3',
 'inception_4d/output_s_inception_4d/output_s_0_split_4',
 'loss2/ave_pool_s',
 'loss2/conv_s',
 'loss2/fc_s',
 'inception_4e/1x1_s',
 'inception_4e/3x3_reduce_s',
 'inception_4e/3x3_s',
 'inception_4e/5x5_reduce_s',
 'inception_4e/5x5_s',
 'inception_4e/pool_s',
 'inception_4e/pool_proj_s',
 'inception_4e/output_s',
 'pool4/3x3_s2_s',
 'pool4/3x3_s2_s_pool4/3x3_s2_s_0_split_0',
 'pool4/3x3_s2_s_pool4/3x3_s2_s_0_split_1',
 'pool4/3x3_s2_s_pool4/3x3_s2_s_0_split_2',
 'pool4/3x3_s2_s_pool4/3x3_s2_s_0_split_3',
 'inception_5a/1x1_s',
 'inception_5a/3x3_reduce_s',
 'inception_5a/3x3_s',
 'inception_5a/5x5_reduce_s',
 'inception_5a/5x5_s',
 'inception_5a/pool_s',
 'inception_5a/pool_proj_s',
 'inception_5a/output_s',
 'inception_5a/output_s_inception_5a/output_s_0_split_0',
 'inception_5a/output_s_inception_5a/output_s_0_split_1',
 'inception_5a/output_s_inception_5a/output_s_0_split_2',
 'inception_5a/output_s_inception_5a/output_s_0_split_3',
 'inception_5b/1x1_s',
 'inception_5b/3x3_reduce_s',
 'inception_5b/3x3_s',
 'inception_5b/5x5_reduce_s',
 'inception_5b/5x5_s',
 'inception_5b/pool_s',
 'inception_5b/pool_proj_s',
 'inception_5b/output_s',
 'pool5/7x7_s1_s']

In [38]:
#TODO: set output layer name. You can use sketch_net.blobs.keys() to list all layer
output_layer_sketch = 'pool5/7x7_s1_s'
output_layer_image = 'pool5/7x7_s1_p'




In [12]:
#set the transformer
transformer = caffe.io.Transformer({'data': np.shape(sketch_net.blobs['data'].data)})
transformer.set_mean('data', np.array([104, 117, 123]))
transformer.set_transpose('data',(2,0,1))
transformer.set_channel_swap('data', (2,1,0))
transformer.set_raw_scale('data', 255.0)

Sketchy test set


In [24]:
#photo paths
photo_paths = 'C:\Users\Patsorn\Documents/notebook_backup/SBIR/photos/'
sketch_paths = 'C:\Users\Patsorn\Documents/notebook_backup/SBIR/sketches/'

In [15]:
#load up test images
with open('../list/test_img_list.txt','r') as my_file:
    test_img_list = [c.rstrip() for c in my_file.readlines()]

In [39]:
#extract feature for all test images
feats = []
N = np.shape(test_img_list)[0]
for i,path in enumerate(test_img_list):
    imgname = path.split('/')[-1]
    imgname = imgname.split('.jpg')[0]
    imgcat = path.split('/')[0]
    print '\r',str(i+1)+'/'+str(N)+ ' '+'Extracting ' +path+'...',
    full_path = photo_paths + path
    img = (transformer.preprocess('data', caffe.io.load_image(full_path.rstrip())))
    img_in = np.reshape([img],np.shape(sketch_net.blobs['data'].data))
    out_img = img_net.forward(data=img_in)
    out_img = np.copy(out_img[output_layer_image]) 
    feats.append(out_img)
    print 'done',
np.shape(feats)
feats = np.resize(feats,[np.shape(feats)[0],np.shape(feats)[2]])  #quick fixed for size


1250/1250 Extracting sailboat/n04128499_654.jpg... done

In [44]:
#build nn pool
from sklearn.neighbors import NearestNeighbors,LSHForest
nbrs  = NearestNeighbors(n_neighbors=np.size(feats,0), algorithm='brute',metric='cosine').fit(feats)

In [45]:
#compute score

num_query = 0
count_recall = [0]*1250
sum_rank = 0
sum_class_rank = [0]*125
count_recall_class = np.zeros((125,1250),np.float)
i_coco =-1
for i,img in enumerate(test_img_list):
    imgname = img.split('/')[-1]
    imgname = imgname.split('.jpg')[0]
    imgcat = img.split('/')[0]
    
    sketch_list = os.listdir(sketch_paths+imgcat)
    sketch_img_list = [skg for skg in sketch_list if skg.startswith(imgname+'-') and skg.endswith('-5.png')]#change this skg.endswith('-1.png') to the variation you want
    for sketch in sketch_img_list:
        sketch_path = sketch_paths + imgcat+'/' + sketch
        sketch_in = (transformer.preprocess('data', plt.imread(sketch_path)))
        sketch_in = np.reshape([sketch_in],np.shape(sketch_net.blobs['data'].data))
        query = sketch_net.forward(data=sketch_in)
        query=np.copy(query[output_layer_sketch])
        distances, indices = nbrs.kneighbors(np.reshape(query,[np.shape(query)[1]]))
        num_query = num_query+1
        print '\r','...'+sketch+'...',

        for j,indice in enumerate(indices[0]):
            if indice==i:
                #this j is the right one.
                count_recall[j] = count_recall[j]+1
                print '\r','ranking: '+imgcat+ ' '+sketch  + ' found at '  +str(j),
                break
                
cum_count = [0]*1250
sumc = 0
for i,c in enumerate(count_recall):
    sumc = sumc + c
    cum_count[i] = sumc
print '\nRecall @K=1 = ', 1.00*cum_count[0]/cum_count[-1]


ranking: sailboat n04128499_654-5-5.png found at 0 
Recall @K=1 =  0.371039290241