关于ML.NET v0.5的发布说明

在这个0.5版本中,咱们将TensorFlow模型评分做为ML.NET转换类添加。这样能够在ML.NET实验中使用现有的TensorFlow模型。社区提出的各类问题和反馈能够在这里找到ios

做为即将到来的ML.NET之路的一部分,咱们正在开发一种新的ML.NET API,它能够提升灵活性和易用性。当新API准备得足够好时,咱们计划弃用当前的LearningPipelineAPI。由于这将是一个重大变化,本文末尾分享咱们对多个API选项和比较的建议。
git

此博客文章提供了有关ML.NET中如下主题的详细信息:github

  • 在ML.NET v0.5中添加了TensorFlow模型评分转换(TensorFlowTransform)算法

  • 新的ML.NET API建议api

TensorFlow模型评分转换(TensorFlowTransform)

TensorFlow是一种流行的深度学习和机器学习工具包,能够训练深度神经网络(和通用数值计算)。网络

深度学习是人工智能和机器学习的一个子集,它教授程序来作人类天然而然的事情:经过实例学习。
与传统机器学习相比,它的主要区别在于深度学习模型能够学习直接从图像,声音或文本中执行对象检测和分类任务,甚至能够提供语音识别和语言翻译等任务,而传统的ML方法则严重依赖于特征工程和数据处理。
深度学习模型须要经过使用包含多个层的大量标记数据和神经网络进行训练。它目前的流行是由几个缘由引发的。首先,它在计算机视觉等一些任务上表现更好 第二,由于它能够利用如今变得可用的大量数据(而且须要该量以便表现良好)。架构

使用ML.NET 0.5,咱们开始在ML.NET中添加对深度学习的支持。今天,咱们经过新引进与TensorFlow在ML.NET整合的第一级TensorFlowTransform这使得可以以现有的TensorFlow模型,不管是你训练或从别的地方下载的,并获得来自ML.NET的TensorFlow模型的分数。并发

这种新的TensorFlow评分功能不须要您具有TensorFlow内部细节的工做知识。从长远来看,咱们将致力于使用ML.NET进行深度学习的体验变得更加容易。框架

此转换的实现基于TensorFlowSharp的代码机器学习

以下图所示,您只需在.NET Core或.NET Framework应用程序中添加对ML.NET NuGet包的引用。在封面下,ML.NET包含并引用了本机TensorFlow库,它容许您编写加载现有训练的TensorFlow模型文件以进行评分的代码。

如下代码段显示了如何在ML.NET管道中使用TensorFlow转换:
// ... Additional transformations in the pipeline code

pipeline.Add(new TensorFlowScorer()
{
    ModelFile = "model/tensorflow_inception_graph.pb",   // Example using the Inception v3 TensorFlow model
    InputColumns = new[] { "input" },                    // Name of input in the TensorFlow model
    OutputColumn = "softmax2_pre_activation"             // Name of output in the TensorFlow model
});

// ... Additional code specifying a learner and training process for the ML.NET model

您能够在此处找到与上述代码片断相关的完整代码示例TensorFlowTransform,使用TensorFlow Inception v3模型和现有LearningPipelineAPI。

上面的代码示例使用名为Inception v3的预先训练的TensorFlow模型,您能够从此处下载成立之初V3是受过训练的很是流行的图像识别模型ImageNet数据集,其中TensorFlow模型试图整个图像分红千类,如“伞”,“泽西”和“厨房”。

盗梦空间V3模型能够被归类为深卷积神经网络,能够实现对硬盘的视觉识别任务,匹配或超过在某些领域人类行为的合理性能。该模型/算法由多位研究人员根据原始论文开发:“从新思考计算机视觉的初始架构”,Szegedy等。人。

在下一个ML.NET版本中,咱们将添加功能,以便识别TensorFlow模型的预期输入和输出。目前,使用TensorFlow API或Netron等工具来探索TensorFlow模型。

