Skip to content

Commit 4dcfe4d

Browse files
kevmalCESARDELATORRE
authored andcommitted
Tensorflow samples ported to F# (dotnet#233)
* F# deeplearning samples * add readmes * add F# deeplearning link * remove common and use api directly
1 parent d956d94 commit 4dcfe4d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+7265
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ The official ML.NET samples are divided in multiple categories depending on the
140140
Deep learning is a subset of machine learning. Deep learning architectures such as deep neural networks, are usually applied to fields such as computer vision (object detection, image classification, style transfer), speech recognition, natural language processing and audio recognition.
141141
</td>
142142
<td>
143-
<h4>TensorFlow with ML.NET &nbsp;&nbsp;&nbsp;<a href="samples/csharp/getting-started/DeepLearning_ImageClassification_TensorFlow">C#</a> &nbsp;&nbsp;&nbsp;<img src="images/app-type-getting-started.png" alt="Getting started icon"></h4>
143+
<h4>TensorFlow with ML.NET &nbsp;&nbsp;&nbsp;<a href="samples/csharp/getting-started/DeepLearning_ImageClassification_TensorFlow">C#</a> &nbsp; &nbsp; <a href="samples/fsharp/getting-started/DeepLearning_ImageClassification_TensorFlow">F#</a> &nbsp;&nbsp;&nbsp;<img src="images/app-type-getting-started.png" alt="Getting started icon"></h4>
144144
<h4>Object detection Coming soon &nbsp;&nbsp;&nbsp;<img src="images/app-type-getting-started.png" alt="Getting started icon"></h4>
145145
<h4>Style Transfer Coming soon &nbsp;&nbsp;&nbsp;<img src="images/app-type-e2e.png" alt="End-to-end app icon"></h4>
146146
<h4>ONNX with ML.NET - Coming soon &nbsp;&nbsp;&nbsp;<img src="images/app-type-getting-started.png" alt="Getting started icon"></h4>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.1</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Include="Program.fs" />
10+
</ItemGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="Microsoft.ML" Version="0.9.0" />
14+
<PackageReference Include="Microsoft.ML.ImageAnalytics" Version="0.9.0" />
15+
<PackageReference Include="Microsoft.ML.TensorFlow" Version="0.9.0" />
16+
</ItemGroup>
17+
18+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
open System
2+
open System.IO
3+
open Microsoft.ML
4+
open Microsoft.ML.Data
5+
open Microsoft.ML.ImageAnalytics
6+
open Microsoft.ML.Core.Data
7+
8+
let dataRoot = FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location)
9+
10+
let imageHeight = 224
11+
let imageWidth = 224
12+
let mean = 117
13+
let scale = 1
14+
let channelsLast = true
15+
[<Literal>]
16+
let OutputTensorName = "softmax2"
17+
18+
[<CLIMutable>]
19+
type ImageNetData =
20+
{
21+
[<LoadColumn(0)>]
22+
ImagePath : string
23+
[<LoadColumn(1)>]
24+
Label : string
25+
}
26+
27+
[<CLIMutable>]
28+
type ImageNetDataProbability =
29+
{
30+
ImagePath : string
31+
Label : string
32+
PredictedLabel : string
33+
Probability : float32
34+
}
35+
36+
[<CLIMutable>]
37+
type ImageNetPipeline =
38+
{
39+
ImagePath : string
40+
Label : string
41+
PredictedLabelValue : string
42+
Score : float32 []
43+
softmax2_pre_activation : float32 []
44+
}
45+
[<CLIMutable>]
46+
type ImageNetPrediction =
47+
{
48+
[<ColumnName(OutputTensorName)>]
49+
PredictedLabels : float32 []
50+
}
51+
52+
53+
let printImagePrediction (x : ImageNetPipeline) =
54+
let defaultForeground = Console.ForegroundColor
55+
let labelColor = ConsoleColor.Magenta
56+
let probColor = ConsoleColor.Blue
57+
printf "ImagePath: "
58+
Console.ForegroundColor <- labelColor
59+
printf "%s" (Path.GetFileName(x.ImagePath))
60+
Console.ForegroundColor <- defaultForeground
61+
printf " predicted as "
62+
Console.ForegroundColor <- labelColor
63+
printf "%s" x.PredictedLabelValue
64+
Console.ForegroundColor <- defaultForeground
65+
Console.Write(" with score ")
66+
Console.ForegroundColor <- probColor
67+
printf "%f" (x.Score |> Seq.max)
68+
Console.ForegroundColor <- defaultForeground;
69+
printfn ""
70+
71+
let printHeader lines =
72+
let defaultColor = Console.ForegroundColor
73+
Console.ForegroundColor <- ConsoleColor.Yellow
74+
printfn " "
75+
lines |> Seq.iter (printfn "%s")
76+
let maxLength = lines |> Seq.map (fun x -> x.Length) |> Seq.max
77+
printfn "%s" (String('#', maxLength))
78+
Console.ForegroundColor <- defaultColor
79+
80+
let printExn lines =
81+
let defaultColor = Console.ForegroundColor
82+
Console.ForegroundColor <- ConsoleColor.Red
83+
printfn " "
84+
printfn "EXCEPTION"
85+
printfn "#########"
86+
Console.ForegroundColor <- defaultColor
87+
lines |> Seq.iter (printfn "%s")
88+
89+
let printImageNetProb (x : ImageNetDataProbability) =
90+
91+
let defaultForeground = Console.ForegroundColor
92+
let labelColor = ConsoleColor.Magenta
93+
let probColor = ConsoleColor.Blue
94+
let exactLabel = ConsoleColor.Green
95+
let failLabel = ConsoleColor.Red
96+
97+
printf "ImagePath: "
98+
Console.ForegroundColor <- labelColor
99+
printf "%s" (Path.GetFileName(x.ImagePath))
100+
Console.ForegroundColor <- defaultForeground
101+
printf " labeled as "
102+
Console.ForegroundColor <- labelColor
103+
printf "%s" x.Label
104+
Console.ForegroundColor <- defaultForeground
105+
printf " predicted as "
106+
if x.Label = x.PredictedLabel then
107+
Console.ForegroundColor <- exactLabel
108+
printf "%s" x.PredictedLabel
109+
else
110+
Console.ForegroundColor <- failLabel
111+
printf "%s" x.PredictedLabel
112+
Console.ForegroundColor <- defaultForeground
113+
printf " with probability "
114+
Console.ForegroundColor <- probColor
115+
printf "%f" x.Probability
116+
Console.ForegroundColor <- defaultForeground
117+
printfn ""
118+
119+
let score dataLocation imagesFolder inputModelLocation labelsTxt =
120+
printfn "Read model"
121+
printfn "Model location: %s" inputModelLocation
122+
printfn "Images folder: %s" imagesFolder
123+
printfn "Training file: %s" dataLocation
124+
printfn "Default parameters: image size =(%d,%d), image mean: %d" imageHeight imageWidth mean
125+
let mlContext = MLContext(seed = Nullable 1)
126+
let data = mlContext.Data.ReadFromTextFile<ImageNetData>(dataLocation, hasHeader = false)
127+
let pipeline =
128+
EstimatorChain()
129+
.Append(mlContext.Transforms.LoadImages(imageFolder = imagesFolder, columns = [|struct("ImagePath", "ImageReal")|]))
130+
.Append(mlContext.Transforms.Resize("ImageReal", "ImageReal", imageHeight, imageWidth))
131+
.Append(mlContext.Transforms.ExtractPixels([| ImagePixelExtractorTransform.ColumnInfo("ImageReal", "input", interleave = channelsLast, offset = float32 mean) |]))
132+
.Append(mlContext.Transforms.ScoreTensorFlowModel(inputModelLocation, [| "input" |], [| "softmax2" |]))
133+
let model = pipeline.Fit(data)
134+
let predictionEngine = model.CreatePredictionEngine<ImageNetData, ImageNetPrediction>(mlContext)
135+
136+
printHeader ["Classificate images"]
137+
printfn "Images folder: %s" imagesFolder
138+
printfn "Training file: %s" dataLocation
139+
printfn "Labels file: %s" labelsTxt
140+
141+
let labels = File.ReadAllLines(labelsTxt)
142+
143+
File.ReadAllLines(dataLocation)
144+
|> Seq.map (fun x -> let fields = x.Split '\t' in {ImagePath = Path.Combine(imagesFolder, fields.[0]); Label = fields.[1]})
145+
|> Seq.map
146+
(fun sample ->
147+
let preds = predictionEngine.Predict(sample).PredictedLabels
148+
let bestLabelIndex =
149+
preds
150+
|> Seq.mapi (fun i x -> i, x)
151+
|> Seq.maxBy snd
152+
|> fst
153+
{
154+
PredictedLabel = labels.[bestLabelIndex]
155+
Probability = preds.[bestLabelIndex]
156+
ImagePath = sample.ImagePath
157+
Label = sample.Label
158+
}
159+
)
160+
|> Seq.iter printImageNetProb
161+
162+
[<EntryPoint>]
163+
let main _argv =
164+
let assetsPath = Path.Combine(dataRoot.Directory.FullName, @"..\..\..\assets")
165+
let tagsTsv = Path.Combine(assetsPath, "inputs", "images", "tags.tsv")
166+
let imagesFolder = Path.Combine(assetsPath, "inputs", "images")
167+
let inceptionPb = Path.Combine(assetsPath, "inputs", "inception", "tensorflow_inception_graph.pb")
168+
let labelsTxt = Path.Combine(assetsPath, "inputs", "inception", "imagenet_comp_graph_label_strings.txt")
169+
170+
try
171+
score tagsTsv imagesFolder inceptionPb labelsTxt
172+
with
173+
| e -> printExn [e.Message]
174+
175+
let defaultColor = Console.ForegroundColor
176+
Console.ForegroundColor <- ConsoleColor.Green
177+
printfn " "
178+
printfn "Press any key to finish."
179+
Console.ForegroundColor <- defaultColor
180+
Console.ReadKey() |> ignore
181+
0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
broccoli.jpg broccoli
2+
broccoli.png broccoli
3+
canoe2.jpg canoe
4+
canoe3.jpg canoe
5+
canoe4.jpg canoe
6+
coffeepot.jpg coffeepot
7+
coffeepot2.jpg coffeepot
8+
coffeepot3.jpg coffeepot
9+
coffeepot4.jpg coffeepot
10+
pizza.jpg pizza
11+
pizza2.jpg pizza
12+
pizza3.jpg pizza
13+
teddy1.jpg teddy bear
14+
teddy2.jpg teddy bear
15+
teddy3.jpg teddy bear
16+
teddy4.jpg teddy bear
17+
teddy6.jpg teddy bear
18+
toaster.jpg toaster
19+
toaster2.png toaster
20+
toaster3.jpg toaster
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Donovan Govan, [Toaster](https://commons.wikimedia.org/wiki/File:Toaster.jpg), [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode)
2+
Consumer Reports, [Consumer Reports - Hamilton Beach Digital toaster](https://commons.wikimedia.org/wiki/File:Consumer_Reports_-_Hamilton_Beach_Digital_toaster.tiff), [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)
3+
MichalPL, [Ok Toaster](https://commons.wikimedia.org/wiki/File:OK._Toaster.jpg) [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)
4+
Hussein Kefel, [A Canoe At The_River Number 2 -Sierra Leone](https://commons.wikimedia.org/wiki/File:A_Canoe_At_The_River_Number_2_-_Sierra_Leone.JPG), [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode)
5+
Jarek Tuszyński, [Adirondacks - Rolling Pond Campground - canoe](https://commons.wikimedia.org/wiki/File:Adirondacks_-_Rolling_Pond_Campground_-_canoe.JPG), [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode)
6+
Harasmode, [Cascada de Tamul, San Luis Potosí](https://commons.wikimedia.org/wiki/File:Cascada_de_Tamul,_San_Luis_Potos%C3%AD.jpg), [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)
7+
Jon Sullivan, [Pepperoni pizza](https://commons.wikimedia.org/wiki/File:Pepperoni_pizza.jpg), This work has been released into the public domain by its author, Jon Sullivan ([PD Photo.org](http://pdphoto.org/))
8+
Sapoproductions, [Pizza con huevo](https://commons.wikimedia.org/wiki/File:Pizza_con_huevo.jpg), [GNU Free Documentation License v1.2 or later](https://en.wikipedia.org/wiki/en:GNU_Free_Documentation_License) and [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)
9+
Agnieszka Kwiecień, [Spinach pizza](https://commons.wikimedia.org/wiki/File:Spinach_pizza.jpg), [GNU Free Documentation License v1.2 or later](https://en.wikipedia.org/wiki/en:GNU_Free_Documentation_License) and [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode)
10+
Dickbauch, [Kaffekanne db](https://commons.wikimedia.org/wiki/File:Kaffekanne_db.jpg), [GNU Free Documentation License v1.2 or later](https://en.wikipedia.org/wiki/en:GNU_Free_Documentation_License) and [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode)
11+
Skottniss, [Coffeepotsteel](https://commons.wikimedia.org/wiki/File:Coffeepotsteel.jpg), [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)
12+
Kaffekjele, [Kaffekjele, Norsk Folkemuseum, NF.2007-0149AB](https://commons.wikimedia.org/wiki/File:Kaffekjele,_Norsk_Folkemuseum,_NF.2007-0149AB.jpg)
13+
Vassil, [Cafetière Décor relief Meissen 1710 Kunstgewerbemuseum Berlin 05052018](https://commons.wikimedia.org/wiki/File:Cafeti%C3%A8re_D%C3%A9cor_relief_Meissen_1710_Kunstgewerbemuseum_Berlin_05052018.jpg), [CC0 1.0 Universal Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/deed.en)
14+
David Monniaux, [Broccoli DSC00862](https://commons.wikimedia.org/wiki/File:Broccoli_DSC00862.png), [GNU Free Documentation License v1.2 or later](https://en.wikipedia.org/wiki/en:GNU_Free_Documentation_License) and [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode)
15+
Chadwick Moyer, [Broccoli666](https://commons.wikimedia.org/wiki/File:Broccoli666.jpg), [public domain](https://en.wikipedia.org/wiki/Public_domain)
16+
Polimerek, [Teddy Bear front flash](https://commons.wikimedia.org/wiki/File:Teddy_Bear_front_flash.jpg), [GNU Free Documentation License v1.2 or later](https://en.wikipedia.org/wiki/en:GNU_Free_Documentation_License), [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode), [CC BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/deed.en), [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/deed.en) and [CC BY-SA 1.0](https://creativecommons.org/licenses/by-sa/1.0/deed.en)
17+
prawdapunk, [Teddy bear](https://commons.wikimedia.org/wiki/File:Teddy_bear.jpg), [GNU Free Documentation License v1.2 or later](https://en.wikipedia.org/wiki/en:GNU_Free_Documentation_License), [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode), [CC BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/deed.en), [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/deed.en) and [CC BY-SA 1.0](https://creativecommons.org/licenses/by-sa/1.0/deed.en)
18+
Earlgray.Ler2ra, [My teddy bear](https://commons.wikimedia.org/wiki/File:My_teddy_bear.jpg), [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.en)
19+
Polimerek, [Teddy Bear left flash](https://commons.wikimedia.org/wiki/File:Teddy_Bear_left_flash.jpg), [GNU Free Documentation License v1.2 or later](https://en.wikipedia.org/wiki/en:GNU_Free_Documentation_License), [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode), [CC BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/deed.en), [CC BY-SA 2.0](https://creativecommons.org/licenses/by-sa/2.0/deed.en) and [CC BY-SA 1.0](https://creativecommons.org/licenses/by-sa/1.0/deed.en)
20+
Clément Bucco-Lechat, [Ours en peluche](https://commons.wikimedia.org/wiki/File:Ours_en_peluche_-_15.jpg), [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/legalcode)

0 commit comments

Comments
 (0)