import graphlab 
images = graphlab.SFrame('https://static.turi.com/datasets/caltech_101/caltech_101_images')

"""
Explanation: Similar Image Search Using Deep Learning on Caltech-101
In this notebook, we will walk you through adapting a neural network trained on the ImageNet Challenge to find similar images within the Caltech-101 dataset. At the end of the notebook, we will be able to alogithmically identify images that are visually similar to each other within the Caltech-101 dataset.
The notebook has several parts:


Part I focuses on loading the data.


Part II focuses on using a pre-trained neural net to extract visual features. 


Part III focuses on using the extracted visual features to train a nearest neighbors model. 


Part I: The Data
In this notebook, we use the Caltech-101 dataset. Caltech-101 contains photos of objects belonging to 101 categories. Note: This is a large dataset, so it may take a while to download.It was collected by Fei-Fei Li, Marco Andreetto, and Marc 'Aurelio Ranzato in September 2003.
End of explanation
"""


# Only do this if you have a GPU
#pretrained_model = graphlab.load_model('https://static.turi.com/models/imagenet_model_iter45')
#images['extracted_features'] = pretrained_model.extract_features(images)

# If you do not have a GPU, do this instead. 
images['extracted_features'] = graphlab.SArray('https://static.turi.com/models/pre_extracted_features.gl')


"""
Explanation: Part II: Extracting Features
We use the neural network trained on the 1.2 million images of the ImageNet Challenge. For each image of the Caltech-101 dataset, we take the activations of the layer before the classification layer and consider that our feature vector for the image. This is a sort of internal representation of what the network knows about the image. If these feature vectors are similar for two images, then the images should be similar as well. This concept is covered more thoroughly in our blog post on the subject. Note that feature exctraction will not be feasible without a GPU and the GPU installation. In that case, you should download the SArray that contains the result of this step.
End of explanation
"""


images

"""
Explanation: Now, let's inspect the images SFrame. The 'extracted_features' column contains  vector representations of the data, as we expected it to.
End of explanation
"""


nearest_neighbor_model = graphlab.nearest_neighbors.create(images, features=['extracted_features'])

similar_images = nearest_neighbor_model.query(images, k = 2)

"""
Explanation: Part III: Finding similar images via Nearest Neighbors on Extracted Features
Knowing that similar extracted features should mean visually similar images, we can do a similar image search simply by finding an images nearest neighbors in the feature space. We demonstrate this below. 
First, we construct the nearest neighbors model on the extracted features. This will allow us to see each image's closest neighbor
End of explanation
"""


similar_images

"""
Explanation: similar_images is an SFrame which contains a query label, and it's neighbor, the reference label
End of explanation
"""


similar_images = similar_images[similar_images['query_label'] != similar_images['reference_label']]

similar_images

"""
Explanation: We do some cleaning to remove the instances where the query equals the reference. This happened beacause the query set was identical to the reference set
End of explanation
"""


graphlab.canvas.set_target('ipynb')
graphlab.SArray([images['image'][9]]).show()

graphlab.SArray([images['image'][1710]]).show()

"""
Explanation: Now we can explore similar images. For instance, the closest image to image 9 is image 1710. We can view and see both are starfish
End of explanation
"""


graphlab.SArray([images['image'][0]]).show()

graphlab.SArray([images['image'][1535]]).show()

"""
Explanation: Similarly, images 0 and 1535 are two similar photos of the same person
End of explanation
"""


