google-coral / pycoral

Python API for ML inferencing and transfer-learning on Coral devices
https://coral.ai
Apache License 2.0
355 stars 146 forks source link

Inference process do a strange behaviour #111

Closed Gaguila20 closed 1 year ago

Gaguila20 commented 1 year ago

Description

I am writing to report an issue that I am encountering while using the Google Coral USB accelerator for inference with a TensorFlow object detection model.

I use the TensorFlow object detection API and employ transfer learning using the MobileNetV2 backbone and custom images. Once I have a model with good results, I optimize the model in TFLITE format, which is then compiled for EdgeTPU. However, when I attempt to run the example code for inference using the detect_image.py script, I notice that the output image differs depending on whether I use an odd or even number for the count flag.

Here is an example command that I have been using:

!python3 Algarve/coral/pycoral/examples/detect_image.py \ --model Algarve/algarve_model_UINT8_edgetpu.tflite \ --labels Algarve/label.txt \ --input Algarve/TEST_ALGARVE/VES_Context_793_1681888605898_NOCLASS_0_0det_afternoon.jpg \ --threshold 0.3 \ --count 3 \ --output Algarve/OUTPUT/PRUEBA9.jpg

As you can see, I am specifying a count of 3, which should output an image with a detected object. However, the model fails to recognize anything. Strangely, when I change the count to 2 or 4, the resulting inference result is different, and the object is now detected.

In this situation, I tried to make my own script for inferring images inside a folder.

import os import time import pathlib import numpy as np

from PIL import Image from PIL import ImageDraw

from pycoral.adapters import common from pycoral.adapters import detect from pycoral.utils.dataset import read_label_file from pycoral.utils.edgetpu import make_interpreter

def draw_objects(draw, objs, labels): """Draws the bounding box and label for each object.""" for obj in objs: bbox = obj.bbox draw.rectangle([(bbox.xmin, bbox.ymin), (bbox.xmax, bbox.ymax)], outline='red') draw.text((bbox.xmin + 10, bbox.ymin + 10), '%s\n%.2f' % (labels.get(obj.id, obj.id), obj.score), fill='red')

Specify the TensorFlow model, labels, and image

path_parent = "/home/gaguila/PYTHON/repositorio/Algarve" image_path = "TEST_ALGARVE" output_images_path = os.path.join(path_parent, 'OUTPUT') output_images_path2 = os.path.join(path_parent, 'OUTPUT100') label_path = "label.txt"

labels = read_label_file(os.path.join(path_parent, label_path)) if label_path else{}

model_file = os.path.join(path_parent, 'algarve_model_UINT8_edgetpu.tflite') directory = os.path.join(path_parent, 'TEST_ALGARVE')

Initialize the TF interpreter

interpreter = make_interpreter(model_file) interpreter.allocate_tensors()

Resize the image

_, size = common.input_size(interpreter)

print(size)

Bucle que recorre la carpeta

image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp'] # Add any other image extensions you need image_names = [] threshold = 0.45

print('----INFERENCE TIME----') print('Note: The first inference is slow because it includes','loading the model into Edge TPU memory.') cnt=0 times = []

for filename in os.listdir(directory): image = Image.open(os.path.join(directory, filename)) image = image.convert("RGB") _, scale = common.set_resized_input(interpreter, image.size, lambda size: image.resize(size, Image.LANCZOS)) print(scale) start = time.perf_counter()

interpreter.invoke()

for _ in range(2): # Even Example without loop the result are equal to odd number
    interpreter.invoke()

inference_time = time.perf_counter() - start
objs = detect.get_objects(interpreter, threshold, scale)
times.append(inference_time*1000)

print('%.2f ms' % ( inference_time*1000))
print('-------RESULTS--------')
if not objs:
    print('No objects detected')

for obj in objs:
    print(labels.get(obj.id, obj.id))
    print('  id:    ', obj.id)
    print('  score: ', obj.score)
    print('  bbox:  ', obj.bbox)

image_output = image.convert('RGB')
draw_objects(ImageDraw.Draw(image_output), objs, labels)
new_string = "Salida_"+ str(cnt) +str(".jpg")
print(new_string)
image_output.save( (os.path.join(output_images_path, new_string) ) )
cnt+=1

print("-------TIMES-------") print("Mean time: ", np.mean(times[1:]), "ms") print("Std time: ", np.std(times[1:]), "ms") print("Max time: ", np.max(times[1:]), "ms") print("Min time: ", np.min(times[1:]), "ms")

I have noticed that when I place the 'invoke' function inside a loop, I get the same results as I do with the example script. If the range is even the result are difference from when I use odd range or without range.

I would greatly appreciate it if someone could help me troubleshoot this issue and provide any guidance on how to fix it. Thank you in advance for your assistance.

Click to expand! ### Issue Type Performance ### Operating System Ubuntu ### Coral Device USB Accelerator ### Other Devices _No response_ ### Programming Language Python 3.8 ### Relevant Log Output _No response_
hjonnala commented 1 year ago

Running interpreter.invoke() any number of times on same input should give same output.

Test your script with any pretrained edgeptu model. If your script is working as expected then issue could be with your edgetpu model. For this you can test script with the uncomplied tflite model, to know whether the issue with your uncompiled tflite or your edgetpu model.

google-coral-bot[bot] commented 1 year ago

Are you satisfied with the resolution of your issue? Yes No