Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,61 @@ public static void Example()
// Download the squeeznet image model from ONNX model zoo, version 1.2
// https://github.com/onnx/models/tree/master/squeezenet or use
// Microsoft.ML.Onnx.TestModels nuget.
// It's a multiclass classifier. It consumes an input "data_0" and produces
// an output "softmaxout_1".
// It's a multiclass classifier. It consumes an input "data_0" and
// produces an output "softmaxout_1".
var modelPath = @"squeezenet\00000001\model.onnx";

// Create ML pipeline to score the data using OnnxScoringEstimator
var mlContext = new MLContext();

// Create in-memory data points. Its Image/Scores field is the input/output of the used ONNX model.
// Create in-memory data points. Its Image/Scores field is the
// input /output of the used ONNX model.
var dataPoints = new ImageDataPoint[]
{
new ImageDataPoint(Color.Red),
new ImageDataPoint(Color.Green)
};

// Convert training data to IDataView, the general data type used in ML.NET.
// Convert training data to IDataView, the general data type used in
// ML.NET.
var dataView = mlContext.Data.LoadFromEnumerable(dataPoints);

// Create a ML.NET pipeline which contains two steps. First, ExtractPixle is used to convert the 224x224 image to a 3x224x224 float tensor.
// Then the float tensor is fed into a ONNX model with an input called "data_0" and an output called "softmaxout_1". Note that "data_0" and
// "softmaxout_1" are model input and output names stored in the used ONNX model file. Users may need to inspect their own models to
// get the right input and output column names.
var pipeline = mlContext.Transforms.ExtractPixels("data_0", "Image") // Map column "Image" to column "data_0"
.Append(mlContext.Transforms.ApplyOnnxModel("softmaxout_1", "data_0", modelPath)); // Map column "data_0" to column "softmaxout_1"
// Create a ML.NET pipeline which contains two steps. First,
// ExtractPixle is used to convert the 224x224 image to a 3x224x224
// float tensor. Then the float tensor is fed into a ONNX model with an
// input called "data_0" and an output called "softmaxout_1". Note that
// "data_0" and "softmaxout_1" are model input and output names stored
// in the used ONNX model file. Users may need to inspect their own
// models to get the right input and output column names.
// Map column "Image" to column "data_0"
// Map column "data_0" to column "softmaxout_1"
var pipeline = mlContext.Transforms.ExtractPixels("data_0", "Image")
.Append(mlContext.Transforms.ApplyOnnxModel("softmaxout_1",
"data_0", modelPath));

var model = pipeline.Fit(dataView);
var onnx = model.Transform(dataView);

// Convert IDataView back to IEnumerable<ImageDataPoint> so that user can inspect the output, column "softmaxout_1", of the ONNX transform.
// Note that Column "softmaxout_1" would be stored in ImageDataPont.Scores because the added attributed [ColumnName("softmaxout_1")]
// tells that ImageDataPont.Scores is equivalent to column "softmaxout_1".
var transformedDataPoints = mlContext.Data.CreateEnumerable<ImageDataPoint>(onnx, false).ToList();
// Convert IDataView back to IEnumerable<ImageDataPoint> so that user
// can inspect the output, column "softmaxout_1", of the ONNX transform.
// Note that Column "softmaxout_1" would be stored in ImageDataPont
//.Scores because the added attributed [ColumnName("softmaxout_1")]
// tells that ImageDataPont.Scores is equivalent to column
// "softmaxout_1".
var transformedDataPoints = mlContext.Data.CreateEnumerable<
ImageDataPoint>(onnx, false).ToList();

// The scores are probabilities of all possible classes, so they should all be positive.
// The scores are probabilities of all possible classes, so they should
// all be positive.
foreach (var dataPoint in transformedDataPoints)
{
var firstClassProb = dataPoint.Scores.First();
var lastClassProb = dataPoint.Scores.Last();
Console.WriteLine($"The probability of being the first class is {firstClassProb * 100}%.");
Console.WriteLine($"The probability of being the last class is {lastClassProb * 100}%.");
Console.WriteLine("The probability of being the first class is " +
(firstClassProb * 100) + "%.");

Console.WriteLine($"The probability of being the last class is " +
(lastClassProb * 100) + "%.");
}

// Expected output:
Expand All @@ -62,7 +79,8 @@ public static void Example()
// The probability of being the last class is 0.394428%.
}

