来自 tflite 解释器的输出张量被压缩

Output tensor from tflite interpreter is squeezed

我正在尝试在 Coral EdgeTPU 上将 YOLOv5s 模型 运行。我按照 YOLOv5 存储库中的 instructions 从 yolov5s.pt 模型转换为 yolov5s-int8_edgetpu.tflite 模型。

克隆 pycoral repository 后,他们提供了一个 detect_image.py 脚本。使用他们的模型时,脚本执行时没有错误。

如果我 运行 与我的 yolov5s-int8_edgetpu.tflite 模型使用相同的脚本,我会收到此错误:

  File "examples/detect_image.py", line 108, in <module>
    main()
  File "examples/detect_image.py", line 87, in main
    objs = detect.get_objects(interpreter, args.threshold, scale)
  File "/usr/lib/python3/dist-packages/pycoral/adapters/detect.py", line 214, in get_objects
    elif common.output_tensor(interpreter, 3).size == 1:
  File "/usr/lib/python3/dist-packages/pycoral/adapters/common.py", line 29, in output_tensor
    return interpreter.tensor(interpreter.get_output_details()[i]['index'])()
IndexError: list index out of range

推理没有任何问题,但是 post 数据处理是我遇到的问题。 出现这个错误的原因是输出tensor的shape与pycoral提供的脚本不兼容。他们期望形状为 [4x6300x85],而我的形状为 [1x25200x85].

输入 yolov5s的详细信息-int8_edgetpu.tflite:

{'name': 'serving_default_input_1:0', 'index': 547, 'shape': array([  1, 640, 640,   3], dtype=int32), 'shape_signature': array([  1, 640, 640,   3], dtype=int32), 'dtype': <class 'numpy.uint8'>, 'quantization': (0.003921568859368563, 0), 'quantization_parameters': {'scales': array([0.00392157], dtype=float32), 'zero_points': array([0], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]

输入 EfficientDetLite2 model的详细信息(从 TFhub 下载):

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

输出 yolov5s的详细信息-int8_edgetpu.tflite:

{'name': 'StatefulPartitionedCall:0', 'index': 548, 'shape': array([    1, 25200,    85], dtype=int32), 'shape_signature': array([    1, 25200,    85], dtype=int32), 'dtype': <class 'numpy.uint8'>, 'quantization': (0.004499140195548534, 1), 'quantization_parameters': {'scales': array([0.00449914], dtype=float32), 'zero_points': array([1], dtype=int32), 'quantized_dimension': 0}, 'sparsity_parameters': {}}]

输出 EfficientDetLite2 model 的详细信息(从 TFhub 下载):

{'name': 'StatefulPartitionedCall:3', 'index': 782, 'shape': array([ 1, 25,  4], dtype=int32), 'shape_signature': array([ 1, 25,  4], 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': {}}, 

{'name': 'StatefulPartitionedCall:2', 'index': 783, 'shape': array([ 1, 25], dtype=int32), 'shape_signature': array([ 1, 25], 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': {}}, 

{'name': 'StatefulPartitionedCall:1', 'index': 784, 'shape': array([ 1, 25], dtype=int32), 'shape_signature': array([ 1, 25], 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': {}}, 

{'name': 'StatefulPartitionedCall:0', 'index': 785, 'shape': array([1], dtype=int32), 'shape_signature': array([1], 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': {}}]

EfficientDet 模型有 4 个输出张量,每个张量分别代表边界框、class_ids、分数和计数。

Yolov5s 模型似乎只是将所有这些都压缩到同一个张量中,没有任何区别。

我认为错误可能出在模型的转换上,但也可能是 Yolov5 模型旨在将所有输出张量压缩为一个。

如果有人遇到过这种情况或对如何进行有建议,我将不胜感激。

由于 Yolov5s 模型的输入文件与 EfficientDet 不同,因此输出张量会有所不同。这里的技巧是理解如何处理这个输出张量。

幸运的是,Ultralytics/Yolov5 进行了导出 competition,其目标是在 EdgeTPU 设备上执行 Yolov5 模型。

This guy Josh won the coral devboard section. He wrote python library to process these wonky tensor outputs from Yolov5s models. Here is the repo. The real processing of the output tensor is done in his non-max-suppression代码。

forked 他的回购并添加了 execute/process 这些 Yolov5s 模型在桌面上的能力。

非常感谢乔希!