在本文中,我们将研究一个卷积神经网络来解决硬币识别问题,并且我们将在Keras.NET中实现一个卷积神经网络。

在这里,我们将介绍卷积神经网络(CNN),并提出一个CNN的架构,我们将训练它来识别硬币。

什么是CNN?正如我们在本系列的前一篇文章中提到的,CNN是一类经常用于图像分类任务的神经网络(NN),比如物体和人脸识别。在CNN中,并非每个节点都连接到下一层的所有节点。这种部分连通性有助于防止在完全连接的网络神经网络中出现的过拟合问题,并且加速了神经网络的收敛速度。

围绕CNN的核心概念是一种被称为卷积的数学运算,卷积在数字信号处理领域非常常见。卷积被定义为两个函数的乘积,产生的第三个函数表示前两个函数之间的重叠量。

在物体识别中,卷积操作允许我们检测图像中的不同特征,如垂直和水平的边缘,纹理和曲线。这就是为什么任何CNN的第一层都是卷积层。

CNN中另一个常见的层是池化层。池化用于减少图像表示的大小,这意味着减少参数的数量,并最终减少计算量。最常见的池化类型是最大池化,它在每个位置上从匹配的单元格组中获取最大值。最后,根据所获得的最大值建立新的图像。

另一个与卷积相关的概念是填充。填充保证了卷积过程将均匀地发生在整个图像,包括边界像素。这个保证是由一个零像素的边框支持的,该边框在缩小后的图像周围添加(在池化之后),以便可以以相同的次数访问图像的所有像素。

最常见的CNN架构通常从卷积层开始,接着是激活层,然后是池化层,最后是传统的全连接网络,比如多层NN。这种类型的模型是层次化的,称为顺序模型。为什么以一个完全连接的网络结束?为了学习转换后图像(经过卷积和池化)中的特征的非线性组合。

下面是我们将在CNN中实现的架构:

  • Conv2D层- 32个过滤器,过滤器大小为3
  • 激活层使用ReLU函数
  • Conv2D层- 32个过滤器,过滤器大小为3
  • 激活层使用ReLU函数
  • MaxPooling2D层-应用(2,2)池窗口
  • DropOut图层,25% -通过随机删除前一层的一些值来防止过拟合(设置为0);也就是稀释法
  • Conv2D层- 64个过滤器,过滤器大小为3
  • 激活层使用ReLU函数
  • Conv2D图层- 64个过滤器,过滤器大小为3,步幅为3
  • 激活层使用ReLU函数
  • MaxPooling2D层-应用(2,2)池窗口
  • DropOut层,25%
  • Flatten层-转换数据,以在下一层中使用
  • Dense 层——表示具有512个节点的传统神经网络的全连接。
  • 激活层使用ReLU函数
  • DropOut层,在50%
  • Dense层,与节点数量匹配的类的数量
  • Softmax层

该体系结构遵循了一种用于物体识别的CNN体系结构模式;层参数通过实验进行了微调。

我们经过的参数微调过程的结果部分存储在Settings类中,我们在这里展示:

public class Settings
{
public const int ImgWidth = 64;
public const int ImgHeight = 64;
public const int MaxValue = 255;
public const int MinValue = 0;
public const int Channels = 3;
public const int BatchSize = 12;
public const int Epochs = 10;
public const int FullyConnectedNodes = 512;
public const string LossFunction = "categorical_crossentropy";
public const string Accuracy = "accuracy";
public const string ActivationFunction = "relu";
public const string PaddingMode = "same";
public static StringOrInstance Optimizer = new RMSprop(lr: Lr, decay: Decay);
private const float Lr = 0.0001f;
private const float Decay = 1e-6f;
}

我们现在有了CNN的体系结构。接下来,我们将研究使用Keras.NET实现的用于硬币识别的CNN。

首先,让我们从Nuget包管理器下载Keras.NET包。我们可以在Tools > Nuget package manager中找到Nuget包管理器。Keras.NET依赖于包Numpy.NET和pythonnet_netstandard。如果没有安装它们,让我们继续安装它们。

需要指出的是,Keras.NET 需要在你的操作系统中安装Python 2.7-3.7版本。它还需要安装Python库Numpy和TensorFlow。在本例中,我们使用的是64位的Python 3.7。

如果在执行本文中的代码时遇到任何问题,请在控制台应用程序中主方法的开始执行时尝试运行以下代码一次。这段代码将设置所需的环境变量,以便找到所有dll:

private static void SetupPyEnv()
{
string envPythonHome = @"C:\Users\arnal\AppData\Local\Programs\Python\Python37\";
string envPythonLib = envPythonHome + "Lib\\;" + envPythonHome + @"Lib\site-packages\";
Environment.SetEnvironmentVariable("PYTHONHOME", envPythonHome, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PATH", envPythonHome + ";" + envPythonLib + ";" + Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine), EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONPATH", envPythonLib, EnvironmentVariableTarget.User);
PythonEngine.PythonHome = envPythonHome;
PythonEngine.PythonPath = Environment.GetEnvironmentVariable("PYTHONPATH");
}

