Nanonets

Nanonets

  • Docs
  • API
  • Help
  • Blog

›Tutorials

Tutorials

  • Image Classification
  • Object Detection

FAQs

  • Annotation Best Practices for Object Detection
  • Data Collection Best Practices
  • Adding categories to OCR models

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

https://mybinder.org/v2/gh/NanoNets/tutorials/master?filepath=image_classification/notebooks/image_classification.ipynb

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)

Object Detection →
  • Want to run this code for yourself?
  • Util Methods for interacting with Nanonets API.
  • Constants
  • Upload Data to newly created model
  • Check the model information and metadata
  • Launch the Training Job on Nanonets Infrastructure.
Nanonets
Docs
Getting StartedGuidesAPI Reference
Community
User Showcase
More
BlogGitHubStar
Copyright © 2019 Nanonets