在ML.NET中加载导出的TensorFlow Keras冻结图模型时遍历预测结果报错的技术求助
Let's break down the potential issues with your code and fix them step by step:
1. Input Data Type Mismatch
Your TensorFlow model was trained with integer inputs, but there's a high chance the input dtype in the frozen graph is int32 (not int64/long which you're using in ML.NET). TensorFlow is strict about dtype matching, so this mismatch can cause silent failures or errors during inference.
Fix:
Change the input type in TensorData from long[] to int[]:
public class TensorData { [ColumnName(@"x")] // Make sure this matches your model's actual input node name! [VectorType(2)] public int[] input { get; set; } // Use int instead of long }
2. Output Type Mismatch
Your Keras model outputs a single value (Dense(units=1)), so the Identity node in the frozen graph returns a scalar tensor per sample. However, you're mapping it to a float[] in OutputScores, which expects an array—this will cause a deserialization error when you try to iterate over results.
Fix:
Change the output type from float[] to float:
class OutputScores { [ColumnName(@"Identity")] public float output { get; set; } // Single float instead of array }
3. Verify Input Node Name
Your ML.NET code uses "x" as the input node name, but TensorFlow often assigns default names like "input_1" to Keras model inputs. If the names don't match, ML.NET can't feed data into the model.
How to check in Python:
Run this snippet to get your model's actual input node name:
import tensorflow as tf frozen_graph = tf.GraphDef() with open("test/test.pb", "rb") as f: frozen_graph.ParseFromString(f.read()) # List all placeholder (input) nodes for node in frozen_graph.node: if node.op == "Placeholder": print(f"Input node name: {node.name}, dtype: {tf.as_dtype(node.attr['dtype'].type)}")
If the input name isn't "x", update the ColumnName attribute in TensorData to match (e.g., [ColumnName(@"input_1")]).
4. Batch Dimension Validation
You set addBatchDimensionInput: true in ScoreTensorFlowModel, which is correct (you used np.expand_dims in Python to add a batch dimension). Just confirm your VectorType(2) aligns with the model's expected input shape of (None, 2).
Modified Working Code
After applying the fixes above, your code should look like this (adjust input name if needed):
public class TensorData { [ColumnName(@"input_1")] // Replace with your actual input node name [VectorType(2)] public int[] input { get; set; } } public static TensorData[] GetTensorData() { return new TensorData[] { new() { input = new int[] { 0, 0 } }, new() { input = new int[] { 12, 10 } }, new() { input = new int[] { 12, 800 } } }; } class OutputScores { [ColumnName(@"Identity")] public float output { get; set; } } public static void Test() { var mlContext = new MLContext(); // Enable logging for debugging if needed mlContext.Log += (sender, e) => Console.WriteLine($"ML.NET Log: {e.Message}"); var data = GetTensorData(); var idv = mlContext.Data.LoadFromEnumerable(data); using var model = mlContext.Model.LoadTensorFlowModel(@"path to your test.pb"); var pipeline = model.ScoreTensorFlowModel( outputColumnNames: new[] { "Identity"}, inputColumnNames: new[] { "input_1" }, // Match input node name addBatchDimensionInput: true); var estimator = pipeline.Fit(idv); var transformedValues = estimator.Transform(idv); var outScores = mlContext.Data.CreateEnumerable<OutputScores>(transformedValues, reuseRowObject: false); foreach (var prediction in outScores) { Console.WriteLine($"Prediction: {prediction.output}"); } }
Final Checks
- Use an absolute path to your
test.pbfile during debugging to avoid path resolution issues. - If errors persist, the ML.NET logging (added in the code above) will give you detailed insights into what's going wrong during model loading or inference.
内容的提问来源于stack exchange,提问作者tixina3684

