ML.NET入门Demo转F#后编译通过但运行报错,求问题排查
解决ML.NET F#代码运行时的FormatException问题
你的代码里有几个关键问题可能导致了这个格式错误,我来帮你逐一梳理修复:
1. 测试数据的参数顺序完全错误
你调用预测方法时传入的测试数据参数顺序和构造函数定义不匹配,而且数值完全不符合鸢尾花的特征范围!你的构造函数参数是sepLen, sepWid, petLen, petWid, label,但你把PetalWidth设成了5.1——鸢尾花的花瓣宽度最大值通常不会超过2.5,这个数值明显异常,会触发ML.NET的数据有效性检查错误。
换成符合鸢尾花setosa品种的典型特征数据:
let prediction = model.Predict(IrisData(5.1, 3.5, 1.4, 0.2,""))
2. F#类型定义要使用标准CLR属性
ML.NET的反射机制更适配标准的CLR属性,你当前用的val mutable字段可能无法被ML.NET正确识别(尤其是列属性的映射逻辑)。把类型改成F#属性语法:
type IrisData() = [<Column("0")>] member val SepalLength = 0.0 with get, set [<Column("1")>] member val SepalWidth = 0.0 with get, set [<Column("2")>] member val PetalLength = 0.0 with get, set [<Column("3")>] member val PetalWidth = 0.0 with get, set [<Column("4"); ColumnName("Label")>] member val Label = "" with get, set type IrisPrediction() = [<ColumnName("PredictedLabel")>] member val PredictedLabels = "" with get, set
这种写法能确保ML.NET通过反射正常读写字段值,避免因类型访问问题抛出异常。
3. 明确TextLoader的无表头配置
iris.data文件通常没有表头,你需要给TextLoader加上hasHeader = false的明确配置,避免ML.NET误把第一行数据当成表头解析:
pipeline.Add(new TextLoader<IrisData>(dataPath, separator = ",", hasHeader = false))
同时还要确保你的iris.data.txt文件格式完全正确:每行是5个逗号分隔的项,前四个是浮点数,最后一个是品种字符串(比如5.1,3.5,1.4,0.2,Iris-setosa),没有空行或格式错误的行。
修改后的完整可运行代码
整合所有调整后的代码如下:
open Microsoft.ML open Microsoft.ML.Runtime.Api open Microsoft.ML.Trainers open Microsoft.ML.Transforms open System type IrisData() = [<Column("0")>] member val SepalLength = 0.0 with get, set [<Column("1")>] member val SepalWidth = 0.0 with get, set [<Column("2")>] member val PetalLength = 0.0 with get, set [<Column("3")>] member val PetalWidth = 0.0 with get, set [<Column("4"); ColumnName("Label")>] member val Label = "" with get, set type IrisPrediction() = [<ColumnName("PredictedLabel")>] member val PredictedLabels = "" with get, set [<EntryPoint>] let main argv = let pipeline = LearningPipeline() let dataPath = "iris.data.txt" pipeline.Add(TextLoader<IrisData>(dataPath, separator = ",", hasHeader = false)) pipeline.Add(Dictionarizer("Label")) pipeline.Add(ColumnConcatenator("Features", "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")) pipeline.Add(StochasticDualCoordinateAscentClassifier()) pipeline.Add(PredictedLabelColumnOriginalValueConverter(PredictedLabelColumn = "PredictedLabel")) let model = pipeline.Train<IrisData, IrisPrediction>() // 使用标准的鸢尾花测试数据 let testData = IrisData() testData.SepalLength <- 5.1 testData.SepalWidth <- 3.5 testData.PetalLength <- 1.4 testData.PetalWidth <- 0.2 let prediction = model.Predict(testData) Console.WriteLine($"Predicted flower type is: {prediction.PredictedLabels}") 0 // return an integer exit code
按照这些调整修改后,应该就能解决你遇到的FormatException问题了。
内容的提问来源于stack exchange,提问作者red-swan
相关产品推荐
相关产品推荐

