Image Classification
Want to run this code for yourself?
You can find the interactive ipython notebook where you can run all the steps listed here at
PS: it will take a couple of minutes for the mybinder instance to boot up and be ready for use.
import json
import os
import requests
Util Methods for interacting with Nanonets API.
# Helper methods for creating, uploading data and training an object detection model.
def create_new_model(base_url, auth_key, categories):
    """
    function to create a new model for training
    
    Args:
    base_url: url to nanonets endpoint which will decide what type of model to create
    auth_key: authentication key provided by https://app.nanonets.com/#/keys
    categories: List of classes you want to identify
    
    return:
    model_id: a unique reference to new created model
    """
    headers = {
        'accept': 'application/x-www-form-urlencoded'
    }
    data = {'categories' : categories}
    response = requests.request(
        "POST",
        "%s%s" % (base_url, "Model/") ,
        headers=headers,
        auth=requests.auth.HTTPBasicAuth(auth_key, ''),
        data=data,
    )
    result = json.loads(response.text)
    print("Model Information: ", result)
    model_id, model_type, categories = (result["model_id"], result["model_type"], result["categories"])
    return model_id
def get_model_info(base_url, auth_key, model_id):
    """
    function to get/ print information about model at any time
    
    Args:
    base_url: url to nanonets endpoint which will decide what type of model to create
    auth_key: authentication key provided by https://app.nanonets.com/#/keys
    model_id: unique model_id generated at model creation time
    """
    response = requests.request(
        'GET',
        '%s%s' % (base_url, "Model/"),
        auth=requests.auth.HTTPBasicAuth(auth_key,''),
        params={'modelId': model_id},
    )
    print(response.text)
    result = json.loads(response.text)
    model_id, model_type, categories, state = (result["model_id"], result["model_type"], result["categories"], result["state"])
    return model_id, model_type, categories, state
def upload_local_data(base_url, auth_key, image_file, category, model_id):
    """
    function to upload local images to a model that has been created.
    
    Args:
    base_url[str]: nanonets endpoint to which the model upload request will be sent
        eg. https://app.nanonets.com/api/v2/ImageCategorization
    auth_key[str]: authentication key provided by https://app.nanonets.com/#/keys
    image_file[str]: full path to where the image is located
    category[str]: class label to which this image belongs to
    model_id[str]: model id for which data needs to be uploaded
    """
    data = {
        'file': open(image_file, 'rb'),
        'category': ('', category),
        'modelId': ('', '%s' % model_id),
    }
    response = requests.post(
        '%sUploadFile/'% (base_url),
        auth=requests.auth.HTTPBasicAuth(auth_key, ''),
        files=data,
    )
    print(response.text)
def upload_url_data(base_url, auth_key, image_urls, category, model_id):
    """
    function to upload images given by their urls to a model that has been created.
    The advantage of using URLs is that you can upload multiple images at the same time.
    
    Args:
    base_url[str]: nanonets endpoint to which the model upload request will be sent
        eg. https://app.nanonets.com/api/v2/ImageCategorization
    auth_key[str]: authentication key provided by https://app.nanonets.com/#/keys
    urls[List[str]]: list of urls that need to be uploaded for the corresponding category
    category[str]: class label to which this image belongs to
    model_id[str]: model id for which data needs to be uploaded
    """
    data = {
        'urls' : image_urls,
        'modelId' : model_id,
        'category': category,
    }
    headers = {
        'accept': 'application/x-www-form-urlencoded'
    }
    response = requests.post(
        '%sUploadUrls/'% (base_url),
        headers=headers,
        auth=requests.auth.HTTPBasicAuth(auth_key, ''),
        data=data,
    )
    print(response.text)
    
    
def train_model(base_url, auth_key, model_id):
    headers = {'authorization': 'Basic %s'%auth_key}
    querystring = {'modelId': model_id}
    response = requests.request(
        'POST',
        '%sTrain/'%(base_url),
        headers=headers,
        auth=requests.auth.HTTPBasicAuth(auth_key, ''),
        params=querystring,
    )
    print("training started .... ")
    print(json.loads(response.text))
Constants
Some basic constants for creating and launching training on Nanonets API
BASE_MODEL_URL = 'https://app.nanonets.com/api/v2/ImageCategorization/'
AUTH_KEY = "<AUTH_KEY_FROM_NANONETS_APP>" ## can be foung https://app.nanonets.com/#/keys
# you can provide more than 2 categories and train a multi class classification model as well.
CATEGORIES = ["dogs", "cats"]
model_id = create_new_model(BASE_MODEL_URL, auth_key=AUTH_KEY, categories=CATEGORIES)
Upload Data to newly created model
# # Upload data available on local machine
# # Useful when you have custom images which are not freely available on the web.
# from multiprocessing import Pool
# dog_path = "/Users/parvoberoi/Downloads/dogs/"
# cat_path = "/Users/parvoberoi/Downloads/cats/"
# dog_images = os.listdir(dog_path)
# cat_images = os.listdir(cat_path)
# # helper method for use with multiprocessing.map()
# def upload_local_image(image_info):
#     image_path, category, model_id = image_info
#     upload_local_data(BASE_MODEL_URL, AUTH_KEY, image_path, category, model_id)
    
# p = Pool(5)
# x = p.map(upload_local_image, [(os.path.join(dog_path, image_file), "dogs", model_id) for image_file in dog_images])
# y = p.map(upload_local_image, [(os.path.join(cat_path, image_file), "cats", model_id) for image_file in cat_images])
# Upload data by their URLs.
# Prefered way for generic images as it allows us to upload multiple images with one request.
base_github_url = "https://raw.githubusercontent.com/NanoNets/tutorials/master/image_classification/data/"
cat_urls = [
    os.path.join(base_github_url, "cats", "%d_cat.jpeg"%index) for index in range(1, 31)
]
upload_url_data(BASE_MODEL_URL, AUTH_KEY, cat_urls, "cats", model_id)
dog_urls = [
    os.path.join(base_github_url, "dogs", "%d_dog.jpeg"%index) for index in range(1, 31)
]
upload_url_data(BASE_MODEL_URL, AUTH_KEY, dog_urls, "dogs", model_id)
Check the model information and metadata
You can confirm whether atleast 25(minimum required to launch training) images per category have been uploaded or not.
get_model_info(BASE_MODEL_URL, AUTH_KEY, model_id)
Launch the Training Job on Nanonets Infrastructure.
train_model(BASE_MODEL_URL, AUTH_KEY, model_id)
