ML.NET:如何使用新数据重新训练文本分类模型

rip*_*nas 5 .net c# machine-learning ml.net

总的来说,我对机器学习非常陌生,尤其是 Microsoft ML.NET。我想做的是为文本分类创建一个可重新训练的模型。假设我有一篇文章(用于训练)和一篇文章预测(用于分类):

public class Article
{
    public string Text { get; set; }
    public string Topic { get; set; }
}

public class ArticlePrediction
{
    public float[] Score { get; set; }
    public uint PredictedLabel { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

根据可重新训练模型的文档此 GitHub 问题,我得出结论,我将需要两个管道 - 准备管道和训练管道。并为“准备好的”数据创建一个单独的中间模型,以便进行重新训练:

public class ArticlePrepared : Article
{
    [VectorType(???)]
    public float[] Features { get; set; }
    public uint Label { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

模型的实际训练是微不足道的:

public static void Train(MLContext ctx, IDataView data)
{
    var prepPipeline = ctx.Transforms.Conversion.MapValueToKey("Label", "Topic")
        .Append(ctx.Transforms.Text.FeaturizeText("Features", "Text"));
    var trainPipeline = ctx.MulticlassClassification.Trainers
        .LbfgsMaximumEntropy("Label", "Features", historySize: 50, l1Regularization: 0.1f);

    var prepModel = prepPipeline.Fit(data);
    var prepData = prepModel.Transform(data);
    var trainModel = trainPipeline.Fit(prepData);

    ctx.Model.Save(prepModel, data.Schema, PreparationPipelinePath);
    ctx.Model.Save(trainModel, prepData.Schema, TrainingPipelinePath);
}
Run Code Online (Sandbox Code Playgroud)

再培训部分是我正在努力解决的部分,我现在怀疑这是否可能:

public static void Retrain(MLContext ctx, Article article)
{
    var prepModel = ctx.Model.Load(PreparationPipelinePath, out var _);
    var retrainModel = ctx.Model.Load(TrainingPipelinePath, out var _) as ISingleFeaturePredictionTransformer<object>;
    var modelParams = (MaximumEntropyModelParameters)retrainModel.Model;

    var prepData = prepModel.Transform(ctx.Data.LoadFromEnumerable(new[] { article }));

    var retrainedModel = ctx.MulticlassClassification.Trainers
        .LbfgsMaximumEntropy("Label", "Features", historySize: 50, l1Regularization: 0.1f)
        .Fit(prepData, modelParams); // boom!

    ctx.Model.Save(retrainedModel, prepData.Schema, TrainingPipelinePath);
}
Run Code Online (Sandbox Code Playgroud)

收到的异常是未找到有效的训练实例,所有实例都缺少特征。 我有几个问题:

  • 在我看来,文本中的每个单词都被转换为模型特征。这意味着当我尝试用新Article的模型重新训练模型时,训练好的模型不具有这个新模型的所有特征Article(因为我想重新训练模型的新文本是不同的)。这是我收到异常的原因吗?

  • 在对文本进行特征化时,无法确定准备好的ArticlePrepared模型应该具有多少特征(即VectorType属性的大小,或Features数组属性的长度)。是否可以使用动态数量的功能?如果您检查 GitHub 存储库(下面的链接),您会看到VectorType大小为 131,但这是从已保存的架构中获取的硬编码值。不用说,像这样的硬编码在现实世界中是行不通的。

我创建了一个可用于重现问题的GitHub 存储库

有没有办法做我想做的事情,还是我走错了方向?任何帮助或见解表示赞赏。