/// <summary> /// Loads multiple artifacts of interest from the input model file, given the context /// established by the command line arguments. /// </summary> /// <param name="ch">The channel to which to provide output.</param> /// <param name="wantPredictor">Whether we want a predictor from the model file. If /// <c>false</c> we will not even attempt to load a predictor. If <c>null</c> we will /// load the predictor, if present. If <c>true</c> we will load the predictor, or fail /// noisily if we cannot.</param> /// <param name="predictor">The predictor in the model, or <c>null</c> if /// <paramref name="wantPredictor"/> was false, or <paramref name="wantPredictor"/> was /// <c>null</c> and no predictor was present.</param> /// <param name="wantTrainSchema">Whether we want the training schema. Unlike /// <paramref name="wantPredictor"/>, this has no "hard fail if not present" option. If /// this is <c>true</c>, it is still possible for <paramref name="trainSchema"/> to remain /// <c>null</c> if there were no role mappings, or pipeline.</param> /// <param name="trainSchema">The training schema if <paramref name="wantTrainSchema"/> /// is true, and there were role mappings stored in the model.</param> /// <param name="pipe">The data pipe constructed from the combination of the /// model and command line arguments.</param> protected void LoadModelObjects( IChannel ch, bool?wantPredictor, out IPredictor predictor, bool wantTrainSchema, out RoleMappedSchema trainSchema, out IDataLoader pipe) { // First handle the case where there is no input model file. // Everything must come from the command line. using (var file = Host.OpenInputFile(Args.InputModelFile)) using (var strm = file.OpenReadStream()) using (var rep = RepositoryReader.Open(strm, Host)) { // First consider loading the predictor. if (wantPredictor == false) { predictor = null; } else { ch.Trace("Loading predictor"); predictor = ModelFileUtils.LoadPredictorOrNull(Host, rep); if (wantPredictor == true) { Host.Check(predictor != null, "Could not load predictor from model file"); } } // Next create the loader. var loaderFactory = Args.Loader; IDataLoader trainPipe = null; if (loaderFactory != null) { // The loader is overridden from the command line. pipe = loaderFactory.CreateComponent(Host, new MultiFileSource(Args.DataFile)); if (Args.LoadTransforms == true) { Host.CheckUserArg(!string.IsNullOrWhiteSpace(Args.InputModelFile), nameof(Args.InputModelFile)); pipe = LoadTransformChain(pipe); } } else { var loadTrans = Args.LoadTransforms ?? true; pipe = LoadLoader(rep, Args.DataFile, loadTrans); if (loadTrans) { trainPipe = pipe; } } if (Utils.Size(Args.Transforms) > 0) { pipe = CompositeDataLoader.Create(Host, pipe, Args.Transforms); } // Next consider loading the training data's role mapped schema. trainSchema = null; if (wantTrainSchema) { // First try to get the role mappings. var trainRoleMappings = ModelFileUtils.LoadRoleMappingsOrNull(Host, rep); if (trainRoleMappings != null) { // Next create the training schema. In the event that the loaded pipeline happens // to be the training pipe, we can just use that. If it differs, then we need to // load the full pipeline from the model, relying upon the fact that all loaders // can be loaded with no data at all, to get their schemas. if (trainPipe == null) { trainPipe = ModelFileUtils.LoadLoader(Host, rep, new MultiFileSource(null), loadTransforms: true); } trainSchema = new RoleMappedSchema(trainPipe.Schema, trainRoleMappings); } // If the role mappings are null, an alternative would be to fail. However the idea // is that the scorer should always still succeed, although perhaps with reduced // functionality, even when the training schema is null, since not all versions of // TLC models will have the role mappings preserved, I believe. And, we do want to // maintain backwards compatibility. } } }
public void TestGreyscaleTransformImages() { using (var env = new ConsoleEnvironment()) { var imageHeight = 150; var imageWidth = 100; var dataFile = GetDataPath("images/images.tsv"); var imageFolder = Path.GetDirectoryName(dataFile); var data = env.CreateLoader("Text{col=ImagePath:TX:0 col=Name:TX:1}", new MultiFileSource(dataFile)); var images = ImageLoaderTransform.Create(env, new ImageLoaderTransform.Arguments() { Column = new ImageLoaderTransform.Column[1] { new ImageLoaderTransform.Column() { Source = "ImagePath", Name = "ImageReal" } }, ImageFolder = imageFolder }, data); var cropped = ImageResizerTransform.Create(env, new ImageResizerTransform.Arguments() { Column = new ImageResizerTransform.Column[1] { new ImageResizerTransform.Column() { Name = "ImageCropped", Source = "ImageReal", ImageHeight = imageHeight, ImageWidth = imageWidth, Resizing = ImageResizerTransform.ResizingKind.IsoCrop } } }, images); IDataView grey = ImageGrayscaleTransform.Create(env, new ImageGrayscaleTransform.Arguments() { Column = new ImageGrayscaleTransform.Column[1] { new ImageGrayscaleTransform.Column() { Name = "ImageGrey", Source = "ImageCropped" } } }, cropped); var fname = nameof(TestGreyscaleTransformImages) + "_model.zip"; var fh = env.CreateOutputFile(fname); using (var ch = env.Start("save")) TrainUtils.SaveModel(env, ch, fh, null, new RoleMappedData(grey)); grey = ModelFileUtils.LoadPipeline(env, fh.OpenReadStream(), new MultiFileSource(dataFile)); DeleteOutputPath(fname); grey.Schema.TryGetColumnIndex("ImageGrey", out int greyColumn); using (var cursor = grey.GetRowCursor((x) => true)) { var bitmapGetter = cursor.GetGetter <Bitmap>(greyColumn); Bitmap bitmap = default; while (cursor.MoveNext()) { bitmapGetter(ref bitmap); Assert.NotNull(bitmap); for (int x = 0; x < imageWidth; x++) { for (int y = 0; y < imageHeight; y++) { var pixel = bitmap.GetPixel(x, y); // greyscale image has same values for R,G and B Assert.True(pixel.R == pixel.G && pixel.G == pixel.B); } } } } } Done(); }
[ConditionalFact(typeof(Environment), nameof(Environment.Is64BitProcess))] // x86 fails with "An attempt was made to load a program with an incorrect format." void TestOldSavingAndLoading() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return; } var modelFile = "squeezenet/00000001/model.onnx"; var samplevector = GetSampleArrayData(); var dataView = ComponentCreation.CreateDataView(Env, new TestData[] { new TestData() { data_0 = samplevector } }); var inputNames = new[] { "data_0" }; var outputNames = new[] { "softmaxout_1" }; var est = new OnnxScoringEstimator(Env, modelFile, inputNames, outputNames); var transformer = est.Fit(dataView); var result = transformer.Transform(dataView); var resultRoles = new RoleMappedData(result); using (var ms = new MemoryStream()) { TrainUtils.SaveModel(Env, Env.Start("saving"), ms, null, resultRoles); ms.Position = 0; var loadedView = ModelFileUtils.LoadTransforms(Env, dataView, ms); loadedView.Schema.TryGetColumnIndex(outputNames[0], out int softMaxOut1); using (var cursor = loadedView.GetRowCursor(col => col == softMaxOut1)) { VBuffer <float> softMaxValue = default; var softMaxGetter = cursor.GetGetter <VBuffer <float> >(softMaxOut1); float sum = 0f; int i = 0; while (cursor.MoveNext()) { softMaxGetter(ref softMaxValue); var values = softMaxValue.DenseValues(); foreach (var val in values) { sum += val; if (i == 0) { Assert.InRange(val, 0.00004, 0.00005); } if (i == 1) { Assert.InRange(val, 0.003844, 0.003845); } if (i == 999) { Assert.InRange(val, 0.0029566, 0.0029567); } i++; } } Assert.InRange(sum, 1.0, 1.00001); } } }
protected IDataLoader LoadLoader(RepositoryReader rep, string path, bool loadTransforms) { return(ModelFileUtils.LoadLoader(Host, rep, new MultiFileSource(path), loadTransforms)); }
public void TestOldSavingAndLoading() { var data = new[] { new TestClass() { A = 1, B = 3, C = new float[2] { 1, 2 }, D = new double[2] { 3, 4 } }, new TestClass() { A = float.NaN, B = double.NaN, C = new float[2] { float.NaN, float.NaN }, D = new double[2] { double.NaN, double.NaN } }, new TestClass() { A = float.NegativeInfinity, B = double.NegativeInfinity, C = new float[2] { float.NegativeInfinity, float.NegativeInfinity }, D = new double[2] { double.NegativeInfinity, double.NegativeInfinity } }, new TestClass() { A = float.PositiveInfinity, B = double.PositiveInfinity, C = new float[2] { float.PositiveInfinity, float.PositiveInfinity, }, D = new double[2] { double.PositiveInfinity, double.PositiveInfinity } }, new TestClass() { A = 2, B = 1, C = new float[2] { 3, 4 }, D = new double[2] { 5, 6 } }, }; var dataView = ML.Data.LoadFromEnumerable(data); var pipe = ML.Transforms.ReplaceMissingValues( new MissingValueReplacingEstimator.ColumnOptions("NAA", "A", MissingValueReplacingEstimator.ReplacementMode.Mean), new MissingValueReplacingEstimator.ColumnOptions("NAB", "B", MissingValueReplacingEstimator.ReplacementMode.Mean), new MissingValueReplacingEstimator.ColumnOptions("NAC", "C", MissingValueReplacingEstimator.ReplacementMode.Mean), new MissingValueReplacingEstimator.ColumnOptions("NAD", "D", MissingValueReplacingEstimator.ReplacementMode.Mean)); var result = pipe.Fit(dataView).Transform(dataView); var resultRoles = new RoleMappedData(result); using (var ms = new MemoryStream()) { TrainUtils.SaveModel(Env, Env.Start("saving"), ms, null, resultRoles); ms.Position = 0; var loadedView = ModelFileUtils.LoadTransforms(Env, dataView, ms); } }
public void TestOldSavingAndLoading(int?gpuDeviceId, bool fallbackToCpu) { var modelFile = "squeezenet/00000001/model.onnx"; var samplevector = GetSampleArrayData(); var dataView = ML.Data.LoadFromEnumerable( new TestData[] { new TestData() { data_0 = samplevector } }); var inputNames = new[] { "data_0" }; var outputNames = new[] { "softmaxout_1" }; var est = ML.Transforms.ApplyOnnxModel(outputNames, inputNames, modelFile, gpuDeviceId, fallbackToCpu); var transformer = est.Fit(dataView); var result = transformer.Transform(dataView); var resultRoles = new RoleMappedData(result); using (var ms = new MemoryStream()) { TrainUtils.SaveModel(Env, Env.Start("saving"), ms, null, resultRoles); ms.Position = 0; var loadedView = ModelFileUtils.LoadTransforms(Env, dataView, ms); var sofMaxOut1Col = loadedView.Schema[outputNames[0]]; using (var cursor = loadedView.GetRowCursor(sofMaxOut1Col)) { VBuffer <float> softMaxValue = default; var softMaxGetter = cursor.GetGetter <VBuffer <float> >(sofMaxOut1Col); float sum = 0f; int i = 0; while (cursor.MoveNext()) { softMaxGetter(ref softMaxValue); var values = softMaxValue.DenseValues(); foreach (var val in values) { sum += val; if (i == 0) { Assert.InRange(val, 0.00004, 0.00005); } if (i == 1) { Assert.InRange(val, 0.003844, 0.003845); } if (i == 999) { Assert.InRange(val, 0.0029566, 0.0029567); } i++; } } Assert.InRange(sum, 0.99999, 1.00001); } (transformer as IDisposable)?.Dispose(); } }
public void TestBackAndForthConversionWithoutAlphaNoInterleaveNoOffset() { IHostEnvironment env = new MLContext(); const int imageHeight = 100; const int imageWidth = 130; var dataFile = GetDataPath("images/images.tsv"); var imageFolder = Path.GetDirectoryName(dataFile); var data = TextLoader.Create(env, new TextLoader.Options() { Columns = new[] { new TextLoader.Column("ImagePath", DataKind.TX, 0), new TextLoader.Column("Name", DataKind.TX, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped").Transform(cropped); IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.Rgb, false, 1, 0).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithoutAlphaNoInterleaveNoOffset) + "_model.zip"; var fh = env.CreateOutputFile(fname); using (var ch = env.Start("save")) TrainUtils.SaveModel(env, ch, fh, null, new RoleMappedData(backToBitmaps)); backToBitmaps = ModelFileUtils.LoadPipeline(env, fh.OpenReadStream(), new MultiFileSource(dataFile)); DeleteOutputPath(fname); backToBitmaps.Schema.TryGetColumnIndex("ImageRestored", out int bitmapColumn); backToBitmaps.Schema.TryGetColumnIndex("ImageCropped", out int cropBitmapColumn); using (var cursor = backToBitmaps.GetRowCursorForAllColumns()) { var bitmapGetter = cursor.GetGetter <Bitmap>(bitmapColumn); Bitmap restoredBitmap = default; var bitmapCropGetter = cursor.GetGetter <Bitmap>(cropBitmapColumn); Bitmap croppedBitmap = default; while (cursor.MoveNext()) { bitmapGetter(ref restoredBitmap); Assert.NotNull(restoredBitmap); bitmapCropGetter(ref croppedBitmap); Assert.NotNull(croppedBitmap); for (int x = 0; x < imageWidth; x++) { for (int y = 0; y < imageHeight; y++) { var c = croppedBitmap.GetPixel(x, y); var r = restoredBitmap.GetPixel(x, y); Assert.True(c.R == r.R && c.G == r.G && c.B == r.B); } } } Done(); } }
/// <summary> /// Loads a predictor from the model stream. Returns null iff there's no predictor. /// </summary> /// <param name="env">The host environment to use.</param> /// <param name="modelStream">The model stream.</param> public static IPredictor LoadPredictorOrNull(this IHostEnvironment env, Stream modelStream) { Contracts.CheckValue(modelStream, nameof(modelStream)); return(ModelFileUtils.LoadPredictorOrNull(env, modelStream)); }
public void TestBackAndForthConversionWithAlphaNoInterleaveNoOffset() { IHostEnvironment env = new MLContext(); const int imageHeight = 100; var imageWidth = 130; var dataFile = GetDataPath("images/images.tsv"); var imageFolder = Path.GetDirectoryName(dataFile); var data = TextLoader.Create(env, new TextLoader.Arguments() { Column = new[] { new TextLoader.Column("ImagePath", DataKind.TX, 0), new TextLoader.Column("Name", DataKind.TX, 1), } }, new MultiFileSource(dataFile)); var images = ImageLoaderTransform.Create(env, new ImageLoaderTransform.Arguments() { Column = new ImageLoaderTransform.Column[1] { new ImageLoaderTransform.Column() { Source = "ImagePath", Name = "ImageReal" } }, ImageFolder = imageFolder }, data); var cropped = ImageResizerTransform.Create(env, new ImageResizerTransform.Arguments() { Column = new ImageResizerTransform.Column[1] { new ImageResizerTransform.Column() { Source = "ImageReal", Name = "ImageCropped", ImageHeight = imageHeight, ImageWidth = imageWidth, Resizing = ImageResizerTransform.ResizingKind.IsoCrop } } }, images); var pixels = ImagePixelExtractorTransform.Create(env, new ImagePixelExtractorTransform.Arguments() { InterleaveArgb = false, Column = new ImagePixelExtractorTransform.Column[1] { new ImagePixelExtractorTransform.Column() { Source = "ImageCropped", Name = "ImagePixels", UseAlpha = true } } }, cropped); IDataView backToBitmaps = new VectorToImageTransform(env, new VectorToImageTransform.Arguments() { InterleaveArgb = false, Column = new VectorToImageTransform.Column[1] { new VectorToImageTransform.Column() { Source = "ImagePixels", Name = "ImageRestored", ImageHeight = imageHeight, ImageWidth = imageWidth, ContainsAlpha = true } } }, pixels); var fname = nameof(TestBackAndForthConversionWithAlphaNoInterleaveNoOffset) + "_model.zip"; var fh = env.CreateOutputFile(fname); using (var ch = env.Start("save")) TrainUtils.SaveModel(env, ch, fh, null, new RoleMappedData(backToBitmaps)); backToBitmaps = ModelFileUtils.LoadPipeline(env, fh.OpenReadStream(), new MultiFileSource(dataFile)); DeleteOutputPath(fname); backToBitmaps.Schema.TryGetColumnIndex("ImageRestored", out int bitmapColumn); backToBitmaps.Schema.TryGetColumnIndex("ImageCropped", out int cropBitmapColumn); using (var cursor = backToBitmaps.GetRowCursor((x) => true)) { var bitmapGetter = cursor.GetGetter <Bitmap>(bitmapColumn); Bitmap restoredBitmap = default; var bitmapCropGetter = cursor.GetGetter <Bitmap>(cropBitmapColumn); Bitmap croppedBitmap = default; while (cursor.MoveNext()) { bitmapGetter(ref restoredBitmap); Assert.NotNull(restoredBitmap); bitmapCropGetter(ref croppedBitmap); Assert.NotNull(croppedBitmap); for (int x = 0; x < imageWidth; x++) { for (int y = 0; y < imageHeight; y++) { var c = croppedBitmap.GetPixel(x, y); var r = restoredBitmap.GetPixel(x, y); Assert.True(c == r); } } } } Done(); }
public void TestOldSavingAndLoading() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return; } var samplevector = getSampleArrayData(); var dataView = ComponentCreation.CreateDataView(Env, new TestData[] { new TestData() { data_0 = samplevector } }); var inputNames = "data_0"; var outputNames = "output_1"; var est = new DnnImageFeaturizerEstimator(Env, m => m.ModelSelector.ResNet18(m.Environment, m.InputColumn, m.OutputColumn), inputNames, outputNames); var transformer = est.Fit(dataView); var result = transformer.Transform(dataView); var resultRoles = new RoleMappedData(result); using (var ms = new MemoryStream()) { TrainUtils.SaveModel(Env, Env.Start("saving"), ms, null, resultRoles); ms.Position = 0; var loadedView = ModelFileUtils.LoadTransforms(Env, dataView, ms); loadedView.Schema.TryGetColumnIndex(outputNames, out int softMaxOut1); using (var cursor = loadedView.GetRowCursor(col => col == softMaxOut1)) { VBuffer <float> softMaxValue = default; var softMaxGetter = cursor.GetGetter <VBuffer <float> >(softMaxOut1); float sum = 0f; int i = 0; while (cursor.MoveNext()) { softMaxGetter(ref softMaxValue); var values = softMaxValue.DenseValues(); foreach (var val in values) { sum += val; if (i == 0) { Assert.InRange(val, 0.0, 0.00001); } if (i == 7) { Assert.InRange(val, 0.62935, 0.62940); } if (i == 500) { Assert.InRange(val, 0.15521, 0.155225); } i++; } } Assert.InRange(sum, 83.50, 84.50); } } }
public void Run() { string template; using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(CodeTemplatePath)) using (var reader = new StreamReader(stream)) template = reader.ReadToEnd(); var codeProvider = new CSharpCodeProvider(); using (var fs = File.OpenRead(_args.InputModelFile)) { var transformPipe = ModelFileUtils.LoadPipeline(_host, fs, new MultiFileSource(null), true); var pred = _host.LoadPredictorOrNull(fs); IDataView root; for (root = transformPipe; root is IDataTransform; root = ((IDataTransform)root).Source) { ; } // root is now the loader. _host.Assert(root is IDataLoader); // Loader columns. var loaderSb = new StringBuilder(); for (int i = 0; i < root.Schema.ColumnCount; i++) { if (root.Schema.IsHidden(i)) { continue; } if (loaderSb.Length > 0) { loaderSb.AppendLine(); } ColumnType colType = root.Schema.GetColumnType(i); CodeGenerationUtils.AppendFieldDeclaration(codeProvider, loaderSb, i, root.Schema.GetColumnName(i), colType, true, _args.SparseVectorDeclaration); } // Scored example columns. IDataView scorer; if (pred == null) { scorer = transformPipe; } else { var roles = ModelFileUtils.LoadRoleMappingsOrNull(_host, fs); scorer = roles != null ? _host.CreateDefaultScorer(new RoleMappedData(transformPipe, roles, opt : true), pred) : _host.CreateDefaultScorer(new RoleMappedData(transformPipe, label : null, "Features"), pred); } var nonScoreSb = new StringBuilder(); var scoreSb = new StringBuilder(); for (int i = 0; i < scorer.Schema.ColumnCount; i++) { if (scorer.Schema.IsHidden(i)) { continue; } bool isScoreColumn = scorer.Schema.GetMetadataTypeOrNull(MetadataUtils.Kinds.ScoreColumnSetId, i) != null; var sb = isScoreColumn ? scoreSb : nonScoreSb; if (sb.Length > 0) { sb.AppendLine(); } ColumnType colType = scorer.Schema.GetColumnType(i); CodeGenerationUtils.AppendFieldDeclaration(codeProvider, sb, i, scorer.Schema.GetColumnName(i), colType, false, _args.SparseVectorDeclaration); } // Turn model path into a C# identifier and insert it. var modelPath = !string.IsNullOrWhiteSpace(_args.ModelNameOverride) ? _args.ModelNameOverride : _args.InputModelFile; modelPath = CodeGenerationUtils.GetCSharpString(codeProvider, modelPath); modelPath = string.Format("modelPath = {0};", modelPath); // Replace values inside the template. var replacementMap = new Dictionary <string, string> { { "EXAMPLE_CLASS_DECL", loaderSb.ToString() }, { "SCORED_EXAMPLE_CLASS_DECL", nonScoreSb.ToString() }, { "SCORE_CLASS_DECL", scoreSb.ToString() }, { "MODEL_PATH", modelPath } }; var classSource = CodeGenerationUtils.MultiReplace(template, replacementMap); File.WriteAllText(_args.CSharpOutput, classSource); } }
public void TestOldSavingAndLoading() { var data = new[] { new TestClass() { A = 1, B = 3, C = new float[2] { 1, 2 }, D = new double[2] { 3, 4 } }, new TestClass() { A = float.NaN, B = double.NaN, C = new float[2] { float.NaN, float.NaN }, D = new double[2] { double.NaN, double.NaN } }, new TestClass() { A = float.NegativeInfinity, B = double.NegativeInfinity, C = new float[2] { float.NegativeInfinity, float.NegativeInfinity }, D = new double[2] { double.NegativeInfinity, double.NegativeInfinity } }, new TestClass() { A = float.PositiveInfinity, B = double.PositiveInfinity, C = new float[2] { float.PositiveInfinity, float.PositiveInfinity, }, D = new double[2] { double.PositiveInfinity, double.PositiveInfinity } }, new TestClass() { A = 2, B = 1, C = new float[2] { 3, 4 }, D = new double[2] { 5, 6 } }, }; var dataView = ComponentCreation.CreateDataView(Env, data); var pipe = new NAReplaceEstimator(Env, new NAReplaceTransform.ColumnInfo("A", "NAA", NAReplaceTransform.ColumnInfo.ReplacementMode.Mean), new NAReplaceTransform.ColumnInfo("B", "NAB", NAReplaceTransform.ColumnInfo.ReplacementMode.Mean), new NAReplaceTransform.ColumnInfo("C", "NAC", NAReplaceTransform.ColumnInfo.ReplacementMode.Mean), new NAReplaceTransform.ColumnInfo("D", "NAD", NAReplaceTransform.ColumnInfo.ReplacementMode.Mean)); var result = pipe.Fit(dataView).Transform(dataView); var resultRoles = new RoleMappedData(result); using (var ms = new MemoryStream()) { TrainUtils.SaveModel(Env, Env.Start("saving"), ms, null, resultRoles); ms.Position = 0; var loadedView = ModelFileUtils.LoadTransforms(Env, dataView, ms); } }
/// <summary> /// Finalize the test on a transform, calls the transform, /// saves the data, saves the models, loads it back, saves the data again, /// checks the output is the same. /// </summary> /// <param name="env">environment</param> /// <param name="outModelFilePath"model filename</param> /// <param name="transform">transform to test</param> /// <param name="source">source (view before applying the transform</param> /// <param name="outData">fist data file</param> /// <param name="outData2">second data file</param> /// <param name="startsWith">Check that outputs is the same on disk after outputting the transformed data after the model was serialized</param> public static void SerializationTestTransform(IHostEnvironment env, string outModelFilePath, IDataTransform transform, IDataView source, string outData, string outData2, bool startsWith = false, bool skipDoubleQuote = false, bool forceDense = false) { // Saves model. var roles = env.CreateExamples(transform, null); using (var ch = env.Start("SaveModel")) using (var fs = File.Create(outModelFilePath)) TrainUtils.SaveModel(env, ch, fs, null, roles); if (!File.Exists(outModelFilePath)) { throw new FileNotFoundException(outModelFilePath); } // We load it again. using (var fs = File.OpenRead(outModelFilePath)) { var tr2 = ModelFileUtils.LoadTransforms(env, source, fs); if (tr2 == null) { throw new Exception(string.Format("Unable to load '{0}'", outModelFilePath)); } if (transform.GetType() != tr2.GetType()) { throw new Exception(string.Format("Type mismatch {0} != {1}", transform.GetType(), tr2.GetType())); } } // Checks the outputs. var saver = env.CreateSaver(forceDense ? "Text{dense=+}" : "Text"); var columns = new int[transform.Schema.Count]; for (int i = 0; i < columns.Length; ++i) { columns[i] = i; } using (var fs2 = File.Create(outData)) saver.SaveData(fs2, transform, columns); if (!File.Exists(outModelFilePath)) { throw new FileNotFoundException(outData); } // Check we have the same output. using (var fs = File.OpenRead(outModelFilePath)) { var tr = ModelFileUtils.LoadTransforms(env, source, fs); saver = env.CreateSaver(forceDense ? "Text{dense=+}" : "Text"); using (var fs2 = File.Create(outData2)) saver.SaveData(fs2, tr, columns); } var t1 = File.ReadAllLines(outData); var t2 = File.ReadAllLines(outData2); if (t1.Length != t2.Length) { throw new Exception(string.Format("Not the same number of lines: {0} != {1}", t1.Length, t2.Length)); } for (int i = 0; i < t1.Length; ++i) { if (skipDoubleQuote && (t1[i].Contains("\"\"\t\"\"") || t2[i].Contains("\"\"\t\"\""))) { continue; } if ((startsWith && !t1[i].StartsWith(t2[i])) || (!startsWith && t1[i] != t2[i])) { if (t1[i].EndsWith("\t5\t0:\"\"")) { var a = t1[i].Substring(0, t1[i].Length - "\t5\t0:\"\"".Length); a += "\t\"\"\t\"\"\t\"\"\t\"\"\t\"\""; var b = t2[i]; if ((startsWith && !a.StartsWith(b)) || (!startsWith && a != b)) { throw new Exception(string.Format("2-Mismatch on line {0}/{3}:\n{1}\n{2}", i, t1[i], t2[i], t1.Length)); } } else { // The test might fail because one side is dense and the other is sparse. throw new Exception(string.Format("3-Mismatch on line {0}/{3}:\n{1}\n{2}", i, t1[i], t2[i], t1.Length)); } } } }
public void TestOldSavingAndLoading() { //skip running for x86 as this test using too much memory (over 2GB limit on x86) //and very like to hit memory related issue when running on CI //TODO: optimized memory usage in related code and enable x86 run if (!Environment.Is64BitProcess) { return; } var samplevector = GetSampleArrayData(); var dataView = ML.Data.LoadFromEnumerable( new TestData[] { new TestData() { data_0 = samplevector } }); var inputNames = "data_0"; var outputNames = "output_1"; var est = ML.Transforms.DnnFeaturizeImage(outputNames, m => m.ModelSelector.ResNet18(m.Environment, m.OutputColumn, m.InputColumn), inputNames); var transformer = est.Fit(dataView); var result = transformer.Transform(dataView); var resultRoles = new RoleMappedData(result); using (var ms = new MemoryStream()) { TrainUtils.SaveModel(Env, Env.Start("saving"), ms, null, resultRoles); ms.Position = 0; var loadedView = ModelFileUtils.LoadTransforms(Env, dataView, ms); using (var cursor = loadedView.GetRowCursor(loadedView.Schema[outputNames])) { VBuffer <float> softMaxValue = default; var softMaxGetter = cursor.GetGetter <VBuffer <float> >(loadedView.Schema[outputNames]); float sum = 0f; int i = 0; while (cursor.MoveNext()) { softMaxGetter(ref softMaxValue); var values = softMaxValue.DenseValues(); foreach (var val in values) { sum += val; if (i == 0) { Assert.InRange(val, 0.0, 0.00001); } if (i == 7) { Assert.InRange(val, 0.62935, 0.62940); } if (i == 500) { Assert.InRange(val, 0.15521, 0.155225); } i++; } } Assert.InRange(sum, 83.50, 84.50); } } }
public void TestBackAndForthConversionWithDifferentOrder() { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { return; } IHostEnvironment env = new MLContext(); const int imageHeight = 100; const int imageWidth = 130; var dataFile = GetDataPath("images/images.tsv"); var imageFolder = Path.GetDirectoryName(dataFile); var data = TextLoader.Create(env, new TextLoader.Options() { Columns = new[] { new TextLoader.Column("ImagePath", DataKind.String, 0), new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All, orderOfExtraction: ImagePixelExtractingEstimator.ColorsOrder.ABRG).Transform(cropped); IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", ImagePixelExtractingEstimator.ColorBits.All, orderOfColors: ImagePixelExtractingEstimator.ColorsOrder.ABRG).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithDifferentOrder) + "_model.zip"; var fh = env.CreateOutputFile(fname); using (var ch = env.Start("save")) TrainUtils.SaveModel(env, ch, fh, null, new RoleMappedData(backToBitmaps)); backToBitmaps = ModelFileUtils.LoadPipeline(env, fh.OpenReadStream(), new MultiFileSource(dataFile)); DeleteOutputPath(fname); using (var cursor = backToBitmaps.GetRowCursorForAllColumns()) { var bitmapGetter = cursor.GetGetter <Bitmap>(backToBitmaps.Schema["ImageRestored"]); Bitmap restoredBitmap = default; var bitmapCropGetter = cursor.GetGetter <Bitmap>(backToBitmaps.Schema["ImageCropped"]); Bitmap croppedBitmap = default; while (cursor.MoveNext()) { bitmapGetter(ref restoredBitmap); Assert.NotNull(restoredBitmap); bitmapCropGetter(ref croppedBitmap); Assert.NotNull(croppedBitmap); for (int x = 0; x < imageWidth; x++) { for (int y = 0; y < imageHeight; y++) { var c = croppedBitmap.GetPixel(x, y); var r = restoredBitmap.GetPixel(x, y); if (c != r) { Assert.False(true); } Assert.True(c == r); } } } } Done(); }