This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] SK-AM62A-LP:使用 edgeai-gst-apps 时的低检测精度

Guru**** 2667245 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1582729/sk-am62a-lp-low-detection-accuracy-using-edgeai-gst-apps

器件型号: SK-AM62A-LP

TI 团队大家好、

我一直尝试使用我的 yolox-nano 模型、该模型使用 edgeai-modelmaker 进行了默认配置和自定义数据集训练。 我编译 tensor_bits 设置为 16 位的模型。 我提到了使用该自定义模型执行推理的 2 个选项:  

  1. 来自 edgeai-tidl-tools/examples 的 onnx_ep.py 脚本
  2. 通过 edgeai-gst-apps 使用我的模型。

我尝试了两个 SDK 版本 — r10.1(在上安装了 r11.0 tidl 工具)和 r11.1。 我已经在两者上使用相同的方法训练了模型。 使用 onnx_ep.py 执行推理时、我可以看到如下预测-  

使用 r10.1 进行预测(在上安装了 r11.0 tidl 工具)-  

py_out__frame_002.jpg py_out__frame_003.jpg

使用 r11.1 进行预测-  

py_out__frame_002.jpg py_out__frame_003.jpg

当我想使用 edgeai-gst-apps/apps_python/app_edgeai.py 中使用的 gstreamer 流水线执行推理时、会出现问题。 以下是在同一映像上运行 app_edgeai.py 后生成的图像作为输出-

r11.1 app_edgeai.py 上的预测

output_frame_002.jpg

output_frame_003.jpg

我倾向于认为这两种方法对输入法使用不同的预处理。 我希望使用 app_edgeai.py 中的 gstreamer 流水线来获得相同/相似的结果、而不是使用 onnx_ep.py 基于 onnx 的推理、以确保我以应用程序优先级实时地尽快运行流水线。

