Create Dual Image Regression Project#
This example shows a case where the model consumes two images and regresses a value, thus the uploaded dataset needs to contain the required dual images information alongside the regressed ground truth in a single datapoint.
First we will create a dataset, and later on, a dummy model that returns a regressed value.
Create dataset#
Let’s create the dataset with the custom format by iterating over the images in pairs and (2) creating datapoints containing the images and required value.
In upload_dataset.py
add the following script to perform the above steps.
import os
import random
import efemarai as ef
def get_dataset():
images = [
"https://this-person-does-not-exist.com/img/avatar-11c3c1714641dccb5e0cdd221a4fa6aa.jpg",
"https://this-person-does-not-exist.com/img/avatar-110c31e334d64b1598a07d19bb374fec.jpg",
"https://this-person-does-not-exist.com/img/avatar-112eedb7d5026b58f4762607498137e0.jpg",
"https://this-person-does-not-exist.com/img/avatar-11c85c80da827fd91f7b6a4ad4cd8c1d.jpg",
"https://this-person-does-not-exist.com/img/avatar-1186b1e698b5d848305a606cddeadd10.jpg",
"https://this-person-does-not-exist.com/img/avatar-116a7a1444014822a3715e009e882105.jpg",
"https://this-person-does-not-exist.com/img/avatar-11035e8e377de99688e853971caccf2c.jpg",
"https://this-person-does-not-exist.com/img/avatar-111dd492cd4c87c5ed2673c2bfcf38bc.jpg",
"https://this-person-does-not-exist.com/img/avatar-1175bc9c09349a5275f3f2ff81821c8b.jpg",
"https://this-person-does-not-exist.com/img/avatar-115b84f284677e28b0e464fcb49a0497.jpg",
]
similarities = [0.0, 0.25, 0.5, 0.75, 1.0]
images_a, images_b = [], []
# Download images
os.makedirs("images", exist_ok=True)
for i, url in enumerate(images):
path = os.path.basename(url)
if not os.path.exists(path):
os.system(f"wget -nv -O {path} {url}")
if i % 2:
images_a.append(path)
else:
images_b.append(path)
return zip(images_a, images_b, similarities)
def upload_dataset():
project = ef.Session().create_project(
name="Dual Image Regression",
description="Example project showing dual image regression.",
exists_ok=True,
)
dataset = project.create_dataset(
name="Dual image dataset",
stage=ef.DatasetStage.Test,
format=ef.DatasetFormat.Custom,
exists_ok=True,
)
for a_url, b_url, similarity in get_dataset():
# Create the inputs to the model
image_a = ef.Image(file_path=os.path.basename(a_url))
image_b = ef.Image(file_path=os.path.basename(b_url))
# Create target outputs for the model
similarity = ef.Value(value=similarity, ref_field=[image_a, image_b])
# A sample, or a datapoint, contains reference to the dataset,
# the inputs and target outputs
datapoint = ef.Datapoint(
dataset=dataset,
inputs={"image_a": image_a, "image_b": image_b},
targets={
"similarity_score": similarity,
},
)
# Upload the datapoint
datapoint.upload()
# Let us know that these were all the datapoints for this dataset, so we
# can calculate additional metadata.
dataset.finalize()
if __name__ == "__main__":
upload_dataset()
Run python upload_dataset.py
and wait for it to be completed.
After wrapping up any processing, you can confirm the status in the UI and explore the inputs and annotations.
Create a model#
A model that works with value dataset will need to return a list of
ef.Value
objects that will be matched to the ones stored in the dataset.
In a file dummy_model.py
save the following code:
import efemarai as ef
import numpy as np
class DummyModel:
"""A DummyModel returning random value"""
def __init__(self, device):
# Move model to device
self.device = device
def __call__(self, image_a, image_b):
return {
"similarity_score": np.random.random(),
}
def predict_images(datapoints, model, device):
outputs = []
for datapoint in datapoints:
image_a = datapoint.get_input("image_a")
image_b = datapoint.get_input("image_b")
output = model(image_a.data, image_b.data)
outputs.append(
[
ef.Value(
value=output["similarity_score"], ref_field=[image_a, image_b]
),
]
)
return outputs
def load_model(device):
model = DummyModel(device)
return model
def test():
device = "cpu"
model = load_model(device=device)
image_RGB = np.random.randint(0, 256, size=(480, 640, 3), dtype=np.uint8)
ef_datapoint = ef.Datapoint(
dataset=None,
inputs={
"image_a": ef.Image(data=image_RGB),
"image_b": ef.Image(data=image_RGB),
},
)
output = predict_images([ef_datapoint], model, device)
print(output)
assert isinstance(output, list)
assert isinstance(output[0][0], ef.Value)
if __name__ == "__main__":
test()
If you run it with python dummy_model.py
you’ll be able to confirm that the
output of the model is a list of detections per input datapoint.
efemarai.yaml
file#
To run the model, you need to have defined the loading and inference
capabilities in the efemarai.yaml
file.
Here’s the one corresponding to the dummy model.
project:
name: "Dual Image Regression"
description: "Example project showing dual image regression."
models:
- name: Dummy Model
description: This is a dummy model to show consuming inputs and outputs
runtime:
image: python:3.10-slim-buster
device: "gpu"
batch:
max_size: 10
load:
entrypoint: dummy_model:load_model
inputs:
- name: device
value: ${model.runtime.device}
output:
name: model
predict:
entrypoint: dummy_model:predict_images
inputs:
- name: datapoints
value: ${datapoints}
- name: model
value: ${model.runtime.load.output.model}
- name: device
value: ${model.runtime.device}
output:
name: predictions
keys:
- similarityScore
Register the model#
To register the model, use the CLI to upload it by going into the root of the
file directory, next to the efemarai.yaml
.
ef model create .
Now you should be able to see the model uploaded and active with this project.