意外的模型输出 运行 Unity 中使用 Barracuda 的 Onnx 模型

Unexpected model output running Onnx model in Unity using Barracuda

上下文

我正在尝试使用 ONNX 格式的预训练模型对 Unity 中的图像数据进行推理。该模型作为称为 modelAsset 的资产链接到 Unity 中的执行组件。我为此使用 Barracuda 版本 1.0.0 并按如下方式执行模型:

// Initialisation        
this.model = ModelLoader.Load(this.modelAsset);
this.worker = WorkerFactory.CreateWorker(WorkerFactory.Type.CSharpBurst, model);

// Loop
Tensor tensor = new Tensor(1, IMAGE_H, IMAGE_W, 3, data);        
worker.Execute(tensor);
Tensor modelOutput = worker.PeekOutput(OUTPUT_NAME);

进入输入张量(其中模型只有 1 个)的数据是 h * w 的图像数据,具有 3 个通道,RGB 值介于 -0.5 和 0.5 之间。该模型有多个输出,我在上面显示的最后一行中检索了这些输出。

预期行为

使用相同的输入数据,PyTorch 模型和转换后的 ONNX 模型在 Python(ONNXRuntime 和 PyTorch)中产生与 Unity 中的 Barracuda 相同的输出数据。

问题

在 python 中,ONNX 和 PyTorch 模型都产生相同的输出。但是,Barracuda 中相同的 ONNX 模型 运行 会产生不同的输出。不同之处主要在于我们期望热图,但梭子鱼在这些模式中始终产生介于 0.001 和 -0.0004 之间的值:

这几乎让人觉得模型权重没有正确加载。

我们发现了什么

根据 the Barracuda manual we found that if we did not set the model to inference mode in the PyTorch net before conversion (link) 转换为 ONNX 时,ONNXRuntime 在 Python 中生成了这些相同的、不正确的结果。换句话说,看起来这个推理模式保存在ONNX模型中,并且在Python中被ONNXRuntime识别,但在Barracuda中不被识别。

我们的问题

总的来说:

并且可能:

原来有2个问题。 首先,输入数据已根据 ONNX 模型维度进行编排,然而,梭子鱼期望不同方向的数据。 “原生 ONNX 数据布局是 NCHW,即通道优先。Barracuda 会自动将 ONNX 模型转换为 NHWC 布局。”因此,我们的数据被扁平化为类似于 Python 实现的数组,这造成了第一个不匹配。

其次,输入图像的Y轴倒置,导致模型无法识别任何人。

纠正这些问题后,实施工作正常!