现在我们将看到使用Keras.NET创建我们的硬币识别CNN是多么简单和透明。下面的类显示了包含模型的所有逻辑的Cnn类。

public class Cnn
{
private DataSet _dataset;
private Sequential _model; public Cnn(DataSet dataset)
{
_dataset = dataset;
_model = new Sequential();
} public void Train()
{
// Build CNN model
_model.Add(new Conv2D(32, kernel_size: (3, 3).ToTuple(),
padding: Settings.PaddingMode,
input_shape: new Shape(Settings.ImgWidth, Settings.ImgHeight, Settings.Channels)));
_model.Add(new Activation(Settings.ActivationFunction));
_model.Add(new Conv2D(32, (3, 3).ToTuple()));
_model.Add(new Activation(Settings.ActivationFunction));
_model.Add(new MaxPooling2D(pool_size: (2, 2).ToTuple()));
_model.Add(new Dropout(0.25)); _model.Add(new Conv2D(64, kernel_size: (3, 3).ToTuple(),
padding: Settings.PaddingMode));
_model.Add(new Activation(Settings.ActivationFunction));
_model.Add(new Conv2D(64, (3, 3).ToTuple()));
_model.Add(new Activation(Settings.ActivationFunction));
_model.Add(new MaxPooling2D(pool_size: (2, 2).ToTuple()));
_model.Add(new Dropout(0.25)); _model.Add(new Flatten());
_model.Add(new Dense(Settings.FullyConnectedNodes));
_model.Add(new Activation(Settings.ActivationFunction));
_model.Add(new Dropout(0.5));
_model.Add(new Dense(_dataset.NumberClasses));
_model.Add(new Softmax()); _model.Compile(loss: Settings.LossFunction,
optimizer: Settings.Optimizer,
metrics: new string[] { Settings.Accuracy }); _model.Fit(_dataset.TrainX, _dataset.TrainY,
batch_size: Settings.BatchSize,
epochs: Settings.Epochs,
validation_data: new NDarray[] { _dataset.ValidationX, _dataset.ValidationY }); var score = _model.Evaluate(_dataset.ValidationX, _dataset.ValidationY, verbose: 0);
Console.WriteLine("Test loss:" + score[0]);
Console.WriteLine("Test accuracy:" + score[1]);
} public NDarray Predict(string imgPath)
{
NDarray x = Utils.Normalize(imgPath);
x = x.reshape(1, x.shape[0], x.shape[1], x.shape[2]);
return _model.Predict(x);
}
}

如我们所见,我们首先有一个构造函数,用于接收数据集(在本系列的第二篇文章中导入和处理),并创建Sequential类的新实例存储在私有变量_model中。Sequential是什么?这是一个空模型,它给了我们叠加层次的可能性,而这正是我们所需要的。

然后,在Train方法中,我们首先按照上一篇文章中介绍的架构创建我们的层堆栈,然后编译模型并调用fit方法开始训练。使用的损失函数是categorical_crossentropy。什么是损失函数?它是我们用来优化学习过程的函数,也就是说,我们要么最小化它,要么最大化它。负责最小化损失函数的是优化器——一种通过改变网络的权重和学习率来最小化损失的算法。

最后,利用验证数据集对模型进行评估。另一个方法是Predict,顾名思义,它预测新输入数据的标签。训练结束后,应调用此方法。开始训练阶段就像运行以下代码一样简单:

var cnn = new Cnn(dataSet);
cnn.Train();

让我们来看看在这个系列中我们正在经历的硬币识别问题的训练中所获得的结果:

我们可以看到,在训练过程中,我们能够达到100%的准确率。在prediction方法中,它的输出将是一个NDarray,它包含了物体或图像属于CNN某个类的概率。

那么,什么样的架构需要GPU而不是CPU呢?例如,AlexNet体系结构包括5个卷积层和3个完全连接的层,以及池化和激活层。这种类型的深度CNN由于其复杂性,在GPU上表现得更好。一般的规则是,你添加的层越多,权重的计算就会越复杂。

在了解了如何编写自己的CNN之后,我们将进入预训练模型的领域。下一篇文章将详细介绍这一点!

欢迎关注我的公众号,如果你有喜欢的外文技术文章,可以通过公众号留言推荐给我。

原文链接:https://www.codeproject.com/Articles/5284228/Deep-Learning-in-Csharp-Coin-Recognition-in-Keras

