TensorFlow.NET机器学习入门【5】采用神经网络实现手写数字识别(MNIST)
从这篇文章开始,终于要干点正儿八经的工作了,前面都是准备工作。这次我们要解决机器学习的经典问题,MNIST手写数字识别。
首先介绍一下数据集。请首先解压:TF_Net\Asset\mnist_png.tar.gz文件
文件夹内包括两个文件夹:training和validation,其中training文件夹下包括60000个训练图片validation下包括10000个评估图片,图片为28*28像素,分别放在0~9十个文件夹中。
程序总体流程和上一篇文章介绍的BMI分析程序基本一致,毕竟都是多元分类,有几点不一样。
1、BMI程序的特征数据(输入)为一维数组,包含两个数字,MNIST的特征数据为28*28的二位数组;
2、BMI程序的输出为3个,MNIST的输出为10个;
网络模型构建如下:
private readonly int img_rows = 28;
private readonly int img_cols = 28;
private readonly int num_classes = 10; // total classes
/// <summary>
/// 构建网络模型
/// </summary>
private Model BuildModel()
{
// 网络参数
int n_hidden_1 = 128; // 1st layer number of neurons.
int n_hidden_2 = 128; // 2nd layer number of neurons.
float scale = 1.0f / 255; var model = keras.Sequential(new List<ILayer>
{
keras.layers.InputLayer((img_rows,img_cols)),
keras.layers.Flatten(),
keras.layers.Rescaling(scale),
keras.layers.Dense(n_hidden_1, activation:keras.activations.Relu),
keras.layers.Dense(n_hidden_2, activation:keras.activations.Relu),
keras.layers.Dense(num_classes, activation:keras.activations.Softmax)
}); return model;
}
这个网络里用到了两个新方法,需要解释一下:
1、Flatten方法:这里表示拉平,把28*28的二维数组拉平为含784个数据的一维数组,因为二维数组无法进行运算;
2、Rescaling 方法:就是对每个数据乘以一个系数,因为我们从图片获取的数据为每一个位点的灰度值,其取值范围为0~255,所以乘以一个系数将数据缩小到1以内,以免后面运算时溢出。
其它基本和上一篇文章介绍的差不多,全部代码如下:

/// <summary>
/// 通过神经网络来实现多元分类
/// </summary>
public class NN_MultipleClassification_BMI
{
private readonly Random random = new Random(1); // 网络参数
int num_features = 2; // data features
int num_classes = 3; // total output . public void Run()
{
var model = BuildModel();
model.summary(); Console.WriteLine("Press any key to continue...");
Console.ReadKey(); (NDArray train_x, NDArray train_y) = PrepareData(1000);
model.compile(optimizer: keras.optimizers.Adam(0.001f),
loss: keras.losses.SparseCategoricalCrossentropy(),
metrics: new[] { "accuracy" });
model.fit(train_x, train_y, batch_size: 128, epochs: 300); test(model);
} /// <summary>
/// 构建网络模型
/// </summary>
private Model BuildModel()
{
// 网络参数
int n_hidden_1 = 64; // 1st layer number of neurons.
int n_hidden_2 = 64; // 2nd layer number of neurons. var model = keras.Sequential(new List<ILayer>
{
keras.layers.InputLayer(num_features),
keras.layers.Dense(n_hidden_1, activation:keras.activations.Relu),
keras.layers.Dense(n_hidden_2, activation:keras.activations.Relu),
keras.layers.Dense(num_classes, activation:keras.activations.Softmax)
}); return model;
} /// <summary>
/// 加载训练数据
/// </summary>
/// <param name="total_size"></param>
private (NDArray, NDArray) PrepareData(int total_size)
{
float[,] arrx = new float[total_size, num_features];
int[] arry = new int[total_size]; for (int i = 0; i < total_size; i++)
{
float weight = (float)random.Next(30, 100) / 100;
float height = (float)random.Next(140, 190) / 100;
float bmi = (weight * 100) / (height * height); arrx[i, 0] = weight;
arrx[i, 1] = height; switch (bmi)
{
case var x when x < 18.0f:
arry[i] = 0;
break; case var x when x >= 18.0f && x <= 28.0f:
arry[i] = 1;
break; case var x when x > 28.0f:
arry[i] = 2;
break;
}
} return (np.array(arrx), np.array(arry));
} /// <summary>
/// 消费模型
/// </summary>
private void test(Model model)
{
int test_size = 20;
for (int i = 0; i < test_size; i++)
{
float weight = (float)random.Next(40, 90) / 100;
float height = (float)random.Next(145, 185) / 100;
float bmi = (weight * 100) / (height * height); var test_x = np.array(new float[1, 2] { { weight, height } });
var pred_y = model.Apply(test_x); Console.WriteLine($"{i}:weight={(float)weight} \theight={height} \tBMI={bmi:0.0} \tPred:{pred_y[0].numpy()}");
}
}
}
另有两点说明:
1、由于对图片的读取比较耗时,所以我采用了一个方法,就是把读取到的数据序列化到一个二进制文件中,下次直接从二进制文件反序列化即可,大大加快处理速度。
2、我没有采用validation图片进行评估,只是简单选了20个样本测试了一下。
【相关资源】
源码:Git: https://gitee.com/seabluescn/tf_not.git
项目名称:NN_MultipleClassification_MNIST
TensorFlow.NET机器学习入门【5】采用神经网络实现手写数字识别(MNIST)的更多相关文章
- TensorFlow卷积神经网络实现手写数字识别以及可视化
边学习边笔记 https://www.cnblogs.com/felixwang2/p/9190602.html # https://www.cnblogs.com/felixwang2/p/9190 ...
- TensorFlow 之 手写数字识别MNIST
官方文档: MNIST For ML Beginners - https://www.tensorflow.org/get_started/mnist/beginners Deep MNIST for ...
- BP神经网络的手写数字识别
BP神经网络的手写数字识别 ANN 人工神经网络算法在实践中往往给人难以琢磨的印象,有句老话叫“出来混总是要还的”,大概是由于具有很强的非线性模拟和处理能力,因此作为代价上帝让它“黑盒”化了.作为一种 ...
- 利用c++编写bp神经网络实现手写数字识别详解
利用c++编写bp神经网络实现手写数字识别 写在前面 从大一入学开始,本菜菜就一直想学习一下神经网络算法,但由于时间和资源所限,一直未展开比较透彻的学习.大二下人工智能课的修习,给了我一个学习的契机. ...
- 第二节,TensorFlow 使用前馈神经网络实现手写数字识别
一 感知器 感知器学习笔记:https://blog.csdn.net/liyuanbhu/article/details/51622695 感知器(Perceptron)是二分类的线性分类模型,其输 ...
- 5 TensorFlow入门笔记之RNN实现手写数字识别
------------------------------------ 写在开头:此文参照莫烦python教程(墙裂推荐!!!) ---------------------------------- ...
- 卷积神经网络CNN 手写数字识别
1. 知识点准备 在了解 CNN 网络神经之前有两个概念要理解,第一是二维图像上卷积的概念,第二是 pooling 的概念. a. 卷积 关于卷积的概念和细节可以参考这里,卷积运算有两个非常重要特性, ...
- 【机器学习】BP神经网络实现手写数字识别
最近用python写了一个实现手写数字识别的BP神经网络,BP的推导到处都是,但是一动手才知道,会理论推导跟实现它是两回事.关于BP神经网络的实现网上有一些代码,可惜或多或少都有各种问题,在下手写了一 ...
- BP神经网络(手写数字识别)
1实验环境 实验环境:CPU i7-3770@3.40GHz,内存8G,windows10 64位操作系统 实现语言:python 实验数据:Mnist数据集 程序使用的数据库是mnist手写数字数据 ...
随机推荐
- 案例 高级定时器和通用定时器产生pwm的区别 gd32和stm32
- python下载openpyxl
直接下载openpyxl报错 ERROR: Command errored out with exit status 1: python setup.py egg_info Check the log ...
- redis安装与简单实用
1.在Linux上redis的安装时十分简单的: 第一步:wget http://download.redis.io/releases/redis-2.8.12.tar.gz 解压: tar zxvf ...
- Virtual functions in derived classes
In C++, once a member function is declared as a virtual function in a base class, it becomes virtual ...
- Activiti工作流引擎使用详解(一)
一.IDEA安装activiti插件 在插件库中查找actiBPM,安装该插件,如果找不到该插件,请到插件库中下载该包手动安装,插件地址 http://plugins.jetbrains.com/pl ...
- 【Spring Framework】Spring入门教程(八)Spring的事务管理
事务是什么? 事务:指单个逻辑操作单元的集合. 在操作数据库时(增删改),如果同时操作多次数据,我们从业务希望,要么全部成功,要么全部失败.这种情况称为事务处理. 例如:A转账给B. 第一步,扣除A君 ...
- HashMap、ConcurrentHashMap对比
1.hashmap的put的原理,hashmap的扩容及计算槽的算法,线程安全的hashtable.ConcurrentHashMap的区别是什么 1.1 hashMap的put原理 什么时候变成红黑 ...
- 【C#】【MySQL】C#连接MySQL数据库(二)解析
C# MySQL 实现简单登录验证 后端代码解析 Visual Studio中使用MySQL的环境配置 下文所有到的代码(前端后端) 请查阅这篇博文 C#连接MySQL数据库(一)代码 获取前端数据 ...
- 新手指南:顶象验证码如何接入微信小程序?
自2017年小程序发布以来,经过4年的快速发展,小程序已然成为企业互联网布局不可或缺的一环.无论是互联网企业还是拥抱互联网的传统企业,无论是服务导向型企业还是产品导向型企业,小程序都为用户提供了一种轻 ...
- Log4j2又爆雷!2.16.0存在DOS风险,升级2.17.0可解决
本以为,经过上周的2.16.0版本升级,Log4j2的漏洞修复工作,大家基本都要告一段落了. 万万没想到,就在周末,Log4j官方又发布了新版本:2.17.0 该版本主要修复安全漏洞:CVE-2021 ...