Отладка F #, которая просто зависает - PullRequest
0 голосов
/ 19 июня 2020

Можно ли отлаживать F # или, как LINQ в C#, это фактически невозможно?

Я работаю над проектами машинного обучения для. NET разработчиков и я впервые использую F #.

Я попытался отредактировать пример упражнения. Версию C# было легко запустить, но моя попытка с версией F # просто зависла.

Что я могу сделать, чтобы отследить проблему?

open System.IO

type Observation = { Label:string; Pixels: int[] }
type Distance = int[] * int[] -> int
type Classifier = int[] -> string

let toObservation (csvData:string) =
    let columns = csvData.Split(',')
    let label = columns.[0]
    let pixels = columns.[1..] |> Array.map int
    { Label = label; Pixels = pixels }

let reader path = 
    let data = File.ReadAllLines path
    data.[1..]
    |> Array.map toObservation

let trainingPath = __SOURCE_DIRECTORY__ + @"../../Data/trainingsample.csv"
let training = reader trainingPath

let manhattanDistance (pixels1,pixels2) =
    Array.zip pixels1 pixels2
    |> Array.map (fun (x,y) -> abs (x-y))
    |> Array.sum

let euclideanDistance (pixels1,pixels2) =
    Array.zip pixels1 pixels2
    |> Array.map (fun (x,y) -> pown (x-y) 2)
    |> Array.sum

let dotCountDistance(pixels1, pixels2) =
    let t1 = pixels1 |> Array.map (fun(z) -> if z > 128 then 1 else 0) |> Array.sum
    let t2 = pixels2 |> Array.map (fun(z) -> if z > 128 then 1 else 0) |> Array.sum
    abs(t1 - t2)


let train (trainingset:Observation[]) (dist:Distance) =
    let classify (pixels:int[]) =
        trainingset
        |> Array.minBy (fun x -> dist (x.Pixels, pixels))
        |> fun x -> x.Label
    classify

//
// This is my new function 
//
let train2 (trainingset:Observation[]) (dist:Distance) =
    let classify (pixels:int[]) =
        trainingset
        |> Array.map (fun(z) -> dist(z.Pixels, pixels), z.Label)
        |> Array.groupBy(fun (a, y) -> y)
        |> Array.map(fun (lbl, ds) -> lbl, (ds |> Array.map(fun (p, q) -> p) |>  Array.sum ) * 100 / (ds |> Array.length))
        |> Array.sortByDescending( fun (lbl, s) -> s)
        |> fun z -> z.[0]
        |> fun (lbl, s) -> lbl
    classify
//
//
//


let validationPath = __SOURCE_DIRECTORY__ + @"../../Data/validationsample.csv"
let validation = reader validationPath

let evaluate validationSet classifier = 
    validationSet
    |> Array.averageBy (fun x -> if classifier x.Pixels = x.Label then 1. else 0.)
    |> printfn "Correct: %.3f"

let manhattanModel = train training manhattanDistance
let euclideanModel = train training euclideanDistance
let dotCountModel = train training dotCountDistance

let manhattanModel2 = train2 training manhattanDistance
let euclideanModel2 = train2 training euclideanDistance
let dotCountModel2 = train2 training dotCountDistance

printfn "Manhattan"
evaluate validation manhattanModel // <------------------- This just hangs.
printfn "Euclidean"
evaluate validation euclideanModel
printfn "Dot Count"
evaluate validation dotCountModel

// Illustration: full distance function

let d (X,Y) = 
    Array.zip X Y 
    |> Array.map (fun (x,y) -> pown (x-y) 2) 
    |> Array.sum 
    |> sqrt

Вот, y C# версия, которая работает

            return data.Select(z => new { z.Label, D = distance.Between(z.Pixels, pixels) })
                .GroupBy(z => z.Label)
                .Select(z => new { Label = z.Key, MeanDistance = z.Average(y => y.D) })
                .OrderBy(z => z.MeanDistance).First()
                .Label;

1 Ответ

1 голос
/ 19 июня 2020

Вы можете отлаживать скрипт в F # Interactive (сначала убедитесь, что у вас включена эта опция).

У меня было то же поведение, что и вы, он зависает. Я запустил тот же код, что и консольная программа, и он запустился за несколько секунд. (Результат был «Правильно: 0,934»). Итак, я считаю, что это проблема, возможно, ошибка F # Interactive.

...