Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Arslan-Mehmood1 opened this issue Aug 25, 2023 · 29 comments

Comments

@Arslan-Mehmood1
Copy link

Arslan-Mehmood1 commented Aug 25, 2023

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.

@jveitchmichaelis
Copy link
Owner

How many classes does your model have?

@Arslan-Mehmood1 Arslan-Mehmood1 changed the title Ultralytics Yolov8 tflite edgetpu model inference on Coral USB Accelerator Unable to interpret prediction values by Ultralytics Yolov8 tflite edgetpu model inference on Coral USB Accelerator Aug 25, 2023
@Arslan-Mehmood1
Copy link
Author

it has 247 classes. label.txt

@jveitchmichaelis
Copy link
Owner

jveitchmichaelis commented Aug 25, 2023 via email

@Arslan-Mehmood1
Copy link
Author

Arslan-Mehmood1 commented Aug 25, 2023

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).

@jveitchmichaelis
Copy link
Owner

jveitchmichaelis commented Aug 25, 2023

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
Copy link
Owner

Also see ultralytics/ultralytics#751

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

@jveitchmichaelis
Copy link
Owner

jveitchmichaelis commented Aug 25, 2023 via email

@Arslan-Mehmood1
Copy link
Author

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
Copy link
Author

Arslan-Mehmood1 commented Aug 25, 2023

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

@jveitchmichaelis
Copy link
Owner

jveitchmichaelis commented Aug 25, 2023 via email

@jveitchmichaelis
Copy link
Owner

jveitchmichaelis commented Aug 25, 2023 via email

@Arslan-Mehmood1
Copy link
Author

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.

@jveitchmichaelis
Copy link
Owner

jveitchmichaelis commented Aug 28, 2023

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

@Arslan-Mehmood1
Copy link
Author

Arslan-Mehmood1 commented Aug 28, 2023

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.

@jveitchmichaelis
Copy link
Owner

You can try just changing the cast to np.int8 here:

x = x[np.newaxis].astype(np.uint8)

@Arslan-Mehmood1
Copy link
Author

Arslan-Mehmood1 commented Aug 28, 2023

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
Copy link
Author

Arslan-Mehmood1 commented Aug 28, 2023

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
Copy link
Author

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

@Arslan-Mehmood1
Copy link
Author

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': {}}]

@jveitchmichaelis
Copy link
Owner

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.

@Arslan-Mehmood1
Copy link
Author

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.

@jveitchmichaelis
Copy link
Owner

jveitchmichaelis commented Aug 28, 2023

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

@Arslan-Mehmood1
Copy link
Author

Arslan-Mehmood1 commented Aug 28, 2023

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

@jveitchmichaelis
Copy link
Owner

jveitchmichaelis commented Aug 28, 2023

If you put a print statement here:

output_path = base + "_detect" + ext

Is it generating an output path?

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

@Arslan-Mehmood1
Copy link
Author

Arslan-Mehmood1 commented Aug 28, 2023

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

@jveitchmichaelis
Copy link
Owner

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.

@Arslan-Mehmood1
Copy link
Author

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

@jveitchmichaelis
Copy link
Owner

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.

@Arslan-Mehmood1
Copy link
Author

alright, I will follow this approach. got your point

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants