/// <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>());
            }
        }
        /// <summary>
        /// Load the model and its input schema from the stream.
        /// </summary>
        /// <param name="stream">A readable, seekable stream to load from.</param>
        /// <returns>A model of type <see cref="CompositeDataLoader{IMultiStreamSource, ITransformer}"/> containing the loader
        /// and the transformer chain.</returns>
        public IDataLoader <IMultiStreamSource> Load(Stream stream)
        {
            _env.CheckValue(stream, nameof(stream));

            using (var rep = RepositoryReader.Open(stream))
            {
                try
                {
                    ModelLoadContext.LoadModel <IDataLoader <IMultiStreamSource>, SignatureLoadModel>(_env, out var model, rep, null);
                    return(model);
                }
                catch (Exception ex)
                {
                    throw _env.Except(ex, "Model does not contain an IDataLoader");
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Load a transformer model and a data loader model from a stream.
        /// </summary>
        /// <param name="stream">A readable, seekable stream to load from.</param>
        /// <param name="loader">The data loader from the model stream. Note that if there is no data loader,
        /// this method will throw an exception. The scenario where no loader is stored in the stream should
        /// be handled instead using the <see cref="Load(Stream, out DataViewSchema)"/> method.</param>
        /// <returns>The transformer model from the model stream.</returns>
        public ITransformer LoadWithDataLoader(Stream stream, out IDataLoader <IMultiStreamSource> loader)
        {
            _env.CheckValue(stream, nameof(stream));

            using (var rep = RepositoryReader.Open(stream))
            {
                try
                {
                    ModelLoadContext.LoadModel <IDataLoader <IMultiStreamSource>, SignatureLoadModel>(_env, out loader, rep, null);
                    return(DecomposeLoader(ref loader));
                }
                catch (Exception ex)
                {
                    throw _env.Except(ex, "Model does not contain an " + nameof(IDataLoader <IMultiStreamSource>) +
                                      ". Perhaps this was saved with an " + nameof(DataViewSchema) + ", or even no information on its input at all. " +
                                      "Consider using the " + nameof(Load) + " method instead.");
                }
            }
        }