好极了

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好:

    此处可能会导致输入数据预处理、但也可能是后处理。 如果您使用 python 应用程序、也可以从 infer_pipe.py 访问 AI 模型的数据输入和输出[1]。 我建议打印或查看其中一些数据、并在 onnxrt_ep.py 和 app_edgeai.py 之间进行比较。  

    模型的预处理和后处理规格将来自模型工件附近的 param.yaml 文件。 您能否提供该 param.yaml、您用于 edgeai-tidl-tools/examples/osrt_pythm/onnxrt_ep.py 的 model_config.py 条目、以及运行 app_edgeai.py 时打印到终端的输出? 还请提供与 app_edgeai.py 一起使用的 YAML 配置文件

    • 对于 app_edgeai.py 输出、我主要对 gstreamer 流水线本身感兴趣。 应该有一些预处理参数直接用在那里。  
    • 请注意、如果您使用 modelmaker 进行训练、它可能已在模型的开头添加了几层、以便它接收 uint8 并为您处理预处理(意味着均值减法和缩放乘法)
    • 或者、它可以是阻止输出可视化的 vizualization-threshold。 该参数可由 app_edgeai.py 使用的配置 YAML 提供

    [1] https://github.com/TexasInstruments/edgeai-gst-apps/blob/799dcbda54f829eb7b234bf93a5669addcc1b919/apps_python/infer_pipe.py#L110 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好:

    因此、我看到的一个区别是:  

    param.yaml 包含“ input_data_layout :nCHW“

    打印的 GST 字符串包括 “tiovxdlpreproc out-pool-size=4 tensor-format=1“

    • 使用“GST-CHECK-1.0 tiovxdlpreproc“进行分析、我看到此插件认为 tensor-format=1 表示 NHWC 而不是 NCHW。
      • 这表明 gstreamer 流水线的预处理在存储器中的张量布局与模型预期的不同。 如果使用 ONNX API 但不使用 gstreamer 获得正确结果、这可能是根本原因。  

    这表明 app_edgeai.py(和依赖项)解析 param.yaml 的方式存在问题、因此使用了错误的张量格式。  我叫 curiousif edgeai-gst-apps OptiFlow 和 apps_cpp 具有相同的效果。 在建议修改源代码之前、我会尝试使用这些工具。  

    这将是奇怪的,因为它应该是相同的 param.yaml 文件,我们在模型动物园中看到。  

    编辑:让我取消这个——我看的是张量格式而不是通道顺序。 让我更仔细地查看并提供更多意见

    BR、
    Reese

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    否则我不会看到明显的问题。 我将提出以下建议:

    -在 ONNXrt_EP.py 中,在将输入张量传递到 ONNX 之前打印输入张量。 最小值和最大值是多少? 您看到图像角的像素值是什么

    -在 infer_pipe.py 的 edgeai-gst-apps 中,打印从 gstreamer 管道中提取的张量。 执行与上述相同的分析。 像素值是否在相同范围内? 他们是否完全不同? 由于您有静态图像、因此甚至可以比较单个像素、尽管它们可能不会匹配位。  

    -类似地,在 generate_pipe.py 中,在模型运行后打印结果的输出。 是否存在任何问题? 您的可视化阈值非常低、因此我假设它几乎为空或仅包含空检测、但让我们确认一下。  

    我还建议使用 edgeai-gst-apps/apps_cpp 或 edgeai-gst-apps/OptiFlow 尝试相同的 YAML.config。 在这里看到不同的结果是很奇怪的,但也许情况就是这样。  

    我注意到您的 REVERSE_CHANNES=True、因此图像将作为 BGR 而不是 RGB 处理。 这就是 tiovxdlpreproc 上的 tensor-format 将执行的操作。 这不应该是问题的根源、因为许多网络至少会对这两种格式进行有效检测、尽管准确度不是最佳

    您的模型工件文件夹是否具有 dataset.yaml? 您能展示一下吗?

    我注意到 param.yaml 中的 num_class = null。 这也是可疑的... 也许这会导致一些后处理被跳过、因为来自模型输出的类 ID 将始终超出[0、num_classs]的范围

    BR、
    Reese

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Akash:

    onnxrt_ep.py 和 app_edgeai.py 之间的区别非常明显。 视觉效果会有所帮助。 我认为这是用于每个.py 脚本的完全相同的模型工件集、是吗?

    我的 config.yaml
    中的值

    input_optimization 部分意味着模型中的前几层处理输入预处理、即均值减法和乘法比例。 看起来像您的模型假设这些运算不是模型本身的一部分 (input_optimization=false)、更重要的是它们是统一的(该运算不会更改数据)。 model_zoo 版本在开始时是否输入 cast->add->mul 层序列? 这里的常量值是否也分别是 0 和 1.0、分别表示 ADD(平均值)和 MUL(标度)? 在我这边可以看到 Mean=0 和 Scale=1

    重新调整列表部分不应该是问题。

    我强烈建议分析模型的数字输出,以确保 X、Y 坐标和置信值的范围是现实的。 似乎您已适当地将 viz_threshold 设置得非常低、但我想确保这实际上是预处理、而不是后处理

    您能否通过模型工件并告知您正在使用的 SDK 版本? 我也可以看一下。  

    BR、
    Reese

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Reese:

    onnxrt_ep.py 和 app_edgeai.py 之间的区别非常明显。 视觉效果会有所帮助。 我认为这是用于每个.py 脚本的完全相同的模型工件集、是吗?

    onnxrt_ep.py 和 APP_edgeai.py 使用了完全相同的参数。

    似乎平均值=0、比例=1。 从我使用的 model_zoo 附加 model.onnx 中的一些图层屏幕截图-

    1.添加图层

    2.泥浆层

    通过与使用 edgeai-modelmaker 和自定义数据集训练的 yolox-nano-lite 模型进行比较、它没有如下所示的相同 Add 和 Mul Layers -  

    我想像你说的那样分析数字输出,但是如果你能让我知道应该分析管道中的确切阶段,这将是很大的帮助(如果可能的话 ,用推理帮助理解直觉)。

    我不能在这个公共论坛上分享模型工件,但我想用任何其他私人方法与你分享它。 我仍乐意 稍后在这公开论坛上公布我们分析的一般性结果。 请建议您使用更安全和更私密的方式与您共享我的文件。

    谢谢你

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Akash:  

    好的、因此预处理确认是相同的。 由于您在两种情况下使用了相同的输入图像、因此它也很有用。 我倾向于后处理成为问题。  

    您可以修改 infer_pipe.py 文件以打印结果[1]。 这里可能会有两个输出张量。  

    对于 onnxrt_ep.py、该输出张量在此处[2]

    [报价 userid=“658004" url="“ url="~“~/support/processors-group/processors/f/processors-forum/1582729/sk-am62a-lp-low-detection-accuracy-using-edgeai-gst-apps/6137647

    通过与使用 edgeai-modelmaker 和自定义数据集训练的 yolox-nano-lite 模型进行比较、它没有如下所示的相同 Add 和 Mul Layers -  

    [/报价]

    这可能是假设您在模型之外进行预处理。 只要您的平均值和比例设置相同、我就看不到任何问题。  

    [1] https://github.com/TexasInstruments/edgeai-gst-apps/blob/c6b3ce5e2a6c9d46a6a66af02f858059a24c400b/apps_python/infer_pipe.py#L110 

    [2] https://github.com/TexasInstruments/edgeai-tidl-tools/blob/e70106c59a5bec5a4f794b81b88534279b8a2312/examples/osrt_python/ort/onnxrt_ep.py#L215 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Akash:  

    我已通过您的一位同事获得了您的模型、并且能够重现此问题。 即使在我自己的几个测试脚本中、我也能从您的模型中看到合理的输出张量、但在 derefine_pipe.py 内、我也看到零良好检测。 事实上,这不仅仅是你一方的问题。

    我在 infer_pipe.py 中拉张量并重新排序张量以恢复图像。 我注意到、当我这样做的时候、重建有大量的柱状文物--看看这些文物的每一个看起来是如何断断续续的。  下面是我从 infer_pipe.py 中提取这些数据的代码片段,在 pipeline () 函数中调用

                if self.pre_proc_debug:
                    self.pre_proc_debug.log(str(input_img.flatten()))
                if True: #block of added code, will produce errors on non-ONNX models
                    input_img2 = input_img.copy()
                    input_img2 = np.transpose(input_img2, (0,2,3,1))
                    input_img2 = np.squeeze(input_img2)
                    import cv2
                    cv2.imwrite('/root/model-test/in-tensor-gst.png', input_img2.astype( np.uint8))
    
                # Inference
                start = time()
                result = self.run_time(input_img)

    我在/opt/model_zoo.下运行了一个与您的模型和基线 OD-8200 模型相同的管道 唯一的区别是 model_zoo 版本将 uint8 作为输入、而您的版本则采用浮点。 tiovxdlpreproc 插件中可能存在一个错误、因为所有其他插件都是相同的。

    我建议的权变措施是修改模型、使其使用前几层将转换、均值减法和比例乘法应用为模型层(从技术上讲,您的模型只需要从 uint8-float32 进行“转换“,因为预处理值是单位预处理)。 然后、该模型将获取 uint8 输入(这也是通过降低 DDR 负载提高性能!) 我预计这个问题不会持续存在。  

    这可以在生成.ONNX 模型后完成,我们有 python 脚本,将这些图层添加到图的开头[1][2]。 请尝试一下、让我知道这是如何变化的

    [1] https://github.com/TexasInstruments/edgeai-tidl-tools/blob/f73a576f5610a5011b83de05c9e30081c895b752/osrt-model-tools/osrt_model_tools/onnx_tools/tidl_onnx_model_utils/onnx_model_opt.py#L65 --函数本身

    [2] https://github.com/TexasInstruments/edgeai-tidl-tools/blob/e70106c59a5bec5a4f794b81b88534279b8a2312/examples/osrt_python/common_utils.py#L293 ——在脚本中调用它——它通常只在下载模型时运行一次,但你可以在 Python 中快捷方式这个逻辑