Esempio n. 1
0
        private ILegacyDataLoader CreateLoaderFromBytes(byte[] loaderBytes, IMultiStreamSource files)
        {
            Contracts.CheckValue(loaderBytes, nameof(loaderBytes));
            Contracts.CheckValue(files, nameof(files));

            using (var stream = new MemoryStream(loaderBytes))
                using (var rep = RepositoryReader.Open(stream, _host))
                {
                    return(ModelFileUtils.LoadLoader(_host, rep, files, false));
                }
        }
Esempio n. 2
0
        public void LoadOriginalBinaryLoaderModel()
        {
            var env = new MLContext().AddStandardComponents();

            using (var modelStream = File.OpenRead(Path.Combine("TestModels", "BinaryLoader-v3.11.0.0.zip")))
                using (var rep = RepositoryReader.Open(modelStream, env))
                {
                    IDataLoader result = ModelFileUtils.LoadLoader(env, rep, new MultiFileSource(null), true);

                    Assert.Equal(2, result.Schema.Count);
                    Assert.Equal("Image", result.Schema[0].Name);
                    Assert.Equal("Class", result.Schema[1].Name);
                }
        }
        /// <summary>
        /// Load the model and its input schema from the stream.
        /// </summary>
        /// <param name="stream">A readable, seekable stream to load from.</param>
        /// <param name="inputSchema">Will contain the input schema for the model. If the model was saved using older APIs
        /// it may not contain an input schema, in this case <paramref name="inputSchema"/> will be null.</param>
        /// <returns>The loaded model.</returns>
        public ITransformer Load(Stream stream, out DataViewSchema inputSchema)
        {
            _env.CheckValue(stream, nameof(stream));

            using (var rep = RepositoryReader.Open(stream, _env))
            {
                var entry = rep.OpenEntryOrNull(SchemaEntryName);
                if (entry != null)
                {
                    var loader = new BinaryLoader(_env, new BinaryLoader.Arguments(), entry.Stream);
                    inputSchema = loader.Schema;
                    ModelLoadContext.LoadModel <ITransformer, SignatureLoadModel>(_env, out var transformerChain, rep,
                                                                                  CompositeDataLoader <object, ITransformer> .TransformerDirectory);
                    return(transformerChain);
                }

                ModelLoadContext.LoadModelOrNull <IDataLoader <IMultiStreamSource>, SignatureLoadModel>(_env, out var dataLoader, rep, null);
                if (dataLoader == null)
                {
                    // Try to see if the model was saved without a loader or a schema.
                    if (ModelLoadContext.LoadModelOrNull <ITransformer, SignatureLoadModel>(_env, out var transformerChain, rep,
                                                                                            CompositeDataLoader <object, ITransformer> .TransformerDirectory))
                    {
                        inputSchema = null;
                        return(transformerChain);
                    }

                    // Try to load from legacy model format.
                    try
                    {
                        var loader = ModelFileUtils.LoadLoader(_env, rep, new MultiFileSource(null), false);
                        inputSchema = loader.Schema;
                        return(TransformerChain.LoadFromLegacy(_env, stream));
                    }
                    catch (Exception ex)
                    {
                        throw _env.Except(ex, "Could not load legacy format model");
                    }
                }
                if (dataLoader is CompositeDataLoader <IMultiStreamSource, ITransformer> composite)
                {
                    inputSchema = composite.Loader.GetOutputSchema();
                    return(composite.Transformer);
                }
                inputSchema = dataLoader.GetOutputSchema();
                return(new TransformerChain <ITransformer>());
            }
        }