// This class is used in Example() to describe data points which will be consumed by ML.NET pipeline.
// This class is used in Example() to describe data points which will be
// consumed by ML.NET pipeline.
private class ImageDataPoint
{
// Height of Image.
Expand All @@ -75,9 +93,9 @@ private class ImageDataPoint
[ImageType(height, width)]
public Bitmap Image { get; set; }

// Expected output of ONNX model. It contains probabilities of all classes.
// Note that the ColumnName below should match the output name in the used
// ONNX model file.
// Expected output of ONNX model. It contains probabilities of all
// classes. Note that the ColumnName below should match the output name
// in the used ONNX model file.
[ColumnName("softmaxout_1")]
public float[] Scores { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,25 @@ public static void Example()

// Generate sample test data.
var samples = GetTensorData();
// Convert training data to IDataView, the general data type used in ML.NET.
// Convert training data to IDataView, the general data type used in
// ML.NET.
var data = mlContext.Data.LoadFromEnumerable(samples);
// Create the pipeline to score using provided onnx model.
var pipeline = mlContext.Transforms.ApplyOnnxModel(modelPath);
// Fit the pipeline and get the transformed values
var transformedValues = pipeline.Fit(data).Transform(data);
// Retrieve model scores into Prediction class
var predictions = mlContext.Data.CreateEnumerable<Prediction>(transformedValues, reuseRowObject: false);
var predictions = mlContext.Data.CreateEnumerable<Prediction>(
transformedValues, reuseRowObject: false);

// Iterate rows
foreach (var prediction in predictions)
{
int numClasses = 0;
foreach (var classScore in prediction.softmaxout_1.Take(3))
{
Console.WriteLine($"Class #{numClasses++} score = {classScore}");
Console.WriteLine("Class #" + numClasses++ + " score = " +
classScore);
}
Console.WriteLine(new string('-', 10));
}
Expand Down Expand Up @@ -65,9 +68,14 @@ public class TensorData
public static TensorData[] GetTensorData()
{
// This can be any numerical data. Assume image pixel values.
var image1 = Enumerable.Range(0, inputSize).Select(x => (float)x / inputSize).ToArray();
var image2 = Enumerable.Range(0, inputSize).Select(x => (float)(x + 10000) / inputSize).ToArray();
return new TensorData[] { new TensorData() { data_0 = image1 }, new TensorData() { data_0 = image2 } };
var image1 = Enumerable.Range(0, inputSize).Select(x => (float)x /
inputSize).ToArray();

var image2 = Enumerable.Range(0, inputSize).Select(x => (float)(x +
10000) / inputSize).ToArray();

return new TensorData[] { new TensorData() { data_0 = image1 }, new
TensorData() { data_0 = image2 } };
}

// Class to contain the output values from the transformation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ namespace Samples.Dynamic
{
public static class ApproximatedKernelMap
{
// Transform feature vector to another non-linear space. See https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf.
// Transform feature vector to another non-linear space. See
// https://people.eecs.berkeley.edu/~brecht/papers/07.rah.rec.nips.pdf.
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.
// 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();
var samples = new List<DataPoint>()
{
Expand All @@ -22,19 +23,26 @@ public static void Example()
new DataPoint(){ Features = new float[7] {-1, 1, 0,-1,-1, 0,-1} },
new DataPoint(){ Features = new float[7] { 0,-1, 0, 1, 0,-1,-1} }
};
// Convert training data to IDataView, the general data type used in ML.NET.
// Convert training data to IDataView, the general data type used in
// ML.NET.
var data = mlContext.Data.LoadFromEnumerable(samples);
// ApproximatedKernel map takes data and maps it's to a random low-dimensional space.
var approximation = mlContext.Transforms.ApproximatedKernelMap("Features", rank: 4, generator: new GaussianKernel(gamma: 0.7f), seed: 1);
// ApproximatedKernel map takes data and maps it's to a random
// low -dimensional space.
var approximation = mlContext.Transforms.ApproximatedKernelMap(
"Features", rank: 4, generator: new GaussianKernel(gamma: 0.7f),
seed: 1);

// Now we can transform the data and look at the output to confirm the behavior of the estimator.
// This operation doesn't actually evaluate data until we read the data below.
// Now we can transform the data and look at the output to confirm the
// behavior of the estimator. This operation doesn't actually evaluate
// data until we read the data below.
var tansformer = approximation.Fit(data);
var transformedData = tansformer.Transform(data);

var column = transformedData.GetColumn<float[]>("Features").ToArray();
foreach (var row in column)
Console.WriteLine(string.Join(", ", row.Select(x => x.ToString("f4"))));
Console.WriteLine(string.Join(", ", row.Select(x => x.ToString(
"f4"))));

// Expected output:
// -0.0119, 0.5867, 0.4942, 0.7041
// 0.4720, 0.5639, 0.4346, 0.2671
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ public static class CalculateFeatureContribution
{
public static void Example()
{
// Create a new context for ML.NET operations. It can be used for exception tracking and logging,
// Create a new context for ML.NET operations. It can be used for
// exception tracking and logging,
// as a catalog of available operations and as the source of randomness.
var mlContext = new MLContext(seed: 1);

Expand All @@ -19,7 +20,8 @@ public static void Example()
// Convert training data to IDataView.
var data = mlContext.Data.LoadFromEnumerable(samples);

// Create a pipeline to concatenate the features into a feature vector and normalize it.
// Create a pipeline to concatenate the features into a feature vector
// and normalize it.
var transformPipeline = mlContext.Transforms.Concatenate("Features",
new string[] { nameof(Data.Feature1), nameof(Data.Feature2) })
.Append(mlContext.Transforms.NormalizeMeanVariance("Features"));
Expand All @@ -37,28 +39,45 @@ public static void Example()
var linearModel = linearTrainer.Fit(transformedData);
// Print the model parameters.
Console.WriteLine($"Linear Model Parameters");
Console.WriteLine($"Bias: {linearModel.Model.Bias} Feature1: {linearModel.Model.Weights[0]} Feature2: {linearModel.Model.Weights[1]}");
Console.WriteLine("Bias: " + linearModel.Model.Bias+ " Feature1: " +
linearModel.Model.Weights[0] + " Feature2: " +linearModel.Model
.Weights[1]);

// Define a feature contribution calculator for all the features, and don't normalize the contributions.
// These are "trivial estimators" and they don't need to fit to the data, so we can feed a subset.
var simpleScoredDataset = linearModel.Transform(mlContext.Data.TakeRows(transformedData, 1));
var linearFeatureContributionCalculator = mlContext.Transforms.CalculateFeatureContribution(linearModel, normalize: false).Fit(simpleScoredDataset);
// Define a feature contribution calculator for all the features, and
// don't normalize the contributions.These are "trivial estimators" and
// they don't need to fit to the data, so we can feed a subset.
var simpleScoredDataset = linearModel.Transform(mlContext.Data
.TakeRows(transformedData, 1));

var linearFeatureContributionCalculator = mlContext.Transforms
.CalculateFeatureContribution(linearModel, normalize: false).Fit(
simpleScoredDataset);

// Create a transformer chain to describe the entire pipeline.
var scoringPipeline = transformer.Append(linearModel).Append(linearFeatureContributionCalculator);
var scoringPipeline = transformer.Append(linearModel).Append(
linearFeatureContributionCalculator);

// Create the prediction engine to get the features extracted from the text.
var predictionEngine = mlContext.Model.CreatePredictionEngine<Data, ScoredData>(scoringPipeline);
// Create the prediction engine to get the features extracted from the
// text.
var predictionEngine = mlContext.Model.CreatePredictionEngine<Data,
ScoredData>(scoringPipeline);

// Convert the text into numeric features.
var prediction = predictionEngine.Predict(samples.First());

// Write out the prediction, with contributions.
// Note that for the linear model, the feature contributions for a feature in an example is the feature-weight*feature-value.
// Note that for the linear model, the feature contributions for a
// feature in an example is the feature-weight*feature-value.
// The total prediction is thus the bias plus the feature contributions.
Console.WriteLine($"Label: {prediction.Label} Prediction: {prediction.Score}");
Console.WriteLine($"Feature1: {prediction.Features[0]} Feature2: {prediction.Features[1]}");
Console.WriteLine($"Feature Contributions: {prediction.FeatureContributions[0]} {prediction.FeatureContributions[1]}");
Console.WriteLine("Label: " + prediction.Label + " Prediction: " +
prediction.Score);

Console.WriteLine("Feature1: " + prediction.Features[0] +
" Feature2: " + prediction.Features[1]);

Console.WriteLine("Feature Contributions: " + prediction
.FeatureContributions[0] + " " + prediction
.FeatureContributions[1]);

// Expected output:
// Linear Model Parameters
Expand Down Expand Up @@ -107,7 +126,9 @@ private static IEnumerable<Data> GenerateData(int nExamples = 10000,
};

// Create a noisy label.
data.Label = (float)(bias + weight1 * data.Feature1 + weight2 * data.Feature2 + rng.NextDouble() - 0.5);
data.Label = (float)(bias + weight1 * data.Feature1 + weight2 *
data.Feature2 + rng.NextDouble() - 0.5);

yield return data;
}
}
Expand Down
Loading