@@ -18,9 +18,10 @@ class Program
1818 // <SnippetDeclareGlobalVariables>
1919 static readonly string _assetsPath = Path . Combine ( Environment . CurrentDirectory , "assets" ) ;
2020 static readonly string _trainTagsTsv = Path . Combine ( _assetsPath , "inputs-train" , "data" , "tags.tsv" ) ;
21- static readonly string _predictTagsTsv = Path . Combine ( _assetsPath , "inputs-predict" , "data" , "tags .tsv" ) ;
21+ static readonly string _predictImageListTsv = Path . Combine ( _assetsPath , "inputs-predict" , "data" , "image_list .tsv" ) ;
2222 static readonly string _trainImagesFolder = Path . Combine ( _assetsPath , "inputs-train" , "data" ) ;
2323 static readonly string _predictImagesFolder = Path . Combine ( _assetsPath , "inputs-predict" , "data" ) ;
24+ static readonly string _predictSingleImage = Path . Combine ( _assetsPath , "inputs-predict-single" , "data" , "toaster3.jpg" ) ;
2425 static readonly string _inceptionPb = Path . Combine ( _assetsPath , "inputs-train" , "inception" , "tensorflow_inception_graph.pb" ) ;
2526 static readonly string _inputImageClassifierZip = Path . Combine ( _assetsPath , "inputs-predict" , "imageClassifier.zip" ) ;
2627 static readonly string _outputImageClassifierZip = Path . Combine ( _assetsPath , "outputs" , "imageClassifier.zip" ) ;
@@ -41,8 +42,12 @@ static void Main(string[] args)
4142 // </CallSnippetReuseAndTuneInceptionModel>
4243
4344 // <SnippetCallClassifyImages>
44- ClassifyImages ( mlContext , _predictTagsTsv , _predictImagesFolder , _outputImageClassifierZip ) ;
45+ ClassifyImages ( mlContext , _predictImageListTsv , _predictImagesFolder , _outputImageClassifierZip ) ;
4546 // </SnippetCallClassifyImages>
47+
48+ // <SnippetCallClassifySingleImage>
49+ ClassifySingleImage ( mlContext , _predictSingleImage , _outputImageClassifierZip ) ;
50+ // </SnippetCallClassifySingleImage>
4651 }
4752
4853 // <SnippetInceptionSettings>
@@ -60,14 +65,8 @@ private struct InceptionSettings
6065 public static void ReuseAndTuneInceptionModel ( MLContext mlContext , string dataLocation , string imagesFolder , string inputModelLocation , string outputModelLocation )
6166 {
6267
63- Console . WriteLine ( "Read model" ) ;
64- Console . WriteLine ( $ "Model location: { inputModelLocation } ") ;
65- Console . WriteLine ( $ "Images folder: { _trainImagesFolder } ") ;
66- Console . WriteLine ( $ "Training file: { dataLocation } ") ;
67- Console . WriteLine ( $ "Default parameters: image size=({ InceptionSettings . ImageWidth } ,{ InceptionSettings . ImageHeight } ), image mean: { InceptionSettings . Mean } ") ;
68-
6968 // <SnippetLoadData>
70- var data = mlContext . Data . ReadFromTextFile < ImageData > ( path : dataLocation , hasHeader : true ) ;
69+ var data = mlContext . Data . ReadFromTextFile < ImageData > ( path : dataLocation , hasHeader : false ) ;
7170 // </SnippetLoadData>
7271
7372 // <SnippetMapValueToKey1>
@@ -144,15 +143,14 @@ public static void ClassifyImages(MLContext mlContext, string dataLocation, stri
144143 {
145144 Console . WriteLine ( $ "=============== Loading model ===============") ;
146145 Console . WriteLine ( $ "Model loaded: { outputModelLocation } ") ;
147-
148146 // Load the model
149147 // <SnippetLoadModel>
150148 ITransformer loadedModel ;
151149 using ( var fileStream = new FileStream ( outputModelLocation , FileMode . Open ) )
152150 loadedModel = mlContext . Model . Load ( fileStream ) ;
153151 // </SnippetLoadModel>
154152
155- // Read the tags .tsv file and add the filepath to the image file name
153+ // Read the image_list .tsv file and add the filepath to the image file name
156154 // before loading into ImageData
157155 // <SnippetReadFromTSV>
158156 var imageData = ReadFromTsv ( dataLocation , imagesFolder ) ;
@@ -171,6 +169,38 @@ public static void ClassifyImages(MLContext mlContext, string dataLocation, stri
171169
172170 }
173171
172+ public static void ClassifySingleImage ( MLContext mlContext , string imagePath , string outputModelLocation )
173+ {
174+ Console . WriteLine ( $ "=============== Loading model ===============") ;
175+ Console . WriteLine ( $ "Model loaded: { outputModelLocation } ") ;
176+ // Load the model
177+ // <SnippetLoadModel2>
178+ ITransformer loadedModel ;
179+ using ( var fileStream = new FileStream ( outputModelLocation , FileMode . Open ) )
180+ loadedModel = mlContext . Model . Load ( fileStream ) ;
181+ // </SnippetLoadModel2>
182+
183+ // load the fully qualified image file name into ImageData
184+ // <SnippetLoadImageData>
185+ var imageData = new ImageData ( )
186+ {
187+ ImagePath = imagePath
188+ } ;
189+ // </SnippetReadFromTSV2>
190+
191+ // <SnippetPredictSingle>
192+ // Make prediction function (input = ImageNetData, output = ImageNetPrediction)
193+ var predictor = loadedModel . CreatePredictionEngine < ImageData , ImagePrediction > ( mlContext ) ;
194+ var prediction = predictor . Predict ( imageData ) ;
195+ // </SnippetPredictSingle>
196+
197+ Console . WriteLine ( "=============== Making single image classification ===============" ) ;
198+ // <SnippetDisplayPrediction>
199+ Console . WriteLine ( $ "Image: { Path . GetFileName ( imageData . ImagePath ) } predicted as: { prediction . PredictedLabelValue } with score: { prediction . Score . Max ( ) } ") ;
200+ // </SnippetDisplayPrediction>
201+
202+ }
203+
174204 private static void PairAndDisplayResults ( IEnumerable < ImageData > imageNetData , IEnumerable < ImagePrediction > imageNetPredictionData )
175205 {
176206 // Builds pairs of (image, prediction) to sync up for display
@@ -196,8 +226,7 @@ public static IEnumerable<ImageData> ReadFromTsv(string file, string folder)
196226 . Select ( line => line . Split ( '\t ' ) )
197227 . Select ( line => new ImageData ( )
198228 {
199- ImagePath = Path . Combine ( folder , line [ 0 ] ) ,
200- Label = line [ 1 ] ,
229+ ImagePath = Path . Combine ( folder , line [ 0 ] )
201230 } ) ;
202231 // </SnippetReadFromTsv>
203232 }
0 commit comments