Esempio n. 4
0
        public void TestTextLoaderKeyTypeBackCompat()
        {
            // Model generated with the following command on a version of the code previous to the KeyType change that removed Min and Contiguous:
            // Train data=...\breast-cancer.txt loader =TextLoader{col=Label:R4:0 col=Features:R4:1-9 col=key:U4[0-*]:3} tr=LogisticRegression {} out=model.zip
            var    mlContext           = new MLContext(1);
            string textLoaderModelPath = GetDataPath("backcompat/textloader-with-key-model.zip");
            string breastCancerPath    = GetDataPath(TestDatasets.breastCancer.trainFilename);

            using (FileStream modelfs = File.OpenRead(textLoaderModelPath))
                using (var rep = RepositoryReader.Open(modelfs, mlContext))
                {
                    var result = ModelFileUtils.LoadLoader(mlContext, rep, new MultiFileSource(breastCancerPath), false);
                    Assert.True(result.Schema.TryGetColumnIndex("key", out int featureIdx));
                    Assert.True(result.Schema[featureIdx].Type is KeyDataViewType keyType && keyType.Count == typeof(uint).ToMaxInt());
                }
        }
        private IDataScorerTransform GetScorer(IHostEnvironment env, IDataView transforms, IPredictor pred, string testDataPath = null)
        {
            using (var ch = env.Start("Saving model"))
                using (var memoryStream = new MemoryStream())
                {
                    var trainRoles = new RoleMappedData(transforms, label: "Label", feature: "Features");

                    // Model cannot be saved with CacheDataView
                    TrainUtils.SaveModel(env, ch, memoryStream, pred, trainRoles);
                    memoryStream.Position = 0;
                    using (var rep = RepositoryReader.Open(memoryStream, ch))
                    {
                        IDataLoader    testPipe  = ModelFileUtils.LoadLoader(env, rep, new MultiFileSource(testDataPath), true);
                        RoleMappedData testRoles = new RoleMappedData(testPipe, label: "Label", feature: "Features");
                        return(ScoreUtils.GetScorer(pred, testRoles, env, testRoles.Schema));
                    }
                }
        }
        public void TestTextLoaderBackCompat_VerWritt_0x0001000C()
        {
            // Checks backward compatibility with a text loader created with "verWrittenCur: 0x0001000C"
            // Model generated with:
            // loader=text{header+ col=SepalLength:Num:0 col=SepalWidth:Num:1 col=PetalLength:Num:2 col=PetalWidth:Num:2 col=Cat:TX:1-8 col=Num:9-14 col=Type:TX:4}
            var    mlContext           = new MLContext(1);
            string textLoaderModelPath = GetDataPath("backcompat/textloader_VerWritt_0x0001000C.zip");
            string irisPath            = GetDataPath(TestDatasets.irisData.trainFilename);

            IDataView iris;

            using (FileStream modelfs = File.OpenRead(textLoaderModelPath))
                using (var rep = RepositoryReader.Open(modelfs, mlContext))
                {
                    iris = ModelFileUtils.LoadLoader(mlContext, rep, new MultiFileSource(irisPath), false);
                }

            var previewIris  = iris.Preview(1);
            var irisFirstRow = new Dictionary <string, float>();

            irisFirstRow["SepalLength"] = 5.1f;
            irisFirstRow["SepalWidth"]  = 3.5f;
            irisFirstRow["PetalLength"] = 1.4f;
            irisFirstRow["PetalWidth"]  = 0.2f;

            Assert.Equal(5, previewIris.ColumnView.Length);
            Assert.Equal("SepalLength", previewIris.Schema[0].Name);
            Assert.Equal(NumberDataViewType.Single, previewIris.Schema[0].Type);
            int index = 0;

            foreach (var entry in irisFirstRow)
            {
                Assert.Equal(entry.Key, previewIris.RowView[0].Values[index].Key);
                Assert.Equal(entry.Value, previewIris.RowView[0].Values[index++].Value);
            }
            Assert.Equal("Type", previewIris.RowView[0].Values[index].Key);
            Assert.Equal("Iris-setosa", previewIris.RowView[0].Values[index].Value.ToString());
        }
            /// <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 ILegacyDataLoader pipe)
            {
                // First handle the case where there is no input model file.
                // Everything must come from the command line.

                using (var file = Host.OpenInputFile(ImplOptions.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           = ImplOptions.Loader;
                            ILegacyDataLoader trainPipe = null;
                            if (loaderFactory != null)
                            {
                                // The loader is overridden from the command line.
                                pipe = loaderFactory.CreateComponent(Host, new MultiFileSource(ImplOptions.DataFile));
                                if (ImplOptions.LoadTransforms == true)
                                {
                                    Host.CheckUserArg(!string.IsNullOrWhiteSpace(ImplOptions.InputModelFile), nameof(ImplOptions.InputModelFile));
                                    pipe = LoadTransformChain(pipe);
                                }
                            }
                            else
                            {
                                var loadTrans = ImplOptions.LoadTransforms ?? true;
                                pipe = LoadLoader(rep, ImplOptions.DataFile, loadTrans);
                                if (loadTrans)
                                {
                                    trainPipe = pipe;
                                }
                            }

                            if (Utils.Size(ImplOptions.Transforms) > 0)
                            {
                                pipe = LegacyCompositeDataLoader.Create(Host, pipe, ImplOptions.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.
                            }
                        }
            }
 protected ILegacyDataLoader LoadLoader(RepositoryReader rep, string path, bool loadTransforms)
 {
     return(ModelFileUtils.LoadLoader(Host, rep, new MultiFileSource(path), loadTransforms));
 }