在本文中,我们将研究一个卷积神经网络来解决硬币识别问题,并且我们将在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. 免费AWS云服务器一键搭建Trojan详细教程

    前言 想要撸AWS服务器的可以看我上一篇博客,这里就不介绍了,以下步骤有问题的朋友可以私信或者评论区留言. 配置AWS云服务器 选择语言,博主写了博客后才看到,前面都是使用谷歌翻译. 选择地区 创建虚 ...

  2. P1633 二进制

    首先将 \(A,B,C\) 二进制中 \(1\) 的个数和最大长度 \(L\) 算出来. 接着考虑二进制位相加的情况: 低位不进上来. \(X\) 和 \(Y\) 中的两个 \(1\) 合成 \(Z\ ...

  3. 蓝桥杯——测试次数·摔手机(2018JavaB组第4题,17分)

    x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机. 各大厂商也就纷纷推出各种耐摔型手机.x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通. x ...

  4. 【微信开发】缓存的asscess_token过期

    开发中有遇到这样一个问题,我们一般会将从微信拿到的寿命2个小时的access_token缓存起来,业务里这个缓存的时间是90分钟, 90分钟之后缓存过期,会重新请求新的access_token使旧的a ...

  5. Beta冲刺——用户测试报告

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta 冲刺 这个作业的目标 团队进行Alpha冲刺 作业正文 正文 其他参考文献 无 用户测试报告 用户 ...

  6. mySQL初学者一定要掌握的数据操纵

    本文献给与作者一样不断地在追求梦想的小伙伴! 文章目录 1.INSERT 语句为表中所有字段添加数据 (1)可以指定所有字段名添加数据 (2)可以不指定字段名添加数据 (3)可以指定部分字段添加数据 ...

  7. Kafak探究之路- 内部结构小结

    1.框架与工作流 2 内部结构 kafka的每个主题分区的数据在 first-0(主题名-分区号)文件夹下,保存 n组xxx.log文件与xxx.index文件.log文件存发送消息的元数据,每个大小 ...

  8. Java之选择排序(正序、逆序)

    public class SelectSort { public static void main(String[] args) { /** * @author JadeXu * @// TODO: ...

  9. python核心高级学习总结3-------python实现进程的三种方式及其区别

    python实现进程的三种方式及其区别 在python中有三种方式用于实现进程 多进程中, 每个进程中所有数据( 包括全局变量) 都各有拥有⼀份, 互不影响 1.fork()方法 ret = os.f ...

  10. PyQt(Python+Qt)学习随笔:QScrollArea的widgetResizable属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 滚动区域的widgetResizable属性用于控制滚动区域的内容部署层是否应跟随滚动区域的大小变化 ...