Esempio n. 1
0
        public static void LoadModel(IHostEnvironment env, Stream modelStream, bool loadNames, out IPredictor predictor, out RoleMappedSchema schema)
        {
            Contracts.CheckValue(env, nameof(env));
            env.CheckValue(modelStream, nameof(modelStream));

            schema = null;
            using (var rep = RepositoryReader.Open(modelStream, env))
            {
                ModelLoadContext.LoadModel <IPredictor, SignatureLoadModel>(env, out predictor, rep, ModelFileUtils.DirPredictor);

                if (loadNames)
                {
                    var roles = ModelFileUtils.LoadRoleMappingsOrNull(env, rep);
                    if (roles != null)
                    {
                        var emptyView = ModelFileUtils.LoadPipeline(env, rep, new MultiFileSource(null));
                        schema = new RoleMappedSchema(emptyView.Schema, roles, opt: true);
                    }
                    else
                    {
                        FeatureNameCollection names;
                        if (ModelFileUtils.TryLoadFeatureNames(out names, rep))
                        {
                            schema = names.Schema;
                        }
                    }
                }
            }
        }
        internal BatchPredictionEngine(IHostEnvironment env, Stream modelStream, bool ignoreMissingColumns,
                                       SchemaDefinition inputSchemaDefinition = null, SchemaDefinition outputSchemaDefinition = null)
        {
            Contracts.AssertValue(env);
            Contracts.AssertValue(modelStream);
            Contracts.AssertValueOrNull(inputSchemaDefinition);
            Contracts.AssertValueOrNull(outputSchemaDefinition);

            // Initialize pipe.
            _srcDataView = DataViewConstructionUtils.CreateFromEnumerable(env, new TSrc[] { }, inputSchemaDefinition);

            // Load transforms.
            var pipe = env.LoadTransforms(modelStream, _srcDataView);

            // Load predictor (if present) and apply default scorer.
            // REVIEW: distinguish the case of predictor / no predictor?
            var predictor = env.LoadPredictorOrNull(modelStream);

            if (predictor != null)
            {
                var roles = ModelFileUtils.LoadRoleMappingsOrNull(env, modelStream);
                pipe = roles != null
                    ? env.CreateDefaultScorer(RoleMappedData.CreateOpt(pipe, roles), predictor)
                    : env.CreateDefaultScorer(env.CreateExamples(pipe, "Features"), predictor);
            }

            _pipeEngine = new PipeEngine <TDst>(env, pipe, ignoreMissingColumns, outputSchemaDefinition);
        }
        /// <summary>
        /// Loads a pipeline saved in zip format.
        /// </summary>
        protected void Load(Stream fs)
        {
            var transformPipe = ModelFileUtils.LoadPipeline(_env, fs, new MultiFileSource(null), true);
            var pred          = _env.LoadPredictorOrNull(fs);

            IDataView root;

            for (root = transformPipe; root is IDataTransform && !(root is PassThroughTransform); root = ((IDataTransform)root).Source)
            {
                ;
            }
            if (!(root is PassThroughTransform))
            {
                var tr = new PassThroughTransform(_env, new PassThroughTransform.Arguments(), root);
                transformPipe = ApplyTransformUtils.ApplyAllTransformsToData(_env, transformPipe, tr, root);
            }

            var stack = new List <IDataView>();

            for (root = transformPipe; root is IDataTransform; root = ((IDataTransform)root).Source)
            {
                stack.Add(root);
            }
            stack.Reverse();

            _transforms = new StepTransform[stack.Count];
            for (int i = 0; i < _transforms.Length; ++i)
            {
                _transforms[i] = new StepTransform()
                {
                    transform = stack[i] as IDataTransform, transformSettings = null
                }
            }
            ;

            if (pred == null)
            {
                _predictor = new StepPredictor()
                {
                    predictor = null, roleMapData = null, trainer = null, trainerSettings = null
                }
            }
            ;
            else
            {
#pragma warning disable CS0618
                var ipred = pred.GetPredictorObject() as IPredictor;
#pragma warning restore CS0618
                _roles = ModelFileUtils.LoadRoleMappingsOrNull(_env, fs).ToList();
                var data = new RoleMappedData(transformPipe, _roles);
                _predictor = new StepPredictor()
                {
                    predictor = ipred, roleMapData = data, trainer = null, trainerSettings = null
                };
            }
            _fastValueMapper = null;
        }
        internal PredictorModelImpl(IHostEnvironment env, Stream stream)
        {
            Contracts.CheckValue(env, nameof(env));
            env.CheckValue(stream, nameof(stream));
            using (var ch = env.Start("Loading predictor model"))
            {
                // REVIEW: address the asymmetry in the way we're loading and saving the model.
                TransformModel = new TransformModelImpl(env, stream);

                var roles = ModelFileUtils.LoadRoleMappingsOrNull(env, stream);
                env.CheckDecode(roles != null, "Predictor model must contain role mappings");
                _roleMappings = roles.ToArray();

                Predictor = ModelFileUtils.LoadPredictorOrNull(env, stream);
                env.CheckDecode(Predictor != null, "Predictor model must contain a predictor");
            }
        }
Esempio n. 5
0
        public static IDataView LoadPipeWithPredictor(IHostEnvironment env, Stream modelStream, IDataView view)
        {
            // Load transforms.
            var pipe = env.LoadTransforms(modelStream, view);

            // Load predictor (if present) and apply default scorer.
            // REVIEW: distinguish the case of predictor / no predictor?
            var predictor = env.LoadPredictorOrNull(modelStream);

            if (predictor != null)
            {
                var roles = ModelFileUtils.LoadRoleMappingsOrNull(env, modelStream);
                pipe = roles != null
                    ? env.CreateDefaultScorer(new RoleMappedData(pipe, roles, opt : true), predictor)
                       : env.CreateDefaultScorer(new RoleMappedData(pipe, label : null, "Features"), predictor);
            }
            return(pipe);
        }
            /// <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.
                            }
                        }
            }
Esempio n. 7
0
        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);
            }
        }