C#加载TensorFlow Keras训练的ONNX模型输入重塑错误解决
我尝试将形状为(1, 37)的float[]数组输入到TensorFlow Keras训练并导出的ONNX模型中,模型要求的输入形状为3D的(1, 1, 37),因此我使用以下代码进行重塑,但在执行session.Run(inputs)时出现如下错误:
Microsoft.ML.OnnxRuntime.OnnxRuntimeException:
'[ErrorCode:InvalidArgument] Got invalid dimensions for input:
float_input for the following indices index: 1 Got: 1 Expected: 37
index: 2 Got: 37 Expected: 1
我的代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; var model_file = "C:/keras_model.onnx"; var session = new InferenceSession(model_file); Console.WriteLine("Hellof, World!"); // 获取输入张量名称 var inputNames = session.InputMetadata.Values; // 打印输入张量名称 foreach (var inputName in inputNames) { Console.WriteLine("Input name: " + inputName); } var inputData1 = new float[] { 1.10E+01f,4.00f,1.00f,3.00f,3.00f,8.00f,5.00f,7.00f,2.00f,7.00f,7.00f,1.00f,4.00f,3.00f,3.00f,1.00f,5.00f,0.00f,1.00f,2.30E+01f,-1.70E-01f,2.08E-01f,2.02E-01f,-1.06f,7.71E-02f,2.29E-01f,4.94E-02f,4.04E-02f,1.10E-01f,1.08E-01f,-2.29E-01f,-4.22E-01f,1.34E-02f,3.38E-01f,-3.79E-02f,2.91E+02f,2.91E+02f }; var inputTensor = new DenseTensor<float>(inputData1, new int[] { 1, 37 }); // 输入形状: (1, 37) var reshapedInput = inputTensor.Reshape(new int[] { 1, 1, 37 }); // 新形状: (1, 1, 37) var inputs = new List<NamedOnnxValue>() { NamedOnnxValue.CreateFromTensor<float>("float_input",reshapedInput), }; var results = session.Run(inputs);
解决方法
错误提示明确说明,模型实际期望的输入形状是(1, 37, 1),而非你预设的(1,1,37)。这是因为Keras导出ONNX时,维度顺序可能发生了转换(Keras默认采用channels_last维度顺序,导出ONNX时会保持该逻辑)。
你可以通过两种方式修正:
方式一:直接创建目标形状的张量
跳过中间重塑步骤,直接用输入数据生成模型期望的3D张量:var inputTensor = new DenseTensor<float>(inputData1, new int[] { 1, 37, 1 });方式二:正确重塑已有张量
如果需要先处理(1,37)形状的张量,再将其重塑为模型要求的形状:var inputTensor = new DenseTensor<float>(inputData1, new int[] { 1, 37 }); var reshapedInput = inputTensor.Reshape(new int[] { 1, 37, 1 });
原因说明
错误信息中的维度索引对应张量的各个维度:index=1对应第二个维度,模型期望该维度为37;index=2对应第三个维度,模型期望该维度为1。这意味着模型实际要求的输入形状是(batch_size, feature_count, channel),也就是(1,37,1),而非你之前理解的(1,1,37)。
内容的提问来源于stack exchange,提问作者jad

