【问题标题】:ML.NET: Why do I have to train a pretrained model?ML.NET:为什么我必须训练预训练模型?
【发布时间】:2020-12-20 18:18:32
【问题描述】:

我想使用预训练模型(如 inceptionV1/V3)进行图像分类。

所以我在 ML.NET 中设置了一个管道,我在其中加载了这个 TensorFlow 模型。但在每个教程中,我发现你必须在之后训练该模型才能获得模型。

例如这里: https://docs.microsoft.com/en-US/dotnet/machine-learning/tutorials/image-classification

=> 使用上面加载的数据训练模型: => ITransformer 模型 = pipeline.Fit(trainingData);

为什么不能在没有训练数据的情况下调用 Fit()。因为我只想使用原始加载的模型而不进行修改。它已经由 Google 用数百万张图片进行训练,应该足以满足我的所有需求。

感谢您的建议!

【问题讨论】:

  • 请阅读ml标签的描述。

标签: .net tensorflow machine-learning ml.net


【解决方案1】:

感谢您的回答,但它并没有解决我最初的问题,即未经培训我无法获得模型。

所以对于其他有同样问题的人,我找到了一种解决方法: 我没有使用 ML.NET 来加载初始模型,但我现在使用 TensorFlow.NET nuget 包来执行此操作。在那里我可以加载一个预训练的模型并使用它。

这是我使用的示例项目的链接: https://github.com/SciSharp/SciSharp-Stack-Examples/tree/master/src/TensorFlowNET.Examples/ImageProcessing 我需要两个很好的例子:

  • 文件 ImageRecognitionInception.cs 包含一个用于图像分类的 InceptionV1 模型(注意:在顶部的评论中有站立的 InceptionV3,但这是错误的。这个文件肯定使用 InceptionV1 模型 - 您可以通过图像分辨率为 224 像素。InceptionV3 使用 299 像素的图像)。
  • InceptionArchGoogLeNet.cs 文件包含一个用于图像分类的 InceptionV3 模型。

我希望这对那些也在寻找一种简单的方法来加载预训练模型而无需重新训练的人有所帮助。

【讨论】:

    【解决方案2】:

    您不必再次训练模型。只需加载它,然后使用它来进行预测。问题是模型是在 imagenet 数据集上训练的。这个数据集有 1000 个类。您的图像类型可能包含在 1000 个类别中,也可能不包含。要为您的应用程序定制模型,您应该使用您的自定义数据集对其进行训练。例如,如果您有一个包含 250 类鸟类的训练集,每个类都有一个单独的目录,并且您想要对鸟类进行分类,那么您应该使用 Inception 模型,如下所示。我

    img_size= (224,224)  # set this to the size of images you want to use
    img_shape=(224,224,3) # set this to the input image shape
    no_of_classes =250     # set this to an integer value for the number of classes
    train_dir=r'c:\birds\train'   #point this to your training directory'
    t_gen=ImageDataGenerator(preprocessing_function=tf.keras.applications.inception_v3.preprocess_input,  validation_split=0.3)
    train_gen=t_gen.flow_from_directory( directory= train_dir, target_size=img_size, 
               class_mode="categorical",  batch_size=32, shuffle=True, seed=123, 
               subset='training)
    valid_gen=t_gen.flow_from_directory(directory= train_dir, target_size=img_size, 
               class_mode="categorical", batch_size=32, shuffle=False, seed=123, 
               subset='validation')
        
    base_model=tf.keras.applications.InceptionV3( include_top=False, weights="imagenet",    
               input_shape=img_shape, pooling='max')
    x=basemodel.output
    x= Dense(512, activation-'relu')(x)
    x= Dropout(.3)(x)
    output=Dense(no_of_classes, activation='softmax')(x)
    
    model=Model(inputs=base_model.input, outputs=output)
    model.compile(Adam(lr=.001), loss='categorical_crossentropy', metrics=['accuracy'])
    history==model.fit(x=train_gen,  epochs=20, verbose=2,   
                      validation_data=valid_gen, shuffle=False,  initial_epoch=0)
    

    【讨论】:

    • 我知道我可以针对我的特定需求训练模型。但我只想按原样使用它。问题更多的是 ML.NET 不允许我在没有训练的情况下获得模型,或者?
    【解决方案3】:

    实际上,您永远不会从零开始重新训练完整的模型,而只是最后几层。顶层学习非常普遍的特征,随着我们深入网络,这些层往往会学习更具体到我们正在处理的任务的模式.事实上,我们正在根据我们的特定需求对模型进行微调。

    【讨论】:

    • 至少在 .NET 中,当我像我链接的示例中那样训练时,它只预测其中一个训练课程,而不是原来的 1000 个课程。这就是为什么它对我来说如此奇怪。
    【解决方案4】:

    只需将空数据集传递给Fit 方法,例如

        let tf = mlContext.Model.LoadTensorFlowModel modelLocation
        let pipeline = tf.ScoreTensorFlowModel("OutputNode", "InputNode", addBatchDimensionInput = false)
        let data = mlContext.Data.LoadFromEnumerable(Seq.empty<InputType>)
        let model = pipeline.Fit(data)
    

    这将加载模型并在不修改 tensorflow 模型的情况下为您获取转换器。

    【讨论】:

      猜你喜欢
      • 2017-08-19
      • 1970-01-01
      • 2022-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-03
      • 2017-03-27
      • 2020-05-27
      相关资源
      最近更新 更多