Step 01: Detecting Objects Using mobilenet


This tutorial and the assets can be downloaded as part of the Wallaroo Tutorials repository.

Step 01: Detecting Objects Using mobilenet

The following tutorial demonstrates how to use a trained mobilenet model deployed in Wallaroo to detect objects. This process will use the following steps:

  1. Create a Wallaroo workspace and pipeline.
  2. Upload a trained mobilenet ML model and add it as a pipeline step.
  3. Deploy the pipeline.
  4. Perform an inference on a sample image.
  5. Draw the detected objects, their bounding boxes, their classifications, and the confidence of the classifications on the provided image.
  6. Review our results.

Steps

Import Libraries

The first step will be to import our libraries. Please check with Step 00: Introduction and Setup and verify that the necessary libraries and applications are added to your environment.

# preload needed libraries 

import wallaroo
from wallaroo.object import EntityNotFoundError
from wallaroo.framework import Framework
from IPython.display import display
from IPython.display import Image
import pandas as pd
import json
import datetime
import time
import cv2
import matplotlib.pyplot as plt
import string
import random
import pyarrow as pa
import sys
import asyncio
pd.set_option('display.max_colwidth', None)

import sys

import utils

Connect to the Wallaroo Instance

The first step is to connect to Wallaroo through the Wallaroo client. The Python library is included in the Wallaroo install and available through the Jupyter Hub interface provided with your Wallaroo environment.

This is accomplished using the wallaroo.Client() command, which provides a URL to grant the SDK permission to your specific Wallaroo environment. When displayed, enter the URL into a browser and confirm permissions. Store the connection into a variable that can be referenced later.

If logging into the Wallaroo instance through the internal JupyterHub service, use wl = wallaroo.Client(). For more information on Wallaroo Client settings, see the Client Connection guide.

# Login through local service

wl = wallaroo.Client()

Set Variables

The following variables and methods are used later to create or connect to an existing workspace, pipeline, and model.

Verify that the workspace name is unique before running.

workspace_name = f'mobilenetworkspacetest'
pipeline_name = f'mobilenetpipeline'
model_name = f'cv-mobilenet'
model_file_name = 'models/mobilenet.pt.onnx'

Create Workspace

The workspace will be created or connected to, and set as the default workspace for this session. Once that is done, then all models and pipelines will be set in that workspace.

workspace = wl.get_workspace(name=workspace_name, create_if_not_exist=True)
wl.set_current_workspace(workspace)
wl.get_current_workspace()
{'name': 'mobilenetworkspacetest', 'id': 16, 'archived': False, 'created_by': '36e83b1d-b405-4d30-abc5-e7000163d930', 'created_at': '2024-04-09T17:35:41.35534+00:00', 'models': [{'name': 'cv-post-process-drift-detection', 'versions': 42, 'owner_id': '""', 'last_update_time': datetime.datetime(2024, 4, 9, 21, 28, 13, 49570, tzinfo=tzutc()), 'created_at': datetime.datetime(2024, 4, 9, 17, 50, 8, 925220, tzinfo=tzutc())}, {'name': 'cv-mobilenet', 'versions': 3, 'owner_id': '""', 'last_update_time': datetime.datetime(2024, 4, 9, 19, 33, 58, 579502, tzinfo=tzutc()), 'created_at': datetime.datetime(2024, 4, 9, 17, 35, 48, 698553, tzinfo=tzutc())}], 'pipelines': [{'name': 'mobilenetpipeline', 'create_time': datetime.datetime(2024, 4, 9, 17, 35, 42, 360178, tzinfo=tzutc()), 'definition': '[]'}]}

Create Pipeline and Upload Model

We will now create or connect to an existing pipeline as named in the variables above.

pipeline = wl.build_pipeline(pipeline_name)
mobilenet_model = (wl.upload_model(model_name, 
                                  model_file_name, 
                                  framework=Framework.ONNX)
                                .configure(batch_config="single", 
                                           tensor_fields=["tensor"]
                                           )
                    )

Upload Post Processing Module

The following module takes the results from the CV model output, and averages the confidence values from all detected objects. This is used for observability and model drift tracking.

input_schema = pa.schema([
    pa.field('boxes', pa.list_(pa.list_(pa.float32(), list_size=4))),
    pa.field('classes', pa.list_(pa.int64())),
    pa.field('confidences', pa.list_(pa.float32()))
    ]
)

output_schema = pa.schema([
    pa.field('boxes', pa.list_(pa.list_(pa.float32(), list_size=4))),
    pa.field('classes', pa.list_(pa.int64())),
    pa.field('confidences', pa.list_(pa.float32())),
    pa.field('avg_confidence', pa.list_(pa.float32())),
])

