ML.NET库学习009:花卉图像分类模型

embedded/2025/2/22 17:42:50/

文章目录

  • ML.NET库学习009:花卉图像分类模型
    • 进行图像分类训练的实现
      • 功能分析
      • 代码结构
      • 核心组件
      • 示例输出
      • 代码实现
      • 详细步骤说明
      • 注意事项
    • 进行图像分类预测的实现
      • 主要目的
      • 原理概述
      • 实现的主要功能
      • 主要流程步骤
      • 使用的主要函数和方法
      • 关键技术
      • 功能详细解读
        • (1)模型加载与预测引擎创建
        • (2)图像数据读取
        • (3)单次预测与性能测量
        • (4)批量预测
      • 实现步骤分步骤
      • 数据结构设计
    • 关键技术
      • 1. 数据结构与内容说明
      • 2. 样本数据清洗方法
      • 3. 预测数据处理方法说明
    • 示例代码
    • 分步解释
        • `MapValueToKey` 函数
        • `LoadRawImageBytes` 函数
        • `.Fit()` 和 `.Transform()` 方法
        • `ImageClassification` 函数
        • `MapKeyToValue` 函数
    • 什么是 Shuffle 清洗操作?
      • 为什么需要 Shuffle?
      • 在 Python 中使用 `random.shuffle()`:
      • 机器学习框架中:
    • Shuffle 的注意事项
    • 总结

ML.NET库学习009:花卉图像分类模型

进行图像分类训练的实现

功能分析

该C#程序使用Microsoft的ML.NET库来构建一个花卉图像分类模型。主要功能包括:

  1. 下载和加载数据集:从指定URL下载花卉图片数据集,并解压到本地目录。
  2. 训练模型:基于预训练的TensorFlow模型(如Inception v3),通过迁移学习训练新的分类器,以识别不同种类的花卉。
  3. 评估模型性能:在测试数据集上评估模型的准确性、精确度等指标。
  4. 保存模型:将训练好的模型保存为ML.NET和TensorFlow格式,以便后续使用。
  5. 单张图片预测:加载一张图片,使用训练好的模型进行预测,并输出结果。

代码结构

  1. 主函数(Main Method)

    • 下载数据集
    • 加载并预处理图像数据
    • 训练模型
    • 评估模型
    • 保存模型
    • 进行单张图片的预测测试
  2. 辅助方法

    • LoadImagesFromDirectory:从指定目录加载图像,并生成ImageData对象。
    • DownloadImageSet:下载并解压远程数据集文件。
    • EvaluateModel:评估模型在测试集上的性能。
    • TrySinglePrediction:使用训练好的模型对单张图片进行预测。

核心组件

  • 迁移学习:利用预训练的TensorFlow模型,通过微调来适应新的花卉分类任务。这可以减少训练时间,并提高模型性能。

  • 图像处理:加载、缩放和归一化处理图像数据,使其适合输入到深度学习模型中。

  • 模型评估:使用准确率、精确度、召回率等指标来衡量模型的性能。

示例输出

运行该程序后,控制台将显示以下内容:

  1. 训练时间:显示训练模型所用的时间。
  2. 评估结果:显示测试集上的分类准确率和其它相关指标。
  3. 单张图片预测:输出被预测图片的文件名、预测标签及其概率。

