CNN | 02实现几何图形分类

2024-03-07 17:58

本文主要是介绍CNN | 02实现几何图形分类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文及数据集

https://github.com/microsoft/ai-edu/tree/master/%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/A2-%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86/%E7%AC%AC8%E6%AD%A5%20-%20%E5%8D%B7%E7%A7%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C

2 实现几何图形分类

2.1 提出问题

有一种儿童玩具:在一个平板上面有三种形状的洞:圆形、三角形、正方形,让小朋友们拿着这三种形状的积木从对应的洞中穿过那个平板就算成功。如果形状不对是穿不过去的,比如一个圆形的积木无法穿过一个方形的洞。这就要求儿童先学会识别几何形状,学会匹配,然后手眼脑配合才能成功。

人工智能现在还是初期阶段,它能否达到3岁儿童的能力呢?先看一下图18-21所示的样本数据。

图18-21 样本数据

一共有5种形状:圆形、菱形、直线、矩形、三角形。上图中列出了一些样本,由于图片尺寸是28x28的灰度图,所以在放大显示后可以看到很多锯齿,读者可以忽略。需要强调的是,每种形状的尺寸和位置在每个样本上都是有差异的,它们的大小和位置都是随机的,比如圆形的圆心位置和半径都是不一样的,还有可能是个椭圆。

其实二维几何形状识别是一个经典的话题了,如果不用神经网络的话,用一些传统的算法已经实现了,有兴趣的读者可以查询相关的知识,比如OpenCV库中就提供了一套方法。

2.2 用前馈神经网络解决问题

我们下面要考验一下神经网络的能力。我们先用前面学过的全连接网络来解决这个问题,搭建一个三层的网络如下:

def dnn_model():num_output = 5max_epoch = 50batch_size = 16learning_rate = 0.1params = HyperParameters_4_2(learning_rate, max_epoch, batch_size,net_type=NetType.MultipleClassifier,init_method=InitialMethod.MSRA,optimizer_name=OptimizerName.SGD)net = NeuralNet_4_2(params, "pic_dnn")f1 = FcLayer_2_0(784, 128, params)net.add_layer(f1, "f1")r1 = ActivationLayer(Relu())net.add_layer(r1, "relu1")f2 = FcLayer_2_0(f1.output_size, 64, params)net.add_layer(f2, "f2")r2 = ActivationLayer(Relu())net.add_layer(r2, "relu2")f3 = FcLayer_2_0(f2.output_size, num_output, params)net.add_layer(f3, "f3")s3 = ClassificationLayer(Softmax())net.add_layer(s3, "s3")return net

样本数据为28x28的灰度图,所以我们要把它展开成1x784的向量,第一层用128个神经元,第二层用64个神经元,输出层5个神经元接Softmax分类函数。

最后可以得到如下训练结果。

图18-22 训练过程中损失函数值和准确度的变化

在测试集上得到的准确度是89.8%,这已经超出笔者的预期了,本来猜测准确度会小于80%。有兴趣的读者可以再精调一下这个前馈神经网络网络,看看是否可以得到更高的准确度。

2.3 用卷积神经网络解决问题

下面我们来看看卷积神经网络能不能完成这个工作。首先搭建网络模型如下:

def cnn_model():num_output = 5max_epoch = 50batch_size = 16learning_rate = 0.1params = HyperParameters_4_2(learning_rate, max_epoch, batch_size,net_type=NetType.MultipleClassifier,init_method=InitialMethod.MSRA,optimizer_name=OptimizerName.SGD)net = NeuralNet_4_2(params, "shape_cnn")c1 = ConvLayer((1,28,28), (8,3,3), (1,1), params)net.add_layer(c1, "c1")r1 = ActivationLayer(Relu())net.add_layer(r1, "relu1")p1 = PoolingLayer(c1.output_shape, (2,2), 2, PoolingTypes.MAX)net.add_layer(p1, "p1") c2 = ConvLayer(p1.output_shape, (16,3,3), (1,0), params)net.add_layer(c2, "c2")r2 = ActivationLayer(Relu())net.add_layer(r2, "relu2")p2 = PoolingLayer(c2.output_shape, (2,2), 2, PoolingTypes.MAX)net.add_layer(p2, "p2") params.learning_rate = 0.1f3 = FcLayer_2_0(p2.output_size, 32, params)net.add_layer(f3, "f3")bn3 = BnLayer(f3.output_size)net.add_layer(bn3, "bn3")r3 = ActivationLayer(Relu())net.add_layer(r3, "relu3")f4 = FcLayer_2_0(f3.output_size, num_output, params)net.add_layer(f4, "f4")s4 = ClassificationLayer(Softmax())net.add_layer(s4, "s4")return net

