You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity Sentis运行自定义训练的YOLOv9s ONNX模型时触发IndexError轴越界问题求助

Unity Sentis运行自定义训练的YOLOv9s ONNX模型时触发IndexError轴越界问题求助

嘿,我之前刚好踩过类似的坑,来给你捋捋可能的原因和解决办法!

首先,这个错误大概率是Sentis自带的YOLO后处理逻辑和你的模型输出形状不兼容导致的。Sentis默认的YOLO后处理钩子是针对标准YOLO输出形状设计的,而你自定义训练的YOLOv9s输出是(1,7,7581),这个3维形状和Sentis预期的可能不一样——比如它可能默认期待输出是4维张量(包含锚框维度的那种),但你的输出没有第4维,所以它去访问axis=3的时候就直接越界了。

给你几个具体的解决方向:

1. 绕过Sentis自带的后处理,自己写推理逻辑

这是最直接的办法,毕竟自定义模型的输出格式往往和官方预设的不一样。你可以在Unity里这么做:

  • 导入ONNX模型后,不要用Sentis提供的YOLO后处理工具类(比如YoloPostProcess之类的)
  • 直接获取模型推理的原始输出张量,然后自己解析这个(1,7,7581)的形状:其中7对应的应该是[x,y,w,h,conf,class1,class2,...](具体看你训练时的类别数),7581是检测框的数量
  • 自己写代码过滤置信度、NMS(非极大值抑制)这些步骤,完全控制后处理流程,就不会触发Sentis的预设逻辑了

2. 导出ONNX时调整输出格式,匹配Sentis的预期

如果你还是想用Sentis的后处理,那得在导出ONNX的时候做调整:

  • 导出时试试加上--simplify参数,也就是yolo export format=onnx opset=15 simplify=True,简化ONNX模型的结构,可能会修正输出张量的维度标识
  • 或者在PyTorch里手动把输出张量reshape成Sentis期待的格式再导出,比如把你的(1,7,7581)转置成(1,7581,7),这样张量就变成了3维但维度顺序更贴合常规YOLO输出,再导出ONNX后Sentis的后处理逻辑可能就能识别了

3. 自定义训练YOLOv9s转ONNX的最佳实践

给你几个我总结的坑点:

  • 导出ONNX时一定要指定和Unity推理时一致的输入形状,比如你这里用的(1,3,448,640),在Unity里加载模型后也要确保输入张量的形状完全匹配,不要动态改尺寸
  • 尽量用opset=13或者15,这两个版本和Sentis的兼容性最好,别用太新的opset
  • 导出后可以用Netron工具打开ONNX模型,检查输出张量的形状和维度,确保没有奇怪的动态维度(Sentis对动态维度的支持还不太稳定)
  • 导出后先在PyTorch里测试ONNX模型的推理结果,和原始.pt模型对比一致后再导入Unity,提前排除模型导出的问题

另外,你可以先在Unity里写个简单的测试脚本,只做模型推理,不加载任何后处理,看看能不能正常拿到输出张量。如果能拿到,那肯定就是后处理的问题;如果还是报错,那可能是ONNX模型本身的导出有问题,得回去检查导出命令。

希望这些能帮到你,要是还有问题可以再补充细节!

内容来源于stack exchange

火山引擎 最新活动