代码实现

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.ML.Core.Data;
using Microsoft.ML.Transforms.Image;
using Microsoft.ML.Models;public class Program
{public static void Main(string[] args){// 下载数据集并加载图像string imagesFolderPath = "images";DownloadImages(imagesFolderPath);// 加载训练和测试数据var data = LoadImageData(imagesFolderPath);// 划分训练集和测试集var splits = data.TrainTestSplit(0.7, shuffle: true);var trainData = splits.Train;var testData = splits.Test;// 定义模型管道IEstimator<ImageData, ImagePrediction> pipeline =new LearningPipeline(new ConvertImageToFloat(),new DenseVectorizer<ImageData>(),new StochasticGradientDescent<LogisticRegression>().SetMaximumNumberOfIterations(100));// 训练模型var trainedModel = pipeline.Fit(trainData);// 评估模型性能Evaluate(trainedModel, testData);// 保存模型SaveModel(trainedModel, trainData.Schema, "trained-model.zip");// 单张图片预测示例TrySinglePrediction("test-images", trainedModel);}private static void DownloadImages(string folder){var url = "https://example.com/flower-dataset.zip";DownloadFile(url, folder + "/dataset.zip");Unzip(folder + "/dataset.zip", folder);}private static List<ImageData> LoadImageData(string folder){return Directory.GetFiles(folder).Select(f => new ImageData {ImagePath = f}).ToList();}private static void Evaluate(IEstimator<ImageData, ImagePrediction> model, IDataView testData){var prediction = model.Predict(testData);var accuracy = prediction.Accuracy();Console.WriteLine($"Accuracy: {accuracy}");}private static void SaveModel(IEstimator<ImageData, ImagePrediction> model, Schema<ImageData> schema, string filename){// 实现模型保存逻辑}private static void TrySinglePrediction(string testFolder, IEstimator<ImageData, ImagePrediction> model){var imagePaths = Directory.GetFiles(testFolder);foreach (var imagePath in imagePaths){var prediction = model.Predict(new ImageData {ImagePath = imagePath});Console.WriteLine($"Image: {imagePath}, Prediction: {prediction.PredictedLabel}");}}
}

详细步骤说明

  1. 下载数据集

    • 使用DownloadImages方法从指定URL下载花卉图片数据集,并将其解压到本地目录。
  2. 加载和预处理图像

    • 使用LoadImageData方法将所有图像文件路径加载为ImageData对象列表,每个对象包含图像的路径信息。
  3. 训练模型

    • 构建一个机器学习管道,包括将图像转换为浮点数、将其向量化以及使用随机梯度下降优化逻辑回归模型。
    • 调用Fit方法在训练数据上训练模型。
  4. 评估模型性能

    • 使用测试数据集评估训练好的模型,并输出分类准确率等指标。
  5. 保存模型

    • 将训练好的模型保存为文件,以便后续使用。
  6. 单张图片预测

    • 加载一张测试图片,使用训练好的模型进行预测,并输出结果。

注意事项

  • 数据集路径:确保imagestest-images目录存在,并且包含正确的图像文件。
  • 依赖项管理:需要安装ML.NET库以及相关的NuGet包。
  • 性能优化:可以调整训练参数,如学习率、迭代次数等,以提高模型性能。

进行图像分类预测的实现

主要目的

本项目的目的是利用训练好的机器学习模型对输入的图像进行分类预测。具体来说,模型将根据输入的图片特征(如颜色、纹理等)输出图片所属的类别标签及其概率。

原理概述

  • 监督学习:使用预训练好的模型对新的数据进行预测。
  • 卷积神经网络 (CNN):通常用于图像分类任务,能够自动提取图像中的特征。
  • ML.NET:一个开源的机器学习框架,提供了丰富的功能来构建和部署机器学习模型。

实现的主要功能

  • 加载预训练好的 ML.NET 模型文件(.zip 格式)。
  • 使用模型对输入图像进行分类预测,并输出预测结果及其概率。
  • 测量单次和多次预测的时间,以评估模型的性能。

主要流程步骤

  1. 初始化 MLContext 对象。
  2. 加载预训练好的模型文件。
  3. 创建预测引擎(Prediction Engine),用于处理输入数据并生成预测结果。
  4. 读取输入目录中的所有图像文件,并将其转换为模型可接受的格式。
  5. 使用预测引擎对每张图片进行预测,输出结果。

使用的主要函数和方法

  • MLContext.Model.Load:加载预训练好的模型文件。
  • CreatePredictionEngine:创建预测引擎,用于处理输入数据并生成预测结果。
  • FileUtils.LoadInMemoryImagesFromDirectory:从指定目录读取所有图像文件,并将其转换为 InMemoryImageData 格式。

关键技术

  • 数据结构的设计(如 InMemoryImageDataImagePrediction)。
  • 模型加载和预测引擎的创建。
  • 图像数据预处理和结果解析。

功能详细解读

(1)模型加载与预测引擎创建
  • 使用 MLContext.Model.Load 方法加载 .zip 格式的模型文件。
  • 调用 CreatePredictionEngine 创建一个可以处理输入数据并输出预测结果的引擎。
(2)图像数据读取
  • 使用 FileUtils.LoadInMemoryImagesFromDirectory 从指定目录读取所有图像文件,并将它们转换为 InMemoryImageData 格式的对象。
  • 每个 InMemoryImageData 对象包含图片的字节数组、高度和宽度,以及图片文件名。
(3)单次预测与性能测量
  • 使用 predictionEngine.Predict 方法对单张图像进行预测,并记录预测时间。
  • 输出预测结果(类别标签及其概率)。
(4)批量预测
  • 对输入目录中的所有图像逐一进行预测,输出每张图片的预测结果。

实现步骤分步骤

// 初始化 MLContext
var mlContext = new MLContext(seed: 1);// 加载模型
var loadedModel = mlContext.Model.Load(imageClassifierModelZipFilePath, out var modelInputSchema);// 创建预测引擎
var predictionEngine = mlContext.Model.CreatePredictionEngine(modelInputSchema, loadedModel);

数据结构设计

  • InMemoryImageData:用于存储单张图像的数据,包括图片字节数组、高度、宽度和文件名。
public class InMemoryImageData
{public byte[] ImageBytes { get; set; }public int Height { get; set; }public int Width { get; set; }public string ImageFileName { get; set; }
}
  • ImagePrediction:用于存储模型输出的预测结果,包括类别标签和概率。
public class ImagePrediction
{public string PredictedLabel { get; set; }public float[] Score { get; set; }
}

关键技术

1. 数据结构与内容说明

  • InMemoryImageData:用于存储输入图片的原始数据和属性信息,方便模型处理。
  • ImagePrediction:用于存储模型输出的结果,包括预测类别标签及其概率。

2. 样本数据清洗方法

  • 在训练阶段,需要对图像进行预处理(如调整大小、归一化等)并按类别标签分组。
  • 使用 FileUtils.LoadInMemoryImagesFromDirectory 函数加载和转换图像数据。

3. 预测数据处理方法说明

  • 输入格式:预测阶段的图像数据需要以 InMemoryImageData 格式传递给模型。
  • 输出结果:模型返回一个 ImagePrediction 对象,包含类别标签及其概率。

示例代码

using Microsoft.ML;
using Microsoft.ML.Data;public class InMemoryImageData
{public byte[] ImageBytes { get; set; }public int Height { get; set; }public int Width { get; set; }public string ImageFileName { get; set; }
}public class ImagePrediction
{public string PredictedLabel { get; set; }public float[] Score { get; set; }
}class Program
{static void Main(string[] args){var mlContext = new MLContext(seed: 1);// 加载模型文件路径string modelFilePath = @"path\to\model.zip";ITransformer loadedModel;var modelInputSchema = mlContext.Model.Load(modelFilePath, out loadedModel);// 创建预测引擎var predictionEngine = mlContext.Model.CreatePredictionEngine(modelInputSchema, loadedModel);// 加载输入图片目录string inputImagePath = @"path\to\input_images";var images = FileUtils.LoadInMemoryImagesFromDirectory(inputImagePath).ToList();foreach (var image in images){var prediction = predictionEngine.Predict(image);Console.WriteLine($"Image: {image.ImageFileName}, Predicted Label: {prediction.PredictedLabel}, Probability: {prediction.Score.Max()}");}}
}

通过以上分析和实现,我们能够高效地利用 ML.NET 进行图像分类预测,并进一步优化模型性能以满足实际需求。


分步解释

  1. 加载并转换数据

    IDataView shuffledFullImagesDataset = mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelAsKey", inputColumnName: "Label", keyOrdinality: KeyOrdinality.ByValue).Append(mlContext.Transforms.LoadRawImageBytes(outputColumnName: "Image",imageFolder: fullImagesetFolderPath,inputColumnName: "ImagePath")).Fit(shuffledFullImageFilePathsDataset).Transform(shuffledFullImageFilePathsDataset);
    
MapValueToKey 函数
  • 作用:将字符串类型的标签(如“猫”、“狗”等)转换为整数类型的键。这是因为大多数机器学习算法更擅长处理数值类型的数据。
  • 参数
    • 输出列名: 新生成的列名,通常是 “LabelAsKey”。
    • 输入列名: 原始标签所在的列名,如 “Label”。
    • 键序数性: 指定如何为不同的类别分配数值。KeyOrdinality.ByName 表示根据类别名称的字典顺序来排序。
LoadRawImageBytes 函数
  • 作用:从指定的文件夹中加载图像,并将它们转换为适合机器学习模型处理的数据格式(通常是二维数组或张量)。
  • 参数
    • 输出列名: 存储图像数据的新列名,如 “Image”。
    • 图像文件夹: 包含训练图像的文件夹路径,例如 fullImagesetFolderPath
    • 输入列名: 包含图像文件路径的列名,如 “ImagePath”。
.Fit().Transform() 方法
  • 作用.Fit() 用于训练数据转换器,使其能够将原始数据转换为模型所需的格式。.Transform() 则应用已训练好的转换器到实际数据上。
  • 过程
    • 首先调用 .Fit(已打乱的全图像文件路径数据集),让转换器了解如何处理输入数据。
    • 然后调用 .Transform(已打乱的全图像文件路径数据集),将原始数据转换为目标格式,并存储在 shuffledFullImagesDataset 中。
  1. 划分训练集和测试集

    var trainTestData = mlContext.Data.TrainTestSplit(shuffledFullImagesDataset, testFraction: 0.2);
    IDataView trainDataView = trainTestData.TrainSet;
    IDataView testDataView = trainTestData.TestSet;
    
    • TrainTestSplit:将数据集按80%训练和20%测试的比例划分为两部分。
    • trainDataViewtestDataView:分别表示训练集和测试集的数据视图,用于后续模型训练和评估。
  2. 定义机器学习管道

var pipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(featureColumnName: "Image",labelColumnName: "LabelAsKey",validationSet:testDataView) .Append(mlContext.Transforms.Conversion.MapKeyToValue(outputColumnName:"PredictedLabel", inputColumnName: "PredictedLabel"));
  • MapValueToKey:再次将标签列转换为键,确保模型训练时能够正确处理标签。
  • LoadRawImageBytes:加载图像数据到特征列"Image"中。
  • ImageClassification:定义一个图像分类器,使用转移学习在预训练模型上进行微调。
  • MapKeyToValue:将预测结果从键转换回原始标签值,输出列为"PredictedLabel"。
ImageClassification 函数
  • 作用:初始化一个图像分类器,通常基于深度神经网络(DNN),用于处理多类分类任务。
  • 参数
    • 特征列名: 输入数据中存储图像特征的列名,如 “Image”。
    • 标签列名: 存储类别标签的列名,如 “LabelAsKey”。
    • 验证集: 提供一个独立的数据子集用于模型评估和调优。
MapKeyToValue 函数
  • 作用:将模型预测的结果从数值形式(键)转换回原始的文本形式(值),以便于人类理解。
  • 参数
    • 输出列名: 存储转换后结果的列名,如 “PredictedLabel”。
    • 输入列名: 模型输出的数值结果所在的列名。
  1. 训练模型

    Console.WriteLine("*** Training the image classification model with DNN Transfer Learning on top of the selected pre-trained model/architecture ***");var watch = Stopwatch.StartNew();ITransformer trainedModel = pipeline.Fit(trainDataView);watch.Stop();
    Console.WriteLine($"Training completed in {watch.Elapsed.TotalSeconds} seconds.");
    
    • Fit:使用训练集数据对管道进行拟合,生成一个训练好的模型转换器trainedModel
    • 计时器:记录模型的训练时间,输出到控制台。

通过以上步骤,完整的图像分类模型训练流程得以实现。首先,数据经过预处理和转换以适应机器学习的要求;然后,数据被划分为训练集和测试集;接着,定义并配置了包含特征提取、模型训练和结果转译的管道;最后,使用训练数据拟合模型,并输出训练所需的时间。这一流程确保了模型能够有效地从数据中学习,并为后续的预测任务做好准备。

什么是 Shuffle 清洗操作?

在数据预处理和机器学习任务中,“Shuffle” 是一种常见的操作,主要用于随机打乱数据集的顺序。这种操作有助于确保模型在训练过程中不会因为数据的排列方式而引入不必要的偏倚,从而提高模型的泛化能力。


为什么需要 Shuffle?

  1. 防止顺序偏差

    • 在某些情况下,数据可能是按某种特定顺序排列的(例如时间序列数据),直接使用这种顺序进行训练可能导致模型记住这种顺序而不是学习数据本身的模式。
  2. 确保随机性

    • 打乱数据顺序可以增加训练过程中的随机性,使得模型在不同批次中看到的数据更加多样化,有助于避免过拟合。
  3. 提升模型泛化能力

    • 通过 Shuffle,模型不会因为特定的排列方式而记住某些模式,从而更有效地学习到数据的整体特征。

在 Python 中使用 random.shuffle()

import random# 示例数据集
data = [1, 2, 3, 4, 5]# 打乱数据顺序
random.shuffle(data)print("打乱后的数据:", data)

机器学习框架中:

  • Scikit-learn

    • 使用 train_test_split 函数时,可以通过设置 shuffle=True 来实现 Shuffle。
    from sklearn.model_selection import train_test_split# 示例数据集
    X = ...
    y = ...# 分割数据并打乱顺序
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=True)
    
  • TensorFlow/Keras

    • 在训练模型时,可以通过设置 shuffle=True 来启用 Shuffle。
    model.fit(X_train, y_train, epochs=10, batch_size=32, shuffle=True)
    

Shuffle 的注意事项

  1. 确保数据完整

    • Shuffle 应该在训练集、验证集和测试集之间分别进行,避免污染测试数据。
  2. 保持分组完整性(可选)

    • 如果某些情况下需要保持特定的分组关系(例如时间序列数据),则不应打乱顺序。此时需要谨慎使用 Shuffle。
  3. 随机种子(Optional)

    • 为了复现实验结果,可以在 Shuffle 时设置一个固定的随机种子。
    random.seed(42)
    random.shuffle(data)
    

Shuffle 是一种重要的数据清洗操作,主要用于随机打乱数据集的顺序,以避免模型因数据排列方式而引入偏差,并提升其泛化能力。在实际应用中,合理使用 Shuffle 可以显著改善模型性能。

总结

这个程序展示了如何使用ML.NET进行花卉图像分类。


http://www.ppmy.cn/embedded/164396.html

相关文章

【Rust中级教程】1.15. Trait bounds(Trait 约束)的编译与分派

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 1.15.1. 静态分发(static dispatch) 编译泛型代码或者调用dyn Trait(详见【Rust自学】17.2…

Unity摄像机与灯光相关知识

一、Inspector窗口 Inspector窗口可以查看和编辑对象的属性以及设置 其中包含各种组件&#xff0c;例如用Cube对象来举例 1.Sphere(Mesh)组件&#xff1a; 用来决定对象的网格属性&#xff0c;例如球体网格为Sphere、立方体网格为Cube 2.Mesh Renderer组件&#xff1a; 用来设置…

8.python文件

文章目录 1.**文件**1.1**文件是什么**1.2**文件路径**1.3**文件操作**1.3.1**打开文件**1.3.2**关闭文件**1.3.3**写文件**1.3.4**读文件** 1.4**关于中文的处理**1.5**使用上下文管理器** 大家好&#xff0c;我是晓星航。今天为大家带来的是 python文件 相关的讲解&#xff0…

Deepseek 与 ChatGPT:AI 浪潮中的双子星较量

引言 在人工智能飞速发展的当下&#xff0c;AI 语言模型成为了人们关注的焦点。Deepseek 与 ChatGPT 作为其中的佼佼者&#xff0c;各自展现出独特的魅力&#xff0c;引领着 AI 技术的发展潮流。今天&#xff0c;就让我们深入探讨这两款模型&#xff0c;看看它们在 AI 领域中是…

使用 DeepSeek 生成流程图、甘特图与思维导图:结合 Typora 和 XMind 的高效工作流

在现代工作与学习中&#xff0c;可视化工具如流程图、甘特图和思维导图能够极大地提升信息整理与表达的效率。本文将详细介绍如何使用 DeepSeek 生成 Mermaid 文本&#xff0c;结合 Typora 快速生成流程图和甘特图&#xff0c;并通过 Markdown 格式生成思维导图&#xff0c;最终…

题海拾贝:【枚举】P2010 [NOIP 2016 普及组] 回文日期

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

智信BI:解决Power BI全面兼容问题的新选择

随着企业数据量的持续增长&#xff0c;数据可视化的重要性日益凸显。智信BI作为一套现代化的数据可视化平台&#xff0c;专注于帮助企业应对复杂的数据分析挑战。该平台支持多种报表形式&#xff0c;包括Power BI报表、格式化报表及Office报表&#xff0c;满足不同用户的多样化…

分步教程:使用 i18next 本地化 React 网站

分步教程&#xff1a;使用 i18next 本地化 React 网站 通过本指南学习如何为 React 应用添加多语言支持&#xff0c;实现动态语言切换和翻译管理。 前置条件 基础的 React.js 知识已安装 Node.js 和 npm/yarn通过 create-react-app 创建的 React 项目 步骤 1&#xff1a;安装所…