module_post_process_model = wl.upload_model("cv-post-process-drift-detection", 
                                            "./models/post-process-drift-detection.zip",
                                            framework=Framework.PYTHON,
                                            input_schema=input_schema, 
                                            output_schema=output_schema
                                            )
Waiting for model loading - this will take up to 10.0min.
Model is pending loading to a container runtime..
Model is attempting loading to a container runtime.......successful

Ready

Deploy Pipeline

With the model uploaded, we can add it is as a step in the pipeline, then deploy it. Once deployed, resources from the Wallaroo instance will be reserved and the pipeline will be ready to use the model to perform inference requests.

pipeline.undeploy()
namemobilenetpipeline
created2024-04-09 17:35:42.360178+00:00
last_updated2024-04-11 18:48:13.786619+00:00
deployedFalse
archx86
accelnone
tags
versions53851f22-4e48-4e14-94b1-0b81cd884acd, dcb69ef6-2ade-4b4e-94da-4f76c54fd718, 7e6ae68e-c2ac-4f5a-95ce-863d221bdedc, a9f5f1ae-610d-4313-bf39-19c043d5d4e8, cc9cba9a-1898-4e0e-ad2d-bd4e1ad156d8, 40fd4660-479f-4a13-b7c0-af93918b0ac5, 9decc9fc-f18c-4e07-a6ff-09ebeedb3c0e, 5770d1b6-497c-4205-8399-bfe24ba84c5a, 6a7a2f55-1336-498f-82ae-09ffa5284b5b, 65b636fe-062f-4238-b4b1-c64b738537d7, 36b12514-0c5c-47fe-afba-bdd609e24ccd, 95572aa3-a6ea-4900-8dd3-1b96cfe1671a, 5a3d4d94-8b22-429c-a4d0-613ae459033f, e1a97c30-4e32-46a8-88ca-2926cabc5a9f, 0f7800ca-9d9b-4989-9312-86c7ddad8450, adc6ab3e-2c6e-4250-aacc-4945aa981803, 142117d5-bf13-4fcd-a9d0-760600f9a5b0, 5cc86e33-4ff1-4257-a3f2-4e95ba3bb7f4, 0cb75c86-e326-4a88-8fa6-971402a448ad, 8f9abb58-c5df-41e2-ae8b-9240c636da38, 03573f29-b39b-49e5-8785-1c1688ea0405, c679436e-12a2-4eae-8203-a963733434b7, d17008ef-0fe9-4b99-9782-899c3f4d830c, ffbacedc-d280-49cb-b1cd-40b413853ffd, bd813919-fde4-4e83-8f65-bb177a31547a, 225fce83-c278-484a-8140-9eeb848e488d, 0a84141a-2db2-40a4-bbf0-075b19176617, 6ff6f69d-f25e-433c-8ff2-0e213e93b7da, 3db345ae-f7a3-4216-a5c8-1ae7fd543b93, b96149e6-b333-41cd-931b-3b43e9437fa7, 45ac9c5c-fd5a-40ee-bb9f-f8323dcbd9a7, e9ad4a22-3301-4b5d-9eed-6ec974ad3ac8, 7b01b6d9-cd92-44e2-8c95-379bed7b162b, 1839dd21-8b4e-42c0-9d92-e79fea664d18, 696b6c83-40d2-4418-85b5-1b6539217345, 0b8cb6e8-cb4d-4375-ac8e-b59022755b93, 575c204a-adc7-4092-8d37-8bb8d8eff976, 2bf03c98-8038-49ca-9df1-0555e8e53caf, 1d2f4610-642b-44f5-86ca-cd59fc9c0505, f1bfe8ca-8945-4571-978b-a659c0f8d23a, 69c1d108-79d4-4246-ac95-301467268dc8, 1c7c47a7-2bc4-490e-a866-3f45ba6814c2, 47193309-715c-43af-8bcd-2fd74c95ee51, efc63a47-6f7a-4d91-b4a5-172ef8a1159e
stepscv-mobilenet
publishedFalse
pipeline.clear()
pipeline.add_model_step(mobilenet_model)
pipeline.add_model_step(module_post_process_model)

deploy_config = wallaroo.DeploymentConfigBuilder().replica_count(1).cpus(1).memory("1Gi").build()
pipeline.deploy(deployment_config=deploy_config)

# wait 20 seconds to give the sidekick pods time to finish starting
import time
time.sleep(20)

Prepare input image

Next we will load a sample image and resize it to the width and height required for the object detector. Once complete, it the image will be converted to a numpy ndim array and added to a dictionary.

