-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Samples and unit test for image-related transform estimators #3165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,80 @@ | ||||
using System; | ||||
using System.Collections.Generic; | ||||
using System.Linq; | ||||
using Microsoft.ML.Data; | ||||
|
||||
namespace Microsoft.ML.Samples.Dynamic | ||||
{ | ||||
public static class ConvertToImage | ||||
{ | ||||
private const int imageHeight = 224; | ||||
private const int imageWidth = 224; | ||||
private const int numberOfChannels = 3; | ||||
private const int inputSize = imageHeight * imageWidth * numberOfChannels; | ||||
|
||||
// Sample that shows how an input array (of doubles) can be used to interop with image related estimators in ML.NET. | ||||
public static void Example() | ||||
{ | ||||
// Create a new ML context, for ML.NET operations. It can be used for exception tracking and logging, | ||||
// as well as the source of randomness. | ||||
var mlContext = new MLContext(); | ||||
|
||||
// Create a list of training data points. | ||||
var dataPoints = GenerateRandomDataPoints(4); | ||||
|
||||
// Convert the list of data points to an IDataView object, which is consumable by ML.NET API. | ||||
var data = mlContext.Data.LoadFromEnumerable(dataPoints); | ||||
|
||||
// Image loading pipeline. | ||||
var pipeline = mlContext.Transforms.ConvertToImage(imageHeight, imageWidth, "Image", "Features") | ||||
.Append(mlContext.Transforms.ExtractPixels("Pixels", "Image")); | ||||
|
||||
var transformedData = pipeline.Fit(data).Transform(data); | ||||
|
||||
// Preview the transformedData. | ||||
var transformedDataPreview = transformedData.Preview(); | ||||
PrintPreview(transformedDataPreview); | ||||
// Features Image Pixels | ||||
// 185,209,196,142,52 System.Drawing.Bitmap 185,209,196,142,52 | ||||
// 182,235,84,23,87 System.Drawing.Bitmap 182,235,84,23,87 | ||||
// 192,214,247,22,38 System.Drawing.Bitmap 192,214,247,22,38 | ||||
// 242,161,141,223,192 System.Drawing.Bitmap 242,161,141,223,192 | ||||
} | ||||
|
||||
private static void PrintPreview(DataDebuggerPreview data) | ||||
{ | ||||
foreach (var colInfo in data.ColumnView) | ||||
Console.Write("{0,-25}", colInfo.Column.Name); | ||||
|
||||
Console.WriteLine(); | ||||
foreach (var row in data.RowView) | ||||
{ | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
omit #Resolved |
||||
foreach (var kvPair in row.Values) | ||||
{ | ||||
if (kvPair.Key == "Pixels" || kvPair.Key == "Features") | ||||
{ | ||||
var rawValues = ((VBuffer<float>)kvPair.Value).DenseValues().Take(5); | ||||
Console.Write("{0,-25}", string.Join(",", rawValues)); | ||||
} | ||||
else | ||||
Console.Write("{0,-25}", kvPair.Value); | ||||
} | ||||
Console.WriteLine(); | ||||
} | ||||
} | ||||
|
||||
private class DataPoint | ||||
{ | ||||
[VectorType(inputSize)] | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
is this annotation needed? #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, this is indeed needed. when fitting a model, we do some checks e.g. schema validation / size checks / whether the estimator works with fixed size or variable size etc the
Unhandled Exception: System.ArgumentOutOfRangeException: Schema mismatch for input column 'Features': expected known-size vector of type Single, Double or Byte, got VarVector In reply to: 271595813 [](ancestors = 271595813) |
||||
public float[] Features { get; set; } | ||||
} | ||||
|
||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need for it. Users can add it #Resolved |
||||
private static IEnumerable<DataPoint> GenerateRandomDataPoints(int count, int seed = 0) | ||||
{ | ||||
var random = new Random(seed); | ||||
|
||||
for (int i = 0; i < count; i++) | ||||
yield return new DataPoint { Features = Enumerable.Repeat(0, inputSize).Select(x => (float)random.Next(0, 256)).ToArray() }; | ||||
} | ||||
} | ||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
using System.IO; | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using Microsoft.ML.Data; | ||
|
||
namespace Microsoft.ML.Samples.Dynamic | ||
|
@@ -38,24 +40,41 @@ public static void Example() | |
var imagesFolder = Path.GetDirectoryName(imagesDataFile); | ||
// Image loading pipeline. | ||
var pipeline = mlContext.Transforms.LoadImages("ImageObject", imagesFolder, "ImagePath") | ||
.Append(mlContext.Transforms.ResizeImages("ImageObject", imageWidth: 100, imageHeight: 100 )) | ||
.Append(mlContext.Transforms.ExtractPixels("Pixels", "ImageObject")); | ||
|
||
.Append(mlContext.Transforms.ResizeImages("ImageObjectResized", inputColumnName: "ImageObject", imageWidth: 100, imageHeight: 100)) | ||
.Append(mlContext.Transforms.ExtractPixels("Pixels", "ImageObjectResized")); | ||
|
||
var transformedData = pipeline.Fit(data).Transform(data); | ||
|
||
// The transformedData IDataView contains the loaded images now | ||
//Preview of the transformedData | ||
// Preview the transformedData. | ||
var transformedDataPreview = transformedData.Preview(); | ||
PrintPreview(transformedDataPreview); | ||
// ImagePath Name ImageObject ImageObjectResized Pixels | ||
// tomato.bmp tomato System.Drawing.Bitmap System.Drawing.Bitmap 255,255,255,255,255... | ||
// banana.jpg banana System.Drawing.Bitmap System.Drawing.Bitmap 255,255,255,255,255... | ||
// hotdog.jpg hotdog System.Drawing.Bitmap System.Drawing.Bitmap 255,255,255,255,255... | ||
// tomato.jpg tomato System.Drawing.Bitmap System.Drawing.Bitmap 255,255,255,255,255... | ||
} | ||
|
||
// Preview of the content of the images.tsv file | ||
// | ||
// ImagePath Name ImageObject "Pixels" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
maybe keep the headers/column names, even if they don't print out. Or print them separately. #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
// tomato.bmp tomato {System.Drawing.Bitmap} [ 255, 255, 255, ..... 232, 243, 226, ... | ||
// banana.jpg banana {System.Drawing.Bitmap} [ 255, 255, 255, ..... 90, 54, 43, ... | ||
// hotdog.jpg hotdog {System.Drawing.Bitmap} [ 255, 255, 255, ..... 132, 143, 126, ... | ||
// tomato.jpg tomato {System.Drawing.Bitmap} [ 255, 255, 255, ..... 16, 21, 23, ... | ||
private static void PrintPreview(DataDebuggerPreview data) | ||
{ | ||
foreach (var colInfo in data.ColumnView) | ||
Console.Write("{0,-25}", colInfo.Column.Name); | ||
|
||
Console.WriteLine(); | ||
foreach (var row in data.RowView) | ||
{ | ||
foreach (var kvPair in row.Values) | ||
{ | ||
if (kvPair.Key == "Pixels") | ||
{ | ||
var pixels = ((VBuffer<float>)kvPair.Value).DenseValues().Take(5); | ||
Console.Write("{0}...", string.Join(",", pixels)); | ||
} | ||
else | ||
Console.Write("{0,-25}", kvPair.Value); | ||
} | ||
Console.WriteLine(); | ||
} | ||
} | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
omit :) #Resolved