C#中的深度学习(四):使用Keras.NET识别硬币的更多相关文章

  1. Deep learning for visual understanding: A review 视觉理解中的深度学习:回顾 之一

    Deep learning for visual understanding: A review 视觉理解中的深度学习:回顾 ABSTRACT: Deep learning algorithms ar ...

  2. keras框架下的深度学习(一)手写体识别

    这个系列文章主要记录使用keras框架来搭建深度学习模型的学习过程,其中有一些自己的想法和体会,主要学习的书籍是:Deep Learning with Python,使用的IDE是pycharm. 在 ...

  3. CNCC2017中的深度学习与跨媒体智能

    CNCC2017中的深度学习与跨媒体智能 转载请注明作者:梦里茶 目录 机器学习与跨媒体智能 传统方法与深度学习 图像分割 小数据集下的深度学习 语音前沿技术 生成模型 基于贝叶斯的视觉信息编解码 珠 ...

  4. 如何使用深度学习破解验证码 keras 连续验证码

    在实现网络爬虫的过程中,验证码的出现总是会阻碍爬虫的工作.本期介绍一种利用深度神经网络来实现的端到端的验证码识别方法.通过本方法,可以在不切割图片.不做模板匹配的情况下实现精度超过90%的识别结果. ...

  5. 深度学习框架: Keras官方中文版文档正式发布

    今年 1 月 12 日,Keras 作者 François Chollet‏ 在推特上表示因为中文读者的广泛关注,他已经在 GitHub 上展开了一个 Keras 中文文档项目.而昨日,Françoi ...

  6. [Deep-Learning-with-Python]计算机视觉中的深度学习

    包括: 理解卷积神经网络 使用数据增强缓解过拟合 使用预训练卷积网络做特征提取 微调预训练网络模型 可视化卷积网络学习结果以及分类决策过程 介绍卷积神经网络,convnets,深度学习在计算机视觉方面 ...

  7. PyTorch中使用深度学习(CNN和LSTM)的自动图像标题

    介绍 深度学习现在是一个非常猖獗的领域 - 有如此多的应用程序日复一日地出现.深入了解深度学习的最佳方法是亲自动手.尽可能多地参与项目,并尝试自己完成.这将帮助您更深入地掌握主题,并帮助您成为更好的深 ...

  8. Deep-Learning-with-Python] 文本序列中的深度学习

    https://blog.csdn.net/LSG_Down/article/details/81327072 将文本数据处理成有用的数据表示 循环神经网络 使用1D卷积处理序列数据 深度学习模型可以 ...

  9. C#中的深度学习(三):理解神经网络结构

    在这篇文章中,我们将回顾监督机器学习的基础知识,以及训练和验证阶段包括哪些内容. 在这里,我们将为不了解AI的读者介绍机器学习(ML)的基础知识,并且我们将描述在监督机器学习模型中的训练和验证步骤. ...

随机推荐

  1. zabbix的搭建及操作(4)实现邮件,钉钉,微信报警

    实现邮件报警 网页版邮箱中开启 POP3/SMTP/IMAP 生成授权码并记录 Server端安装配置邮件服务器 1.Yum安装邮件服务器 yum -y install mailx dos2unix ...

  2. tcp连接的三次握手

    为什么tcp连接需要三次握手才能建立连接 主要是为了初始化sequence number的初始值,通信的双方要互相通知双方的sequence number,这个要作为以后数据通信的序号,保证以后不会因 ...

  3. php bypass disable_function 命令执行 方法汇总简述

    1.使用未被禁用的其他函数 exec,shell_exec,system,popen,proc_open,passthru (python_eval?perl_system ? weevely3 wi ...

  4. Python正则表达式大全

    前言 正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"))操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成 ...

  5. appium元素定位工具

      appium元素定位工具介绍 使用uiautomatorviewer定位工具 使用Appium Inspector定位工具 使用uiautomatorviewer定位工具 谷歌在Android S ...

  6. Java蓝桥杯01——第一题集锦:堆煤球、购物单、哪天返回、第几天、分数

    堆煤球(2016JavaB) 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形), .... 如果一共有100 ...

  7. 深度学习论文翻译解析(十五):Densely Connected Convolutional Networks

    论文标题:Densely Connected Convolutional Networks 论文作者:Gao Huang Zhuang Liu Laurens van der Maaten  Kili ...

  8. 【刷题笔记】DP优化-状压

    因为篇幅太长翻着麻烦,计划把DP拆成几个小专题,这里原文只留下状压,其他请至后续博文. 状态压缩优化 所谓状态压缩,就是将原本需要很多很多维来描述,甚至暴力根本描述不清的状态压缩成一维来描述. 时间复 ...

  9. websocket简单实现五子棋即时对战功能

    几年前做的一个小demo,代码比较老,先上下html显示效果图 因为代码中注释比较详细,所以就直接上代码了 html代码,也就是上图展示的效果页面 <!DOCTYPE html> < ...

  10. Python之【模块】

    双层装饰器 一个函数可以被多个装饰器装饰: 多层装饰器的本质是:嵌套: 执行规则是:解释自下而上,执行自上而下 •简单的用户权限验证程序: USE_INFO = {} # 初始化一个字典,用户存放用户 ...