在Unity中用Barracuda部署更新后的ONNX模型遇输入适配问题
解决Unity Barracuda中更新ONNX模型后的输入张量不匹配问题
问题分析
你遇到的AssertionException: Expected: 3 == 20错误,核心是输入张量的维度与模型期望的维度不匹配。根据你提供的信息:
- 模型Inspector显示输入
input_13的shape为(n:*, h:1, w:3, c:20) - 但实际运行时,模型期望的维度顺序或大小与你创建的张量不匹配,导致宽度(W)和通道数(C)的数值校验失败。
Barracuda中Tensor的维度顺序固定为[N, H, W, C](批量数、高度、宽度、通道数),但部分ONNX模型导出时可能存在维度顺序差异,或者Inspector的显示容易引发误解。
解决方案
1. 修正张量维度与填充逻辑
根据错误提示,模型实际期望的是宽度为20,通道数为3(与Inspector显示的W、C顺序相反)。调整代码如下:
重新定义输入Tensor
private Tensor input = new Tensor(1, 1, 20, 3); // N=1, H=1, W=20, C=3
调整数据填充逻辑
每个Vector3对应W维度的一个索引,x/y/z分别对应C维度的3个通道:
public int RunModel(Vector3[] pointCloud) { for (int i = 0; i < pointCloud.Length; i++) { // 维度顺序:[N, H, W, C] input[0, 0, i, 0] = pointCloud[i].x; input[0, 0, i, 1] = pointCloud[i].y; input[0, 0, i, 2] = pointCloud[i].z; } worker.Execute(input); // 后续处理逻辑... }
2. 验证模型实际输入维度(可选但推荐)
为了彻底确认模型的输入维度,可在加载模型时打印实际shape:
private void Start() { var model = ModelLoader.Load(modelAsset); // 打印输入张量的实际维度,格式为 (N, H, W, C) Debug.Log($"模型输入实际shape: {model.inputs[0].shape}"); worker = WorkerFactory.CreateWorker(WorkerFactory.Type.ComputePrecompiled, model); }
根据打印结果调整Tensor的创建参数,确保完全匹配。
3. 更高效的数据填充方式(可选)
如果数据量较大,可直接通过一维数组批量赋值,避免循环逐个赋值:
public int RunModel(Vector3[] pointCloud) { float[] inputData = new float[20 * 3]; // 20个点 × 3个分量 for (int i = 0; i < pointCloud.Length; i++) { int index = i * 3; inputData[index] = pointCloud[i].x; inputData[index + 1] = pointCloud[i].y; inputData[index + 2] = pointCloud[i].z; } // 用数组直接初始化Tensor,维度对应[N, H, W, C] using (var input = new Tensor(1, 1, 20, 3, inputData)) { worker.Execute(input); // 后续处理... } }
关键原因说明
你之前的代码中,Tensor创建为(1,1,3,20),即W=3、C=20,但模型实际期望的是W=20、C=3,导致维度校验时触发3 == 20的断言失败。这种情况通常是因为ONNX模型导出时的维度顺序与Barracuda的默认[N,H,W,C]顺序不一致,或者Inspector的显示标注容易混淆W和C的含义。
内容的提问来源于stack exchange,提问作者Apfelbox
相关产品推荐
相关产品推荐

