Skip to content

Commit 1f86465

Browse files
committed
mlflow input and output schema update
1 parent 18e0e97 commit 1f86465

File tree

1 file changed

+186
-127
lines changed

1 file changed

+186
-127
lines changed

articles/machine-learning/reference-automl-images-schema.md

Lines changed: 186 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -235,170 +235,229 @@ Example of a JSONL file for Instance Segmentation:
235235

236236
![Image example for instance segmentation.](media/reference-automl-images-schema/instance-segmentation-predictions.jpg)
237237

238-
## Data format for inference
238+
## Data schema for online scoring
239239

240-
In this section, we document the input data format required to make predictions when using a deployed model. Any aforementioned image format is accepted with content type `application/octet-stream`.
240+
In this section, we document the input data format required to make predictions using a deployed model.
241241

242242
### Input format
243243

244-
The following is the input format needed to generate predictions on any task using task-specific model endpoint. After we [deploy the model](how-to-auto-train-image-models.md#register-and-deploy-model), we can use the following code snippet to get predictions for all tasks.
244+
The following is the input format needed to generate predictions on any task using task-specific model endpoint.
245+
246+
```json
247+
{
248+
"input_data": {
249+
"columns": [
250+
"image"
251+
],
252+
"data": [
253+
"image_in_base64_string_format"
254+
]
255+
}
256+
}
257+
```
258+
259+
This json is a dictionary with outer key `input_data` and inner keys `columns`, `data` as described in the following table. The endpoint accepts json string as input in the above format so that this json string can be decoded to json to create a dataframe of samples required by scoring script. Each input image in the `request_json["input_data"]["data"]` defined in the json format above is a [base64 encoded string](https://docs.python.org/3/library/base64.html#base64.encodebytes).
260+
261+
262+
| Key | Description |
263+
| -------- |----------|
264+
| `input_data`<br> (outer key) | It is an outer key in json request. `input_data` is a dictionary that accepts input image samples <br>`Required, Dictionary` |
265+
| `columns`<br> (inner key) | Column names to be used to create dataframe in scoring script. It accepts only one column with `image` as column name.<br>`Required, List` |
266+
| `data`<br> (inner key) | List of base64 encoded images <br>`Required, List`|
267+
268+
269+
After we [deploy the mlflow model](how-to-auto-train-image-models.md#register-and-deploy-model), we can use the following code snippet to get predictions for all tasks.
270+
245271

246272
```python
247-
# input image for inference
248-
sample_image = './test_image.jpg'
249-
# load image data
250-
data = open(sample_image, 'rb').read()
251-
# set the content type
252-
headers = {'Content-Type': 'application/octet-stream'}
253-
# if authentication is enabled, set the authorization header
254-
headers['Authorization'] = f'Bearer {key}'
255-
# make the request and display the response
256-
response = requests.post(scoring_uri, data, headers=headers)
273+
# Get the details for online endpoint
274+
endpoint = ml_client.online_endpoints.get(name=online_endpoint_name)
275+
276+
# Create request json
277+
import base64
278+
import json
279+
280+
sample_image = "./test_image.jpg"
281+
282+
def read_image(image_path):
283+
with open(image_path, "rb") as f:
284+
return f.read()
285+
286+
request_json = {
287+
"input_data": {
288+
"columns": ["image"],
289+
"data": [base64.encodebytes(read_image(sample_image)).decode("utf-8")],
290+
}
291+
}
292+
293+
request_file_name = "sample_request_data.json"
294+
295+
with open(request_file_name, "w") as request_file:
296+
json.dump(request_json, request_file)
297+
298+
resp = ml_client.online_endpoints.invoke(
299+
endpoint_name=online_endpoint_name,
300+
deployment_name=deployment.name,
301+
request_file=request_file_name,
302+
)
303+
predictions = json.loads(resp)
257304
```
305+
306+
258307
### Output format
259308

260-
Predictions made on model endpoints follow different structure depending on the task type. This section explores the output data formats for multi-class, multi-label image classification, object detection, and instance segmentation tasks.
309+
Predictions made on model endpoints follow different structure depending on the task type. This section explores the output data formats for multi-class, multi-label image classification, object detection, and instance segmentation tasks.
310+
311+
The following schemas are defined for the case of one input image.
261312

262313
#### Image classification
263314

264315
Endpoint for image classification returns all the labels in the dataset and their probability scores for the input image in the following format.
265316

266317
```json
267-
{
268-
"filename":"/tmp/tmppjr4et28",
269-
"probs":[
270-
2.098e-06,
271-
4.783e-08,
272-
0.999,
273-
8.637e-06
274-
],
275-
"labels":[
276-
"can",
277-
"carton",
278-
"milk_bottle",
279-
"water_bottle"
280-
]
281-
}
318+
[
319+
{
320+
"filename": "/tmp/tmppjr4et28",
321+
"probs": [
322+
2.098e-06,
323+
4.783e-08,
324+
0.999,
325+
8.637e-06
326+
],
327+
"labels": [
328+
"can",
329+
"carton",
330+
"milk_bottle",
331+
"water_bottle"
332+
]
333+
}
334+
]
282335
```
283336

284337
#### Image classification multi-label
285338

286339
For image classification multi-label, model endpoint returns labels and their probabilities.
287340

288341
```json
289-
{
290-
"filename":"/tmp/tmpsdzxlmlm",
291-
"probs":[
292-
0.997,
293-
0.960,
294-
0.982,
295-
0.025
296-
],
297-
"labels":[
298-
"can",
299-
"carton",
300-
"milk_bottle",
301-
"water_bottle"
302-
]
303-
}
342+
[
343+
{
344+
"filename": "/tmp/tmpsdzxlmlm",
345+
"probs": [
346+
0.997,
347+
0.960,
348+
0.982,
349+
0.025
350+
],
351+
"labels": [
352+
"can",
353+
"carton",
354+
"milk_bottle",
355+
"water_bottle"
356+
]
357+
}
358+
]
304359
```
305360

306361
#### Object detection
307362

308363
Object detection model returns multiple boxes with their scaled top-left and bottom-right coordinates along with box label and confidence score.
309364

310365
```json
311-
{
312-
"filename":"/tmp/tmpdkg2wkdy",
313-
"boxes":[
314-
{
315-
"box":{
316-
"topX":0.224,
317-
"topY":0.285,
318-
"bottomX":0.399,
319-
"bottomY":0.620
366+
[
367+
{
368+
"filename": "/tmp/tmpdkg2wkdy",
369+
"boxes": [
370+
{
371+
"box": {
372+
"topX": 0.224,
373+
"topY": 0.285,
374+
"bottomX": 0.399,
375+
"bottomY": 0.620
376+
},
377+
"label": "milk_bottle",
378+
"score": 0.937
320379
},
321-
"label":"milk_bottle",
322-
"score":0.937
323-
},
324-
{
325-
"box":{
326-
"topX":0.664,
327-
"topY":0.484,
328-
"bottomX":0.959,
329-
"bottomY":0.812
380+
{
381+
"box": {
382+
"topX": 0.664,
383+
"topY": 0.484,
384+
"bottomX": 0.959,
385+
"bottomY": 0.812
386+
},
387+
"label": "can",
388+
"score": 0.891
330389
},
331-
"label":"can",
332-
"score":0.891
333-
},
334-
{
335-
"box":{
336-
"topX":0.423,
337-
"topY":0.253,
338-
"bottomX":0.632,
339-
"bottomY":0.725
340-
},
341-
"label":"water_bottle",
342-
"score":0.876
343-
}
344-
]
345-
}
390+
{
391+
"box": {
392+
"topX": 0.423,
393+
"topY": 0.253,
394+
"bottomX": 0.632,
395+
"bottomY": 0.725
396+
},
397+
"label": "water_bottle",
398+
"score": 0.876
399+
}
400+
]
401+
}
402+
]
346403
```
347404
#### Instance segmentation
348405

349406
In instance segmentation, output consists of multiple boxes with their scaled top-left and bottom-right coordinates, labels, confidence scores, and polygons (not masks). Here, the polygon values are in the same format that we discussed in the schema section.
350407

351408
```json
352-
{
353-
"filename":"/tmp/tmpi8604s0h",
354-
"boxes":[
355-
{
356-
"box":{
357-
"topX":0.679,
358-
"topY":0.491,
359-
"bottomX":0.926,
360-
"bottomY":0.810
361-
},
362-
"label":"can",
363-
"score":0.992,
364-
"polygon":[
365-
[
366-
0.82, 0.811, 0.771, 0.810, 0.758, 0.805, 0.741, 0.797, 0.735, 0.791, 0.718, 0.785, 0.715, 0.778, 0.706, 0.775, 0.696, 0.758, 0.695, 0.717, 0.698, 0.567, 0.705, 0.552, 0.706, 0.540, 0.725, 0.520, 0.735, 0.505, 0.745, 0.502, 0.755, 0.493
367-
]
368-
]
369-
},
370-
{
371-
"box":{
372-
"topX":0.220,
373-
"topY":0.298,
374-
"bottomX":0.397,
375-
"bottomY":0.601
376-
},
377-
"label":"milk_bottle",
378-
"score":0.989,
379-
"polygon":[
380-
[
381-
0.365, 0.602, 0.273, 0.602, 0.26, 0.595, 0.263, 0.588, 0.251, 0.546, 0.248, 0.501, 0.25, 0.485, 0.246, 0.478, 0.245, 0.463, 0.233, 0.442, 0.231, 0.43, 0.226, 0.423, 0.226, 0.408, 0.234, 0.385, 0.241, 0.371, 0.238, 0.345, 0.234, 0.335, 0.233, 0.325, 0.24, 0.305, 0.586, 0.38, 0.592, 0.375, 0.598, 0.365
382-
]
383-
]
384-
},
385-
{
386-
"box":{
387-
"topX":0.433,
388-
"topY":0.280,
389-
"bottomX":0.621,
390-
"bottomY":0.679
391-
},
392-
"label":"water_bottle",
393-
"score":0.988,
394-
"polygon":[
395-
[
396-
0.576, 0.680, 0.501, 0.680, 0.475, 0.675, 0.460, 0.625, 0.445, 0.630, 0.443, 0.572, 0.440, 0.560, 0.435, 0.515, 0.431, 0.501, 0.431, 0.433, 0.433, 0.426, 0.445, 0.417, 0.456, 0.407, 0.465, 0.381, 0.468, 0.327, 0.471, 0.318
397-
]
398-
]
399-
}
400-
]
401-
}
409+
[
410+
{
411+
"filename": "/tmp/tmpi8604s0h",
412+
"boxes": [
413+
{
414+
"box": {
415+
"topX": 0.679,
416+
"topY": 0.491,
417+
"bottomX": 0.926,
418+
"bottomY": 0.810
419+
},
420+
"label": "can",
421+
"score": 0.992,
422+
"polygon": [
423+
[
424+
0.82, 0.811, 0.771, 0.810, 0.758, 0.805, 0.741, 0.797, 0.735, 0.791, 0.718, 0.785, 0.715, 0.778, 0.706, 0.775, 0.696, 0.758, 0.695, 0.717, 0.698, 0.567, 0.705, 0.552, 0.706, 0.540, 0.725, 0.520, 0.735, 0.505, 0.745, 0.502, 0.755, 0.493
425+
]
426+
]
427+
},
428+
{
429+
"box": {
430+
"topX": 0.220,
431+
"topY": 0.298,
432+
"bottomX": 0.397,
433+
"bottomY": 0.601
434+
},
435+
"label": "milk_bottle",
436+
"score": 0.989,
437+
"polygon": [
438+
[
439+
0.365, 0.602, 0.273, 0.602, 0.26, 0.595, 0.263, 0.588, 0.251, 0.546, 0.248, 0.501, 0.25, 0.485, 0.246, 0.478, 0.245, 0.463, 0.233, 0.442, 0.231, 0.43, 0.226, 0.423, 0.226, 0.408, 0.234, 0.385, 0.241, 0.371, 0.238, 0.345, 0.234, 0.335, 0.233, 0.325, 0.24, 0.305, 0.586, 0.38, 0.592, 0.375, 0.598, 0.365
440+
]
441+
]
442+
},
443+
{
444+
"box": {
445+
"topX": 0.433,
446+
"topY": 0.280,
447+
"bottomX": 0.621,
448+
"bottomY": 0.679
449+
},
450+
"label": "water_bottle",
451+
"score": 0.988,
452+
"polygon": [
453+
[
454+
0.576, 0.680, 0.501, 0.680, 0.475, 0.675, 0.460, 0.625, 0.445, 0.630, 0.443, 0.572, 0.440, 0.560, 0.435, 0.515, 0.431, 0.501, 0.431, 0.433, 0.433, 0.426, 0.445, 0.417, 0.456, 0.407, 0.465, 0.381, 0.468, 0.327, 0.471, 0.318
455+
]
456+
]
457+
}
458+
]
459+
}
460+
]
402461
```
403462

404463
> [!NOTE]

0 commit comments

Comments
 (0)