在本文中,我们将研究一个卷积神经网络来解决硬币识别问题,并且我们将在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. Thread.start() ,它是怎么让线程启动的呢?

    作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...

  2. 网络拓扑实例之RRPP单环(五)

    组网图形 RRPP简介 在城域网和企业网的网络规划以及实际组网应用中大多会采用环网结构来提高网络的可靠性.采用环网结构的好处是:当环上任意一个节点或节点之间的链路发生故障,都可以将数据流量切换到备份链 ...

  3. Python爬虫实现翻译功能

    前言 学了这么久的python理论知识,需要开始实战来练手巩固了. 准备 首先安装爬虫urllib库 pip install urllib 获取有道翻译的链接url 需要发送的参数在form data ...

  4. 放进你的收藏夹吃灰!Linux 运维必备的 40 个命令总结

    1.删除0字节文件 find -type f -size 0 -exec rm -rf {} ; 2.查看进程 按内存从大到小排列 PS -e -o "%C : %p : %z : %a&q ...

  5. 测试Hessian反序反序列化 客户端少字段和多字段时能否成功

    import java.io.*; import com.caucho.hessian.io.HessianInput; import com.caucho.hessian.io.HessianOut ...

  6. ios真机使用fixed定位页面滚动时fixed定位的元素也会跟着滚动

    到了ios真机APP中,页面向下滚动,fixed的元素也跟着滚,虽然最后它还是到了它该在的地方,但是它跟着滚动也很影响页面的流畅性和交互性好伐.

  7. MySQL下载及使用

    MySQL下载及使用 在下载MySQL的过程当中一般都不会下载最新版本的软件,因为最新版本的MySQL可能会出现各种问题,也不推荐在原来的版本上更新到最新版本,因为这样可能导致原本项目能正常运行,更新 ...

  8. 【PSMA】Progressive Sample Mining and Representation Learning for One-Shot Re-ID

    目录 主要挑战 主要的贡献和创新点 提出的方法 总体框架与算法 Vanilla pseudo label sampling (PLS) PLS with adversarial learning Tr ...

  9. 去除openwrite.cn博客验证码限制

    相信有的小伙伴肯定遇到过如下这种情况,但是作为老白嫖党肯定是 「下次一定」 了,所以今天我们来看看如何不关注公众号实现 「阅读原文」. 如何解决呢? 1.通过 F12 打开控制台,切换至 Elemen ...

  10. springboot多模块项目搭建遇到的问题记录

    废话不多说,直接上问题报错与解决方法. 问题报错一:(报错信息看下方代码) 问题原因:'com.company.logistics.service.company.CompanyService' 未找 ...