表18-2展示了模型中各层的作用和参数。

表18-2 模型各层的作用和参数

ID类型参数输入尺寸输出尺寸
1卷积8x3x3, S=1,P=11x28x288x28x28
2激活Relu8x28x288x28x28
3池化2x2, S=2, Max8x28x288x14x14
4卷积16x3x3, S=18x14x1416x12x12
5激活Relu16x12x1216x12x12
6池化2x2, S=2, Max16x6x616x6x6
7全连接3257632
8归一化3232
9激活Relu3232
10全连接5325
11分类Softmax55

经过50个epoch的训练后,我们得到的结果如图18-23。

图18-23 训练过程中损失函数值和准确度的变化

以下是打印输出的最后几行:

......
epoch=49, total_iteration=14099
loss_train=0.002093, accuracy_train=1.000000
loss_valid=0.163053, accuracy_valid=0.944000
time used: 259.32207012176514
testing...
0.935
load parameters
0.96

可以看到我们在测试集上得到了96%的准确度,比前馈神经网络模型要高出很多,这也证明了卷积神经网络在图像识别上的能力。

图18-24是部分测试集中的测试样本的预测结果。

图18-24 测试结果

绝大部分样本预测是正确的,只有最后一个样本,看上去应该是一个很扁的三角形,被预测成了菱形。

2.4 形状分类可视化解释

图18-25 可视化解释

参看图18-25,表18-3解释了8个卷积核的作用。

表18-3 8个卷积核的作用

卷积核序号作用直线三角形菱形矩形圆形
1左侧边缘01011
2大色块区域01111
3左上侧边缘01101
445度短边11101
5右侧边缘、上横边00011
6左上、右上、右下01101
7左边框和右下角00011
8左上和右下,及背景00101

表18-3中,左侧为卷积核的作用,右侧为某个特征对于5种形状的判别力度,0表示该特征无法找到,1表示可以找到该特征。

  1. 比如第一个卷积核,其作用为判断是否有左侧边缘,那么第一行的数据为[0,1,0,1,1],表示对直线和菱形来说,没有左侧边缘特征,而对于三角形、矩形、圆形来说,有左侧边缘特征。这样的话,就可以根据这个特征把5种形状分为两类:

    • A类有左侧边缘特征:三角形、矩形、圆形
    • B类无左侧边缘特征:直线、菱形
  2. 再看第二个卷积核,是判断是否有大色块区域的,只有直线没有该特征,其它4种形状都有。那么看第1个特征的B类种,包括直线、菱形,则第2个特征就可以把直线和菱形分开了。

  3. 然后我们只关注A类形状,看第三个卷积核,判断是否有左上侧边缘,对于三角形、矩形、圆形的取值为[1,0,1],即矩形没有左上侧边缘,这样就可以把矩形从A类中分出来。

  4. 对于三角形和圆形,卷积核5、7、8都可以给出不同的值,这就可以把二者分开了。

当然,神经网络可能不是按照我们分析的顺序来判定形状的,这只是其中的一种解释路径,还可以有很多其它种路径的组合,但最终总能够把5种形状分开来。

代码位置

ch18, Level2

思考和练习

  1. 我们使用了3x3的卷积核,如果用5x5的卷积核,但是在其它参数不变的情况下,其效果会不会更好?
  2. 可以建立一个数据集,只包括正圆、椭圆、正方形、矩形等四种形状,看看卷积神经网络是不是能分辨出来。

这篇关于CNN | 02实现几何图形分类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/784348

相关文章

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、