image = cv2.imread('./data/images/input/example/dairy_bottles.png')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(12,8))
plt.grid(False)
plt.imshow(image)
plt.show()
width, height = 640, 480
dfImage, resizedImage = utils.loadImageAndConvertToDataframe('./data/images/input/example/dairy_bottles.png', width, height)

Run Inference

With that done, we can have the model detect the objects on the image by running an inference through the pipeline, and storing the results for the next step.

startTime = time.time()
infResults = pipeline.infer(dfImage, timeout=300)
endTime = time.time()

Draw the Inference Results

With our inference results, we can take them and use the Wallaroo CVDemo class and draw them onto the original image. The bounding boxes and the confidence value will only be drawn on images where the model returned a 90% confidence rate in the object’s identity.

elapsed = 1.0
results = {
    'model_name' : model_name,
    'pipeline_name' : pipeline_name,
    'width': width,
    'height': height,
    'image' : resizedImage,
    'inf-results' : infResults,
    'confidence-target' : 0.50,
    'inference-time': (endTime-startTime),
    'onnx-time' : int(elapsed) / 1e+9,
    'classes_file': "./models/coco_classes.pickle",                 
    'color': 'BLUE'
}

image = utils.drawDetectedObjectsFromInference(results)

Undeploy the Pipeline

With the inference complete, we can undeploy the pipeline and return the resources back to the Wallaroo instance.

pipeline.undeploy()
namemobilenetpipeline
created2024-04-09 17:35:42.360178+00:00
last_updated2024-04-11 18:49:45.097616+00:00
deployedFalse
archx86
accelnone
tags
versions1ea1cb3f-a954-4916-ae95-ec430e374531, 53851f22-4e48-4e14-94b1-0b81cd884acd, dcb69ef6-2ade-4b4e-94da-4f76c54fd718, 7e6ae68e-c2ac-4f5a-95ce-863d221bdedc, a9f5f1ae-610d-4313-bf39-19c043d5d4e8, cc9cba9a-1898-4e0e-ad2d-bd4e1ad156d8, 40fd4660-479f-4a13-b7c0-af93918b0ac5, 9decc9fc-f18c-4e07-a6ff-09ebeedb3c0e, 5770d1b6-497c-4205-8399-bfe24ba84c5a, 6a7a2f55-1336-498f-82ae-09ffa5284b5b, 65b636fe-062f-4238-b4b1-c64b738537d7, 36b12514-0c5c-47fe-afba-bdd609e24ccd, 95572aa3-a6ea-4900-8dd3-1b96cfe1671a, 5a3d4d94-8b22-429c-a4d0-613ae459033f, e1a97c30-4e32-46a8-88ca-2926cabc5a9f, 0f7800ca-9d9b-4989-9312-86c7ddad8450, adc6ab3e-2c6e-4250-aacc-4945aa981803, 142117d5-bf13-4fcd-a9d0-760600f9a5b0, 5cc86e33-4ff1-4257-a3f2-4e95ba3bb7f4, 0cb75c86-e326-4a88-8fa6-971402a448ad, 8f9abb58-c5df-41e2-ae8b-9240c636da38, 03573f29-b39b-49e5-8785-1c1688ea0405, c679436e-12a2-4eae-8203-a963733434b7, d17008ef-0fe9-4b99-9782-899c3f4d830c, ffbacedc-d280-49cb-b1cd-40b413853ffd, bd813919-fde4-4e83-8f65-bb177a31547a, 225fce83-c278-484a-8140-9eeb848e488d, 0a84141a-2db2-40a4-bbf0-075b19176617, 6ff6f69d-f25e-433c-8ff2-0e213e93b7da, 3db345ae-f7a3-4216-a5c8-1ae7fd543b93, b96149e6-b333-41cd-931b-3b43e9437fa7, 45ac9c5c-fd5a-40ee-bb9f-f8323dcbd9a7, e9ad4a22-3301-4b5d-9eed-6ec974ad3ac8, 7b01b6d9-cd92-44e2-8c95-379bed7b162b, 1839dd21-8b4e-42c0-9d92-e79fea664d18, 696b6c83-40d2-4418-85b5-1b6539217345, 0b8cb6e8-cb4d-4375-ac8e-b59022755b93, 575c204a-adc7-4092-8d37-8bb8d8eff976, 2bf03c98-8038-49ca-9df1-0555e8e53caf, 1d2f4610-642b-44f5-86ca-cd59fc9c0505, f1bfe8ca-8945-4571-978b-a659c0f8d23a, 69c1d108-79d4-4246-ac95-301467268dc8, 1c7c47a7-2bc4-490e-a866-3f45ba6814c2, 47193309-715c-43af-8bcd-2fd74c95ee51, efc63a47-6f7a-4d91-b4a5-172ef8a1159e
stepscv-mobilenet
publishedFalse