机器学习框架ML.NET学习笔记【5】多元分类之手写数字识别(续)
一、概述
上一篇文章我们利用ML.NET的多元分类算法实现了一个手写数字识别的例子,这个例子存在一个问题,就是输入的数据是预处理过的,很不直观,这次我们要直接通过图片来进行学习和判断。思路很简单,就是写一个自定义的数据处理通道,输入为文件名,输出为float数字,里面保存的是像素信息。
样本包括6万张训练图片和1万张测试图片,图片为灰度图片,分辨率为20*20 。train_tags.tsv文件对每个图片的数值进行了标记,如下:
二、源码
全部代码:
namespace MulticlassClassification_Mnist
{
class Program
{
//Assets files download from:https://gitee.com/seabluescn/ML_Assets
static readonly string AssetsFolder = @"D:\StepByStep\Blogs\ML_Assets\MNIST";
static readonly string TrainTagsPath = Path.Combine(AssetsFolder, "train_tags.tsv");
static readonly string TrainDataFolder = Path.Combine(AssetsFolder, "train");
static readonly string ModelPath = Path.Combine(Environment.CurrentDirectory, "Data", "SDCA-Model.zip"); static void Main(string[] args)
{
MLContext mlContext = new MLContext(seed: ); TrainAndSaveModel(mlContext);
TestSomePredictions(mlContext); Console.WriteLine("Hit any key to finish the app");
Console.ReadKey();
} public static void TrainAndSaveModel(MLContext mlContext)
{
// STEP 1: 准备数据
var fulldata = mlContext.Data.LoadFromTextFile<InputData>(path: TrainTagsPath, separatorChar: '\t', hasHeader: false);
var trainTestData = mlContext.Data.TrainTestSplit(fulldata, testFraction: 0.1);
var trainData = trainTestData.TrainSet;
var testData = trainTestData.TestSet; // STEP 2: 配置数据处理管道
var dataProcessPipeline = mlContext.Transforms.CustomMapping(new LoadImageConversion().GetMapping(), contractName: "LoadImageConversionAction")
.Append(mlContext.Transforms.Conversion.MapValueToKey("Label", "Number", keyOrdinality: ValueToKeyMappingEstimator.KeyOrdinality.ByValue))
.Append(mlContext.Transforms.NormalizeMeanVariance( outputColumnName: "FeaturesNormalizedByMeanVar", inputColumnName: "ImagePixels")); // STEP 3: 配置训练算法 (using a maximum entropy classification model trained with the L-BFGS method)
var trainer = mlContext.MulticlassClassification.Trainers.LbfgsMaximumEntropy(labelColumnName: "Label", featureColumnName: "FeaturesNormalizedByMeanVar");
var trainingPipeline = dataProcessPipeline.Append(trainer)
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictNumber", "Label")); // STEP 4: 训练模型使其与数据集拟合
ITransformer trainedModel = trainingPipeline.Fit(trainData); // STEP 5:评估模型的准确性
var predictions = trainedModel.Transform(testData);
var metrics = mlContext.MulticlassClassification.Evaluate(data: predictions, labelColumnName: "Label", scoreColumnName: "Score");
PrintMultiClassClassificationMetrics(trainer.ToString(), metrics); // STEP 6:保存模型
mlContext.Model.Save(trainedModel, trainData.Schema, ModelPath);
} private static void TestSomePredictions(MLContext mlContext)
{
// Load Model
ITransformer trainedModel = mlContext.Model.Load(ModelPath, out var modelInputSchema); // Create prediction engine
var predEngine = mlContext.Model.CreatePredictionEngine<InputData, OutPutData>(trainedModel); DirectoryInfo TestFolder = new DirectoryInfo(Path.Combine(AssetsFolder, "test"));
foreach(var image in TestFolder.GetFiles())
{
count++; InputData img = new InputData()
{
FileName = image.Name
};
var result = predEngine.Predict(img); Console.WriteLine($"Current Source={img.FileName},PredictResult={result.GetPredictResult()}");
}
}
} class InputData
{
[LoadColumn()]
public string FileName; [LoadColumn()]
public string Number; [LoadColumn()]
public float Serial;
} class OutPutData : InputData
{
public float[] Score;
public int GetPredictResult()
{
float max = ;
int index = ;
for (int i = ; i < Score.Length; i++)
{
if (Score[i] > max)
{
max = Score[i];
index = i;
}
}
return index;
}
}
}
三、分析
整个处理流程和上一篇文章基本一致,这里解释两个不一样的地方。
1、自定义的图片读取处理通道
namespace MulticlassClassification_Mnist
{
public class LoadImageConversionInput
{
public string FileName { get; set; }
} public class LoadImageConversionOutput
{
[VectorType()]
public float[] ImagePixels { get; set; }
public string ImagePath;
} [CustomMappingFactoryAttribute("LoadImageConversionAction")]
public class LoadImageConversion : CustomMappingFactory<LoadImageConversionInput, LoadImageConversionOutput>
{
static readonly string TrainDataFolder = @"D:\StepByStep\Blogs\ML_Assets\MNIST\train"; public void CustomAction(LoadImageConversionInput input, LoadImageConversionOutput output)
{
string ImagePath = Path.Combine(TrainDataFolder, input.FileName);
output.ImagePath = ImagePath; Bitmap bmp = Image.FromFile(ImagePath) as Bitmap; output.ImagePixels = new float[];
for (int x = ; x < ; x++)
for (int y = ; y < ; y++)
{
var pixel = bmp.GetPixel(x, y);
var gray = (pixel.R + pixel.G + pixel.B) / / ;
output.ImagePixels[x + y * ] = gray;
}
bmp.Dispose();
} public override Action<LoadImageConversionInput, LoadImageConversionOutput> GetMapping()
=> CustomAction;
}
}
这里可以看出,我们自定义的数据处理通道,输入为文件名称,输出是一个float数组,这里数组必须要指定宽度,由于图片分辨率为20*20,所以数组宽度指定为400,输出ImagePath为文件详细地址,用来调试使用,没有实际用途。处理思路非常简单,遍历每个Pixel,计算其灰度值,为了减少工作量我们把灰度值进行缩小,除以了16 ,由于后面数据会做归一化,所以这里影响不是太明显。
2、模型测试
DirectoryInfo TestFolder = new DirectoryInfo(Path.Combine(AssetsFolder, "test"));
int count = ;
int success = ;
foreach(var image in TestFolder.GetFiles())
{
count++; InputData img = new InputData()
{
FileName = image.Name
};
var result = predEngine.Predict(img); if(int.Parse(image.Name.Substring(,))==result.GetPredictResult())
{
success++;
}
}
我们把测试目录里的全面图片读出遍历了一遍,将其测试结果和实际结果做了一次验证,实际上是把评估(Evaluate)的事情又重复做了一次,两次测试的成功率基本接近。
四、关于图片特征提取
我们是采用图片所有像素的灰度值来作为特征值的,但必须要强调的是:像素值矩阵不是图片的典型特征。虽然有时候对于较规则的图片,通过像素提取方式进行计算,也可以取得很好的效果,但在处理稍微复杂一点的图片的时候,就不管用了,原因很明显,我们人类在分析图片内容时看到的特征更多是线条等信息,绝对不是像素值,看下图:
我们人类很容易就判断出这两个图片表达的是同一件事情,但其像素值特征却相差甚远。
传统的图片特征提取方式很多,比如:SIFT、HOG、LBP、Haar等。 现在采用TensorFlow的模型进行特征提取效果非常好。下一篇文章介绍图片分类时再进行详细介绍。
五、资源获取
源码下载地址:https://github.com/seabluescn/Study_ML.NET
工程名称:MulticlassClassification_Mnist_Useful
MNIST资源获取:https://gitee.com/seabluescn/ML_Assets
机器学习框架ML.NET学习笔记【5】多元分类之手写数字识别(续)的更多相关文章
- 机器学习框架ML.NET学习笔记【4】多元分类之手写数字识别
一.问题与解决方案 通过多元分类算法进行手写数字识别,手写数字的图片分辨率为8*8的灰度图片.已经预先进行过处理,读取了各像素点的灰度值,并进行了标记. 其中第0列是序号(不参与运算).1-64列是像 ...
- 机器学习框架ML.NET学习笔记【6】TensorFlow图片分类
一.概述 通过之前两篇文章的学习,我们应该已经了解了多元分类的工作原理,图片的分类其流程和之前完全一致,其中最核心的问题就是特征的提取,只要完成特征提取,分类算法就很好处理了,具体流程如下: 之前介绍 ...
- 机器学习框架ML.NET学习笔记【7】人物图片颜值判断
一.概述 这次要解决的问题是输入一张照片,输出人物的颜值数据. 学习样本来源于华南理工大学发布的SCUT-FBP5500数据集,数据集包括 5500 人,每人按颜值魅力打分,分值在 1 到 5 分之间 ...
- 机器学习框架ML.NET学习笔记【3】文本特征分析
一.要解决的问题 问题:常常一些单位或组织召开会议时需要录入会议记录,我们需要通过机器学习对用户输入的文本内容进行自动评判,合格或不合格.(同样的问题还类似垃圾短信检测.工作日志质量分析等.) 处理思 ...
- 机器学习框架ML.NET学习笔记【2】入门之二元分类
一.准备样本 接上一篇文章提到的问题:根据一个人的身高.体重来判断一个人的身材是否很好.但我手上没有样本数据,只能伪造一批数据了,伪造的数据比较标准,用来学习还是蛮合适的. 下面是我用来伪造数据的代码 ...
- 机器学习框架ML.NET学习笔记【1】基本概念与系列文章目录
一.序言 微软的机器学习框架于2018年5月出了0.1版本,2019年5月发布1.0版本.期间各版本之间差异(包括命名空间.方法等)还是比较大的,随着1.0版发布,应该是趋于稳定了.之前在园子里也看到 ...
- 机器学习框架ML.NET学习笔记【8】目标检测(采用YOLO2模型)
一.概述 本篇文章介绍通过YOLO模型进行目标识别的应用,原始代码来源于:https://github.com/dotnet/machinelearning-samples 实现的功能是输入一张图片, ...
- 机器学习框架ML.NET学习笔记【9】自动学习
一.概述 本篇我们首先通过回归算法实现一个葡萄酒品质预测的程序,然后通过AutoML的方法再重新实现,通过对比两种实现方式来学习AutoML的应用. 首先数据集来自于竞赛网站kaggle.com的UC ...
- 深度学习面试题12:LeNet(手写数字识别)
目录 神经网络的卷积.池化.拉伸 LeNet网络结构 LeNet在MNIST数据集上应用 参考资料 LeNet是卷积神经网络的祖师爷LeCun在1998年提出,用于解决手写数字识别的视觉任务.自那时起 ...
随机推荐
- HTml js 生成图片
<script type="text/javascript"> function $(id) { return document.getElementById(id); ...
- ACM学习历程——HDU5017 Ellipsoid(模拟退火)(2014西安网赛K题)
---恢复内容开始--- Description Given a 3-dimension ellipsoid(椭球面) your task is to find the minimal distanc ...
- ACM学习历程—NPU 2015年陕西省程序设计竞赛网络预赛(正式赛)F题 和谐的比赛(递推)
Description 今天西工大举办了一场比赛总共有m+n人,但是有m人比较懒没带电脑,另外的n个人带了电脑.不幸的是,今天机房的电脑全坏了只能用带的电脑,一台电脑最多两人公用,确保n>=m. ...
- CodeForces - 204C Little Elephant and Furik and Rubik
CodeForces - 204C Little Elephant and Furik and Rubik 个人感觉是很好的一道题 这道题乍一看我们无从下手,那我们就先想想怎么打暴力 暴力还不简单?枚 ...
- 关于ssh免密互访
想要通过ssh进行免密处理,细节就不赘述了,白度一搜一大把: 但是我遇到了一个情况,就是生成的公钥后无法复制到user/.ssh目录下,因为没有ssh目录(.ssh是隐藏目录,正常情况下ls都无法查看 ...
- C++多态的实现条件
#include <iostream> class Person{ public: virtual void say(){ std::cout<<"person&qu ...
- CCD与CMOS的区别?
我们在购买相机或是摄像机时,都会看到使用CMOS镜头或是CCD镜头,那么CCD与CMOS是什么意思呢,CCD与CMOS的区别是什么?首先,让我们了解CCD与CMOS的意思. CCDCCD使用一种高感光 ...
- [hdu3078]Network(LCA+排序)
题意:维护树上两点之间的最短路径,其一,将点a的值变为b,其二,求路径上第k大的值. 解题关键:LCA+sort 复杂度:$O(qn\log n + n\log n)$ 数据弱不怪我 //#pragm ...
- 面试题: 数据库笔试 sql操作 已看 上课的练习题50sql
2018/5/31 oracle数据库面试笔试试题总结http://www.yjbys.com/qiuzhizhinan/show-308759.html 1/4Oracle数据库1.基础测试选择在部 ...
- 下载win7/win8/win10镜像
关于给电脑换系统,很多人会花钱去电脑店里换,或者是下载Ghost系统.但这些系统都不是微软原版的,制作者已经集成了很多常用软件或垃圾软件进去.我在这给大家介绍的是如何下载正版的Windows系统.这个 ...