edgetpu-yolo icon indicating copy to clipboard operation
edgetpu-yolo copied to clipboard

Unable to interpret prediction values by Ultralytics Yolov8 tflite edgetpu model inference on Coral USB Accelerator

Open Arslan-Mehmood1 opened this issue 10 months ago • 29 comments

Hi man, I have exported my yolov8 model to edge tpu model using ultralytics. I'm able to perform the inference using USB coral accelerator. But I'm not sure how to handle the predictions. I'm sharing the input and output details of my interpreter.

Model : yolov8_int8_edgetpu.tflite

Input_details: [{'name': 'serving_default_images:0', 'index': 0, 'shape': array([ 1, 1280, 1280, 3], dtype=int32), 'shape_signature': array([ 1, 1280, 1280, 3], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]

Output_details: [{'name': 'PartitionedCall:0', 'index': 517, 'shape': array([ 1, 251, 33600], dtype=int32), 'shape_signature': array([ 1, 251, 33600], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]

INFERENCE_LOG: python3 detect_image.py -m yolov8_int8_edgetpu.tflite -i image.jpg -o inference/detection.jpg

Note: The first inference is slow because it includes loading the model into Edge TPU memory. ----INFERENCE TIME---- 21368.82 ms

Output Details : [{'name': 'PartitionedCall:0', 'index': 517, 'shape': array([ 1, 251, 33600], dtype=int32), 'shape_signature': array([ 1, 251, 33600], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0), 'quantization_parameters': {'scales': array([], dtype=float32), 'zero_points': array([], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}] Output Data Shape: (1, 251, 33600) Output Data : [[[6.8984828e-03 8.4312847e-03 1.4987010e-02 ... 9.1422123e-01 9.3176806e-01 9.5353013e-01] [8.2258508e-03 8.4541356e-03 8.1687719e-03 ... 9.7039759e-01 9.6757478e-01 9.6137410e-01] [1.3865395e-02 1.7534753e-02 1.8626634e-02 ... 2.2020416e-01 1.8798628e-01 1.2658052e-01] ... [8.6820194e-07 1.4569782e-06 1.3537380e-06 ... 4.9203813e-05 3.5585672e-05 3.4364115e-05] [1.6130493e-06 1.2267126e-06 2.5768195e-06 ... 4.6514473e-05 4.1418200e-05 3.8001206e-05] [4.9328037e-07 1.4711668e-06 1.1877161e-06 ... 3.2545999e-05 3.1352149e-05 2.2766470e-05]]]

CONFUSION: I'm not sure how to handle the output tensor which has shape [ 1, 251, 33600]. Please guide I'm stuck here.

Arslan-Mehmood1 avatar Aug 25 '23 13:08 Arslan-Mehmood1

How many classes does your model have?

jveitchmichaelis avatar Aug 25 '23 13:08 jveitchmichaelis

it has 247 classes. label.txt

Arslan-Mehmood1 avatar Aug 25 '23 13:08 Arslan-Mehmood1

Have you tried the example code in this repository? Please try the detect.py script here and pass in your model + label file as arguments - you can use -h to see help.

There are several steps you need to perform to convert the output but generally the format is:

You get one prediction vector per anchor point. You need to first rescale your result from the quantized values (int > float) and then perform softmax and non-maximum suppression.

On Fri, 25 Aug 2023 at 14:15, Arslan Mehmood @.***> wrote:

I'm using PyCoral api default procedure.

— Reply to this email directly, view it on GitHub https://github.com/jveitchmichaelis/edgetpu-yolo/issues/11#issuecomment-1693346604, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYDMJ4U5P4IVDMLNX6SRWLXXCQP7ANCNFSM6AAAAAA36PZ52E . You are receiving this because you commented.Message ID: @.***>

jveitchmichaelis avatar Aug 25 '23 13:08 jveitchmichaelis

Also I havent followed anything in your repo. I have followed the Pycoral basic detection workflow and used the 'detect.py'. One thing I dont get is that the output tensor length is 33600. How will it get mapped to [coordinates x1,x2,x3,x4,probability] (5-values).

Arslan-Mehmood1 avatar Aug 25 '23 13:08 Arslan-Mehmood1

Each row in the tensor is an object prediction. The first four valued are xy coordinates representing the box. The remaining values are class probabilities. Almost all of them should be zero and you need to run NMS to filter the ones that work.

4 + 247 = 251 columns

Please try using detect.py - it does all the post processing.

Though yolov8 is anchor free I believe. If you're not sure what the output tensor should be then you should post an issue on ultralytics' repo

jveitchmichaelis avatar Aug 25 '23 13:08 jveitchmichaelis

Also see https://github.com/ultralytics/ultralytics/issues/751

It's possible the order of the values is changed in v8 but I doubt it.

jveitchmichaelis avatar Aug 25 '23 13:08 jveitchmichaelis

Also just a note that the detect.py from the coral team assumes you're using an SSD model (eg the examples from Google), so I'm not sure it will work unless the output shapes/interpretations are comparable.

On Fri, 25 Aug 2023 at 14:28, Arslan Mehmood @.***> wrote:

Also I havent followed anything in your repo. I have followed the Pycoral basic detection workflow and used the detect.py. One thing I dont get is that the output tensor length is 33600. How will it get mapped to coordinates x1,x2,x3,x4,probability http://5-values.

— Reply to this email directly, view it on GitHub https://github.com/jveitchmichaelis/edgetpu-yolo/issues/11#issuecomment-1693363414, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYDMJ2LI4ACYI6NHTYLTX3XXCSAXANCNFSM6AAAAAA36PZ52E . You are receiving this because you commented.Message ID: @.***>

jveitchmichaelis avatar Aug 25 '23 14:08 jveitchmichaelis

understood. A little confusion: if 251 is classes plus bounding box. then 33600 are the no of detections right.? if yes, then what if my image contains no object, why would it still predict such 33600 predictions.

Arslan-Mehmood1 avatar Aug 25 '23 14:08 Arslan-Mehmood1

Getting this error when trying this repo detect.py for my model and image.

python3 detect.py --model yolov8_edgetpu.tflite --names label.yaml --image image.jpg

ERROR: INFO:EdgeTPUModel:Confidence threshold: 0.25 INFO:EdgeTPUModel:IOU threshold: 0.45 INFO:EdgeTPUModel:Loaded 247 classes INFO:EdgeTPUModel:Successfully loaded /home/arslan/learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/yolov8_edgetpu.tflite Traceback (most recent call last): File "detect.py", line 51, in model.forward(x) File "/home/arslan/learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/edgetpumodel.py", line 160, in forward self.interpreter.set_tensor(self.input_details[0]['index'], x) File "/usr/lib/python3/dist-packages/tflite_runtime/interpreter.py", line 572, in set_tensor self._interpreter.SetTensor(tensor_index, value) ValueError: Cannot set tensor: Got value of type UINT8 but expected type FLOAT32 for input 0, name: inputs_0

Arslan-Mehmood1 avatar Aug 25 '23 14:08 Arslan-Mehmood1

Hmm, I'm not sure why your model is expecting a float input, it should be looking for int8.

On Fri, 25 Aug 2023 at 16:42, Arslan Mehmood @.***> wrote:

Getting this error when trying this repo detect.py for my model and image.

ERROR: INFO:EdgeTPUModel:Confidence threshold: 0.25 INFO:EdgeTPUModel:IOU threshold: 0.45 INFO:EdgeTPUModel:Loaded 247 classes INFO:EdgeTPUModel:Successfully loaded /home/arslan//learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/yolov8_edgetpu.tflite Traceback (most recent call last): File "detect.py", line 51, in model.forward(x) File "/home/arslan/nixense_vixion/learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/edgetpumodel.py", line 160, in forward self.interpreter.set_tensor(self.input_details[0]['index'], x) File "/usr/lib/python3/dist-packages/tflite_runtime/interpreter.py", line 572, in set_tensor self._interpreter.SetTensor(tensor_index, value) ValueError: Cannot set tensor: Got value of type UINT8 but expected type FLOAT32 for input 0, name: inputs_0

— Reply to this email directly, view it on GitHub https://github.com/jveitchmichaelis/edgetpu-yolo/issues/11#issuecomment-1693473092, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYDMJ7Z5AEMLO5ATMNZAVLXXC2UFANCNFSM6AAAAAA36PZ52E . You are receiving this because you commented.Message ID: @.***>

jveitchmichaelis avatar Aug 25 '23 15:08 jveitchmichaelis

Is your model actually quantised?

On Fri, 25 Aug 2023 at 17:02, Josh Veitch-Michaelis < @.***> wrote:

Hmm, I'm not sure why your model is expecting a float input, it should be looking for int8.

On Fri, 25 Aug 2023 at 16:42, Arslan Mehmood @.***> wrote:

Getting this error when trying this repo detect.py for my model and image.

ERROR: INFO:EdgeTPUModel:Confidence threshold: 0.25 INFO:EdgeTPUModel:IOU threshold: 0.45 INFO:EdgeTPUModel:Loaded 247 classes INFO:EdgeTPUModel:Successfully loaded /home/arslan//learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/yolov8_edgetpu.tflite Traceback (most recent call last): File "detect.py", line 51, in model.forward(x) File "/home/arslan/nixense_vixion/learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/edgetpumodel.py", line 160, in forward self.interpreter.set_tensor(self.input_details[0]['index'], x) File "/usr/lib/python3/dist-packages/tflite_runtime/interpreter.py", line 572, in set_tensor self._interpreter.SetTensor(tensor_index, value) ValueError: Cannot set tensor: Got value of type UINT8 but expected type FLOAT32 for input 0, name: inputs_0

— Reply to this email directly, view it on GitHub https://github.com/jveitchmichaelis/edgetpu-yolo/issues/11#issuecomment-1693473092, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYDMJ7Z5AEMLO5ATMNZAVLXXC2UFANCNFSM6AAAAAA36PZ52E . You are receiving this because you commented.Message ID: @.***>

jveitchmichaelis avatar Aug 25 '23 15:08 jveitchmichaelis

Yes , after converting the yolov8 model to tf saved model using ultralytics. I have quantized my tf saved model to INT8 using tf lite converter and a small calibration dataset from my training images.

Arslan-Mehmood1 avatar Aug 28 '23 08:08 Arslan-Mehmood1

You also need to use the edgetpu compiler, otherwise I don't see how the model is running on the device?

image

https://coral.ai/docs/edgetpu/compiler/

But either way, it seems like your model is not quantised because the input layer is asking for a float tensor instead of the int8 one that we're passing in:

ValueError: Cannot set tensor: Got value of type UINT8 but expected type FLOAT32 for input 0, name: inputs_0

jveitchmichaelis avatar Aug 28 '23 08:08 jveitchmichaelis

sorry for my confusing explainations and all. I'm telling the details from start.

First of all I have exported my yolov8 model to edgetpu model using ultralytics as ultralytics provide this export feature. After successful export, I get all these models as shown in screenshot.

Screenshot from 2023-08-28 13-51-01

and I'm using my_yolov8_full_integer_quant_edgetpu.tflite for inference by your detect.py script in repo. I'm getting this error.

python3 detect.py --model my_yolov8_full_integer_quant_edgetpu.tflite --names label.yaml --image image.jpg INFO:EdgeTPUModel:Confidence threshold: 0.25 INFO:EdgeTPUModel:IOU threshold: 0.45 INFO:EdgeTPUModel:Loaded 247 classes INFO:EdgeTPUModel:Successfully loaded /home/arslan/learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/my_yolov8_full_integer_quant_edgetpu.tflite Traceback (most recent call last): File "detect.py", line 51, in model.forward(x) File "/home/arslan/learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/edgetpumodel.py", line 160, in forward self.interpreter.set_tensor(self.input_details[0]['index'], x) File "/usr/lib/python3/dist-packages/tflite_runtime/interpreter.py", line 572, in set_tensor self._interpreter.SetTensor(tensor_index, value) ValueError: Cannot set tensor: Got value of type UINT8 but expected type INT8 for input 0, name: serving_default_images:0 .

Note: The last time the model which was successfully performing inference on edgetpu using pycoral API, I have deleted all previous files, and I'm starting from scratch.

Arslan-Mehmood1 avatar Aug 28 '23 09:08 Arslan-Mehmood1

You can try just changing the cast to np.int8 here: https://github.com/jveitchmichaelis/edgetpu-yolo/blob/784d9be1bb13ce4b8b3c1bad729a02a69cca97bb/edgetpumodel.py#L158

jveitchmichaelis avatar Aug 28 '23 09:08 jveitchmichaelis

from here I have two approaches, either I can use this edgetpu model provided by ultralytics or I can quantize the savedtf model to INT8 only using tflite converter with a calibration dataset. The above error is of 1st approach.

Arslan-Mehmood1 avatar Aug 28 '23 09:08 Arslan-Mehmood1

one thing I'm not finding good is that inference is taking a lot of time and my local cpu usage gets high when I start inference which means a part of model in being executed on my local cpu, and this thing cancels the idea of edgetpu for fast inference. :( Screenshot from 2023-08-28 14-08-41

Arslan-Mehmood1 avatar Aug 28 '23 09:08 Arslan-Mehmood1

man I would be very thankful to you for helping me in this debugging and successful execution of yolov8 on edgeTPU.

Arslan-Mehmood1 avatar Aug 28 '23 09:08 Arslan-Mehmood1

Specs of model: Model : my_yolov8_full_integer_quant_edgetpu.tflite

input: [{'name': 'serving_default_images:0', 'index': 0, 'shape': array([ 1, 1280, 1280, 3], dtype=int32), 'shape_signature': array([ 1, 1280, 1280, 3], dtype=int32), 'dtype': <class 'numpy.int8'>, 'quantization': (0.01865844801068306, -14), 'quantization_parameters': {'scales': array([0.01865845], dtype=float32), 'zero_points': array([-14], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]

output: [{'name': 'PartitionedCall:0', 'index': 462, 'shape': array([ 1, 251, 33600], dtype=int32), 'shape_signature': array([ 1, 251, 33600], dtype=int32), 'dtype': <class 'numpy.int8'>, 'quantization': (0.003920518793165684, -128), 'quantization_parameters': {'scales': array([0.00392052], dtype=float32), 'zero_points': array([-128], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]

Arslan-Mehmood1 avatar Aug 28 '23 09:08 Arslan-Mehmood1

The edgetpu compiler will tell you which bits of the model are executed on CPU, but this: [ 1, 1280, 1280, 3] is pretty large and you're probably running out of RAM on the accelerator. Try with much smaller input sizes; in this repo I could only get 224 to compile fully I think.

jveitchmichaelis avatar Aug 28 '23 09:08 jveitchmichaelis

yes I had the idea that input size is very large and edgetpu ram is only 7-8mb.

inference results: python3 detect.py --model my_yolov8_full_integer_quant_edgetpu.tflite --names label.yaml --image image.jpg INFO:EdgeTPUModel:Confidence threshold: 0.25 INFO:EdgeTPUModel:IOU threshold: 0.45 INFO:EdgeTPUModel:Loaded 247 classes INFO:EdgeTPUModel:Successfully loaded /home/arslan/nixense_vixion/learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/my_yolov8_full_integer_quant_edgetpu.tflite INFO:main:Testing on user image: image.jpg INFO:EdgeTPUModel:Attempting to load image.jpg

But I cant find any image with detections in my local repo dir. one thing I can do is print the detections received by post processing function.

Arslan-Mehmood1 avatar Aug 28 '23 09:08 Arslan-Mehmood1

You should get a JPEG out, there's a process function which is called during model.predict here:

https://github.com/jveitchmichaelis/edgetpu-yolo/blob/784d9be1bb13ce4b8b3c1bad729a02a69cca97bb/edgetpumodel.py#L131C12-L131C12

jveitchmichaelis avatar Aug 28 '23 09:08 jveitchmichaelis

Screenshot from 2023-08-28 14-35-58

Yes I've checked and understood the source code for detection.

in the working dir, there is no .jpeg file. Meanwhile, I've restarted the inference and this time detections will also be printed out in terminal. Because postprocessing and image saving can only occur if detections are not empty

Arslan-Mehmood1 avatar Aug 28 '23 09:08 Arslan-Mehmood1

If you put a print statement here: https://github.com/jveitchmichaelis/edgetpu-yolo/blob/784d9be1bb13ce4b8b3c1bad729a02a69cca97bb/edgetpumodel.py#L130

Is it generating an output path?

Though you're right, currently if there aren't any detections then nothing will be saved.

jveitchmichaelis avatar Aug 28 '23 09:08 jveitchmichaelis

as suspected

python3 detect.py --model my_yolov8_full_integer_quant_edgetpu.tflite --names label.yaml --image image.jpg INFO:EdgeTPUModel:Confidence threshold: 0.25 INFO:EdgeTPUModel:IOU threshold: 0.45 INFO:EdgeTPUModel:Loaded 247 classes INFO:EdgeTPUModel:Successfully loaded /home/arslan/learning/9_edge_tpu/yolo_edge_repo/edgetpu-yolo/my_yolov8_full_integer_quant_edgetpu.tflite INFO:main:Testing on user image: image.jpg INFO:EdgeTPUModel:Attempting to load image.jpg

Detections : []

Screenshot from 2023-08-28 14-50-50

Arslan-Mehmood1 avatar Aug 28 '23 09:08 Arslan-Mehmood1

I suggest stepping through the various models and seeing where you start to lose detections. Start with the full precision one and then check the quantised ones.

jveitchmichaelis avatar Aug 28 '23 11:08 jveitchmichaelis

alright that's one approach, but fp32 and fp16 models are useless, they won't even execute on edgeTPU, yes to check for detections getting lost, we can follow it

Arslan-Mehmood1 avatar Aug 28 '23 12:08 Arslan-Mehmood1

I would suggest ignoring the TPU for now, just check that you actually get sensible predictions on CPU for all models. Presumably the fp32 models actually work? You will get a significant drop in performance moving to quantised (8-bit), especially for small objects,but the EdgeTPU compilation process shouldn't affect the results any further.

You can also significantly lower the confidence threshold and try some of your training images to see if it helps.

jveitchmichaelis avatar Aug 28 '23 13:08 jveitchmichaelis

alright, I will follow this approach. got your point

Arslan-Mehmood1 avatar Aug 28 '23 13:08 Arslan-Mehmood1