Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.1k views
in Technique[技术] by (71.8m points)

.net - How to translate the intro ML.Net demo to F#?

I'm looking at a the cs file here: https://www.microsoft.com/net/learn/apps/machine-learning-and-ai/ml-dotnet/get-started/windows and in my attempt to translate it to F# it compiles just fine but throws a System.Reflection.TargetInvocationException when run: FormatException: One of the identified items was in an invalid format. What am I missing?

Editted: Was using records before

open Microsoft.ML
open Microsoft.ML.Runtime.Api
open Microsoft.ML.Trainers
open Microsoft.ML.Transforms
open System

type IrisData = 
    [<Column("0")>] val mutable SepalLength : float
    [<Column("1")>] val mutable SepalWidth : float
    [<Column("2")>] val mutable PetalLength : float
    [<Column("3")>] val mutable PetalWidth : float
    [<Column("4");ColumnName("Label")>] val mutable Label : string

    new(sepLen, sepWid, petLen, petWid, label) = 
        { SepalLength = sepLen
          SepalWidth = sepWid
          PetalLength = petLen
          PetalWidth =  petWid
          Label = label }

type IrisPrediction = 
    [<ColumnName("PredictedLabel")>] val mutable PredictedLabels : string
    new() = { PredictedLabels = "Iris-setosa" }


[<EntryPoint>]
let main argv = 
    let pipeline = new LearningPipeline()
    let dataPath = "iris.data.txt"
    pipeline.Add(new TextLoader<IrisData>(dataPath,separator = ","))
    pipeline.Add(new Dictionarizer("Label"))
    pipeline.Add(new ColumnConcatenator("Features", "SepalLength", "SepalWidth", "PetalLength", "PetalWidth"))
    pipeline.Add(new StochasticDualCoordinateAscentClassifier())
    pipeline.Add(new PredictedLabelColumnOriginalValueConverter(PredictedLabelColumn = "PredictedLabel") )    
    let model = pipeline.Train<IrisData, IrisPrediction>()


    let prediction = model.Predict(IrisData(3.3, 1.6, 0.2, 5.1,""))

    Console.WriteLine("Predicted flower type is: {prediction.PredictedLabels}")

    0 // return an integer exit code
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You may find below a working F# version of code for the ML tutorial, using Microsoft.ML 0.1.0 (might break with newer versions). Two major differences from your code that make the sample work are both within IrisData and IrisPredictiontype definitions:

  • Accurate presentation of C# POCO in F# having parameterless constructor and public access to the fields
  • Correct porting of C# float to F#, which is float32

Here is the code

open Microsoft.ML
open Microsoft.ML.Runtime.Api
open Microsoft.ML.Trainers
open Microsoft.ML.Transforms
open System

type IrisData() =
    [<Column("0")>]
    [<DefaultValue>]
    val mutable public SepalLength: float32
    [<DefaultValue>]
    [<Column("1")>]
    val mutable public SepalWidth: float32
    [<DefaultValue>]
    [<Column("2")>]
    val mutable public PetalLength:float32
    [<DefaultValue>]
    [<Column("3")>]
    val mutable public PetalWidth:float32
    [<DefaultValue>]
    [<Column("4")>]
    [<ColumnName("Label")>]
    val mutable public Label:string

type IrisPrediction() =
    [<ColumnName("PredictedLabel")>]
    [<DefaultValue>]
    val mutable public PredictedLabel : string

[<EntryPoint>]
let main argv =
    let pipeline = new LearningPipeline()
    let dataPath = "iris.data.txt"
    let a = IrisPrediction()
    pipeline.Add(new TextLoader<IrisData>(dataPath,separator = ","))
    pipeline.Add(new Dictionarizer("Label"))
    pipeline.Add(new ColumnConcatenator("Features", "SepalLength", "SepalWidth", "PetalLength", "PetalWidth"))
    pipeline.Add(new StochasticDualCoordinateAscentClassifier())
    pipeline.Add(new PredictedLabelColumnOriginalValueConverter(PredictedLabelColumn = "PredictedLabel") )    
    let model = pipeline.Train<IrisData, IrisPrediction>()

    let x = IrisData()
    x.SepalLength <- 3.3f
    x.SepalWidth <- 1.6f
    x.PetalLength <- 0.2f
    x.PetalWidth <- 5.1f
    let prediction = model.Predict(x)

    printfn "Predicted flower type is: %s"  prediction.PredictedLabel

    0

and the output it produces:

Automatically adding a MinMax normalization transform, use 'norm=Warn' or 'norm=No' to turn this behavior off.
Using 4 threads to train.
Automatically choosing a check frequency of 4.
Auto-tuning parameters: maxIterations = 9996.
Auto-tuning parameters: L2 = 2.668802E-05.
Auto-tuning parameters: L1Threshold (L1/L2) = 0.
Using best model from iteration 892.
Not training a calibrator because it is not needed.
Predicted flower type is: Iris-virginica
Press any key to continue . . .

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...