若是您tensorflow_inception_graph.pb使用Netron打开上一个示例TensorFlow模型文件(并浏览模型的图形,您能够看到它如何InputColumninput图形开头的节点相关联

 

以及如何OutputColumnsoftmax2_pre_activation节点的输出相关联几乎在图的末尾。

 

限制:咱们目前正在更新ML.NET API以提升灵活性,由于在今天的ML.NET中使用TensorFlow有一些限制。就目前而言(当使用LearningPipelineAPI时),这些分数只能LearningPipeline做为输入(数字向量)用于像分类器学习者这样的学习者。可是,随着即将推出的新ML.NET API,TensorFlow模型得分将能够直接访问,所以您可使用TensorFlow模型进行评分,而无需在此示例中实现添加额外的学习者及其相关的训练过程使用数字向量要素相关标签(对象名称),基于StochasticDualCoordinateAscentClassifier建立多类分类ML.NET模型 TensorFlow模型为每一个图像文件生成/评分。

考虑到使用ML.NET提到的TensorFlow代码示例正在使用v0.5中LearningPipeline提供的当前API。接下来,支持使用TensorFlow的ML.NET API将略有不一样,而不是基于“pipeline”。这与此博客文章的下一部分有关,该部分重点介绍即将推出的ML.NET新API。

最后,咱们还要强调ML.NET框架目前正在出现TensorFlow,但将来咱们可能会考虑其余深度学习库集成,例如TorchCNTK

您能够在此处使用TensorFlowTransform现有LearningPipelineAPI 查找其余代码示例/测试

探索即将推出的新ML.NET API(0.5以后)并提供反馈

正如本文开头所提到的,咱们很是期待在制做ML.NET时建立新的ML.NET API时获得您的反馈。ML.NET的这种发展提供了比当前LearningPipelineAPI提供的更灵活的功能LearningPipeline当这个新的API准备和足够好的API将被弃用。

如下连接到咱们以GitHub形式得到的一些示例反馈,这些反馈是关于使用LearningPipelineAPI 时的限制

所以,基于LearningPipelineAPI的反馈,几周前咱们决定切换到新的ML.NET API,以解决LearningPipelineAPI目前的大部分限制

这个新ML.NET API的设计原则

咱们正在根据如下原则设计此新API:

  • 使用与Scikit-Learn,TensorFlow和Spark等其余知名框架并行的术语,咱们将尝试在命名和概念方面保持一致,使开发人员更容易理解和学习ML.NET Core。

  • 保持简单和简洁的ML场景,如简单的训练和预测。

  • 容许高级ML场景(使用当前LearningPipelineAPI 没法实现,以下一节所述)。

咱们还探索了诸如Fluent API,声明性和命令式等API方法。
有关原则和所需方案的更深刻讨论,请在GitHub中查看此问题

为何ML.NET正在从LearningPipelineAPI 切换到新的API?

做为预览版制做过程的一部分(请记住ML.NET仍处于早期预览中),咱们一直在得到LearningPipelineAPI反馈,并发现了一些咱们须要经过建立更灵活的API来解决的限制。

具体来讲,新的ML.NET API提供了当前LearningPipelineAPI 没法实现的有吸引力的功能

  • 强类型API:这种新的强类型API利用了C#功能,所以能够在编译时发现错误,同时改进编辑器中的Intellisense。

  • 更好的灵活性:此API提供可分解的训练和预测过程,消除了刚性和线性管道执行。使用新API,执行某个代码路径,而后分叉执行,以便多个路径能够重用初始公共执行。例如,与多个学习者和培训师共享给定变换的执行和转换数据,或分解管道并添加多个学习者。

这个新的API是基于概念,如EstimatorsTransformsDataView,在这篇博客文章下面的代码所示。

  • 改进的可用性:从代码直接调用API,再也不须要脚手架或日照层,在用户/开发人员编写的内容和内部API之间建立模糊的分隔。入口点再也不是强制性的。

  • 可以使用TensorFlow模型进行简单评分。因为API中提到的灵活性,您还能够简单地加载TensorFlow模型并使用它进行评分,而无需添加任何其余学习者和培训过程,如TensorFlow部分以前的“限制”主题中所述。

  • 更好地查看转换后的数据:在应用变换器时,您能够更好地查看数据。

强类型API与LearningPipelineAPI的比较

另外一个重要的比较与新API中强类型API功能有关。
做为您没有强类型API时能够得到的问题的示例,LearningPipelineAPI(以下面的代码所示)经过将列的名称指定为字符串来提供对数据列的访问,所以若是您输入错字(即,写了“Descrption”没有'i'而不是“Description”,做为示例代码中的拼写错误,你会获得一个运行时异常:

pipeline.Add(new TextFeaturizer("Description", "Descrption"));  

可是,当使用新的ML.NET API时,它是强类型的,所以若是你输入错误,它将在编译时捕获,你也能够在编辑器中使用Intellisense。

var estimator = reader.MakeEstimator()
                .Append(row => (                    
                    description: row.description.FeaturizeText()))          

有关可分解列车和预测API的详细信息

如下代码片断显示了如何使用ML.NET中的新API实现“GitHub issue labeler”示例应用程序的转换和培训过程。

这是咱们当前的提案,根据您的反馈,此API可能会相应地发展。

新的ML.NET API代码示例:

public static async Task BuildAndTrainModelToClassifyGithubIssues()
{
    var env = new MLEnvironment();

    string trainDataPath = @"Data\issues_train.tsv";

    // Create reader
    var reader = TextLoader.CreateReader(env, ctx =>
                                    (area: ctx.LoadText(1),
                                    title: ctx.LoadText(2),
                                    description: ctx.LoadText(3)),
                                    new MultiFileSource(trainDataPath), 
                                    hasHeader : true);

    var loss = new HingeLoss(new HingeLoss.Arguments() { Margin = 1 });

    var estimator = reader.MakeNewEstimator
        .Append(row => (
            // Convert string label to key. 
            label: row.area.ToKey(),
            // Featurize 'description'
            description: row.description.FeaturizeText(),
            // Featurize 'title'
            title: row.title.FeaturizeText()))
        .Append(row => (
            // Concatenate the two features into a vector and normalize.
            features: row.description.ConcatWith(row.title).Normalize(),
            // Preserve the label - otherwise it will be dropped
            label: row.label))
        .Append(row => (
            // Preserve the label (for evaluation)
            row.label,
            // Train the linear predictor (SDCA)
            score: row.label.PredictSdcaClassification(row.features, loss: loss)))
        .Append(row => (
            // Want the prediction, as well as label and score which are needed for evaluation
            predictedLabel: row.score.predictedLabel.ToValue(),
            row.label,
            row.score));

    // Read the data
    var data = reader.Read(new MultiFileSource(trainDataPath));

    // Fit the data to get a model
    var model = estimator.Fit(data);

    // Use the model to get predictions on the test dataset and evaluate the accuracy of the model
    var scores = model.Transform(reader.Read(new MultiFileSource(@"Data\issues_test.tsv")));
    var metrics = MultiClassClassifierEvaluator.Evaluate(scores, r => r.label, r => r.score);

    Console.WriteLine("Micro-accuracy is: " + metrics.AccuracyMicro);

    // Save the ML.NET model into a .ZIP file
    await model.WriteAsync("github-Model.zip");
}

public static async Task PredictLableForGithubIssueAsync()
{
    // Read model from an ML.NET .ZIP model file
    var model = await PredictionModel.ReadAsync("github-Model.zip");

    // Create a prediction function that can be used to score incoming issues
    var predictor = model.AsDynamic.MakePredictionFunction<GitHubIssue, IssuePrediction>(env);

    // This prediction will classify this particular issue in a type such as "EF and Database access"
    var prediction = predictor.Predict(new GitHubIssue
    {
        title = "Sample issue related to Entity Framework",
        description = @"When using Entity Framework Core I'm experiencing database connection failures when running queries or transactions. Looks like it could be related to transient faults in network communication agains the Azure SQL Database."
    });

    Console.WriteLine("Predicted label is: " + prediction.predictedLabel);
}

与如下LearningPipeline缺少灵活性的API代码段相比较,由于管道执行不可分解可是线性:

旧的LearningPipelineAPI代码示例:

public static async Task BuildAndTrainModelToClassifyGithubIssuesAsync()
{
        // Create the pipeline
    var pipeline = new LearningPipeline();

    // Read the data
    pipeline.Add(new TextLoader(DataPath).CreateFrom<GitHubIssue>(useHeader: true));

    // Dictionarize the "Area" column
    pipeline.Add(new Dictionarizer(("Area", "Label")));

    // Featurize the "Title" column
    pipeline.Add(new TextFeaturizer("Title", "Title"));

    // Featurize the "Description" column
    pipeline.Add(new TextFeaturizer("Description", "Description"));
    
    // Concatenate the provided columns
    pipeline.Add(new ColumnConcatenator("Features", "Title", "Description"));

    // Set the algorithm/learner to use when training
    pipeline.Add(new StochasticDualCoordinateAscentClassifier());

    // Specify the column to predict when scoring
    pipeline.Add(new PredictedLabelColumnOriginalValueConverter() { PredictedLabelColumn = "PredictedLabel" });

    Console.WriteLine("=============== Training model ===============");

    // Train the model
    var model = pipeline.Train<GitHubIssue, GitHubIssuePrediction>();

    // Save the model to a .zip file
    await model.WriteAsync(ModelPath);

    Console.WriteLine("=============== End training ===============");
    Console.WriteLine("The model is saved to {0}", ModelPath);
}

public static async Task<string> PredictLabelForGitHubIssueAsync()
{
    // Read model from an ML.NET .ZIP model file
    _model = await PredictionModel.ReadAsync<GitHubIssue, GitHubIssuePrediction>(ModelPath);
    
    // This prediction will classify this particular issue in a type such as "EF and Database access"
    var prediction = _model.Predict(new GitHubIssue
        {
            Title = "Sample issue related to Entity Framework", 
            Description = "When using Entity Framework Core I'm experiencing database connection failures when running queries or transactions. Looks like it could be related to transient faults in network communication agains the Azure SQL Database..."
        });

    return prediction.Area;
}

LearningPipelineAPI是彻底线性的代码路径,所以您没法将其分解为多个部分。
例如,BikeSharing ML.NET示例(在机器学习样本GitHub repo中可用)正在使用当前的LearningPipelineAPI。

此示例使用评估程序API经过如下方式比较回归学习者的准确性:

  • 执行多个数据转换为原始数据集
  • 基于七种不一样的回归训练器/算法(如FastTreeRegressor,FastTreeTweedieRegressor,StochasticDualCoordinateAscentRegressor等)训练和建立七种不一样的ML.NET模型

目的是帮助您比较给定问题的回归学习者。

因为这些模型的数据转换是相同的,所以您可能但愿重用与转换相关的代码执行。可是,因为LearningPipelineAPI仅提供单个线性执行,所以您须要为您建立/训练的每一个模型运行相同的数据转换步骤,如如下代码摘录自BikeSharing ML.NET示例所示

var fastTreeModel = new ModelBuilder(trainingDataLocation, new FastTreeRegressor()).BuildAndTrain();
var fastTreeMetrics = modelEvaluator.Evaluate(fastTreeModel, testDataLocation);
PrintMetrics("Fast Tree", fastTreeMetrics);

var fastForestModel = new ModelBuilder(trainingDataLocation, new FastForestRegressor()).BuildAndTrain();
var fastForestMetrics = modelEvaluator.Evaluate(fastForestModel, testDataLocation);
PrintMetrics("Fast Forest", fastForestMetrics);

var poissonModel = new ModelBuilder(trainingDataLocation, new PoissonRegressor()).BuildAndTrain();
var poissonMetrics = modelEvaluator.Evaluate(poissonModel, testDataLocation);
PrintMetrics("Poisson", poissonMetrics);

//Other learners/algorithms
//...

BuildAndTrain()方法须要同时具备数据转换和每种状况下的不一样算法,如如下代码所示:

public PredictionModel<BikeSharingDemandSample, BikeSharingDemandPrediction> BuildAndTrain()
{
    var pipeline = new LearningPipeline();
    pipeline.Add(new TextLoader(_trainingDataLocation).CreateFrom<BikeSharingDemandSample>(useHeader: true, separator: ','));
    pipeline.Add(new ColumnCopier(("Count", "Label")));
    pipeline.Add(new ColumnConcatenator("Features", 
                                        "Season", 
                                        "Year", 
                                        "Month", 
                                        "Hour", 
                                        "Weekday", 
                                        "Weather", 
                                        "Temperature", 
                                        "NormalizedTemperature",
                                        "Humidity",
                                        "Windspeed"));
    pipeline.Add(_algorythm);

    return pipeline.Train<BikeSharingDemandSample, BikeSharingDemandPrediction>();
}            

使用旧LearningPipelineAPI,对于使用不一样算法的每次培训,您须要再次运行相同的过程,一次又一次地执行如下步骤:

  • 从文件加载数据集
  • 进行列转换(连续,复制或其余特征或字典,若是须要)

可是,基于新的ML.NET API EstimatorsDataView您将可以重用部分执行,就像在这种状况下同样,从新使用数据转换执行做为使用不一样算法的多个模型的基础。

您还能够在此处使用新API探索其余代码示例。

相关文章
相关标签/搜索