当前位置: 首页 > news >正文

深度学习与图像处理案例 │ 图像分类(智能垃圾分拣器)


以垃圾分类任务为主线,使用图像分类套件PaddleClas实现高精度垃圾分类,并最终脱离训练环境,通过FastDeploy部署工具,在Jetson Nano智能边缘设备上实现算法集成。

01、任务概述

3.1.1任务背景

2020年11月,住房和城乡建设部等12个部门联合发文,明确了到2025年46个重点城市要基本建立配套完善的生活垃圾分类法律法规制度体系,地级及以上城市建立生活垃圾分类投放、分类收集、分类运输、分类处理系统,这体现了国家对生活垃圾分类工作的高度重视。

面对每天庞大的生活垃圾,传统的人工分类方法耗时耗力、效率较低。为了解决这个问题,垃圾自动分类处理系统应运而生。通常垃圾分类处理系统由垃圾自动分拣机、可燃垃圾低温磁化炉、可腐烂有机垃圾资源化处理设备三部分组成,可以将城市小区、乡镇社区以及农村的生活垃圾进行分类,并在源头就地把分类后的垃圾资源化处理,起到节能减排、绿色环保的作用。如何设计出实用高效的智能垃圾自动分拣算法显得尤为重要。

按照垃圾分类方法,生活垃圾可以分为厨余垃圾、有害垃圾、可回收物和其他垃圾四大类,如图3.1所示。因四类垃圾在外观形态上有明显的不同,又考虑到摄像头成本低、无接触等优势,一般会采用基于图像的垃圾分类方法来构建垃圾分类系统,即通过摄像头捕获垃圾图像并进行自动分类。

■ 图3.1生活垃圾分类

基于图像的垃圾分类方法属于典型的图像分类应用,已有的方法主要分为两大类: 基于传统特征描述的方法和基于深度学习的方法。基于传统特征描述的方法计算成本小,对硬件要求不高,在早期硬件资源受限条件下易于部署和应用。随着技术的发展以及海量数据的挖掘和利用,基于深度学习的垃圾分类方法逐渐成为主流。在图像样本充足的情况下,基于深度学习的方法识别率高、鲁棒性强,而伴随着各种轻量级深度学习模型的提出,在算法速度、硬件依赖、运算精度上深度学习分类方法均取得了显著进步,使得运算资源不再制约其应用。

本案例内容将以垃圾分类任务为主线,使用图像分类套件PaddleClas实现高精度垃圾分类,并最终脱离训练环境,通过FastDeploy部署工具,在Jetson Nano智能边缘设备上实现算法集成。

3.1.2安装PaddleClas套件

PaddleClas是飞桨为工业界和学术界所研发的一个图像分类算法库,助力开发者能够快速训练出视觉分类模型并完成部署应用。PaddleClas功能结构如图3.2所示,其中功能图底部是一系列前沿的图像分类算法,每种算法在模型大小、推理速度上均有不同的性能表现,一般根据业务场景选择相应的算法模型。在算法层之上,面向工业界还提供了一些产业级特色方案,这些方案所采用的模型或算法精度高、稳定性好、易部署。针对算法的训练和推理部署,PaddleClas提供了完备、统一的实现接口,参照官网教程可以快速完成整个算法研发任务。在最顶端的应用场景方面,PaddleClas提供了诸多真实有效的场景应用案例,如商品识别、车辆属性分析、电动车进电梯识别等,感兴趣的读者可以针对性地借鉴和学习这些案例,并应用到实际的项目中。

■ 图3.2图像分类套件PaddleClas功能结构图

 

下面开始介绍如何安装PaddleClas套件。在安装PaddleClas套件前,请先确保已正确安装PaddlePaddle。

首先下载PaddleClas套件,可以使用GitHub源进行下载,如因网络原因无法下载,也可以尝试从国内Gitee源进行下载。

下载完成后通过cd命令切换到PaddleClas根目录,然后安装相关的依赖库: 

 最后安装paddleclas: 

这样就完成了PaddleClas的安装。

02、算法原理

图像分类是计算机视觉的重要领域,它的目标是将图像分类到预定义的标签。近些年研究者提出很多不同种类的神经网络模型,极大地提升了图像分类算法的性能。下面着重介绍三个重要的图像分类网络模型及其基本原理。

3.2.1VGG算法

Alex的成功指明了深度卷积神经网络可以取得出色的识别结果,但并没有提供相应的方案来指导后续的研究者如何设计新的网络来进一步提升性能。VGG算法的提出证明了通过相同卷积模块的堆叠可以有效提升分类性能,这一理念也被延续至今。

VGG是牛津大学的视觉几何小组(Visual Geometry Group)在2014年提出的一种神经网络模型,该模型证明了使用重复的卷积模块并且适当增加模型深度能够有效提高图像分类性能。VGG有多种不同变体,如VGG11、VGG13、VGG16和VGG19,这些变体本质上没有太大的区别,只是所使用的神经网络层数量不一样。

图3.3展示了VGG16对应的模型结构,该模型输入是224×224×3的RGB图像,然后经过一系列的卷积层convolution、非线性激活层ReLU和最大池化层max pooling来提取高层语义特征,接下来对提取到的卷积特征使用3个全连接层fully connected和非线性激活层ReLU进行降维处理,映射到分类类别所对应的数量,最后使用softmax分类器完成分类。图3.3所示的下方列出了每层卷积的核参数和通道参数。

■ 图3.3VGG模型结构图

这里需要说明的是,VGG所有的卷积层都采用3×3的卷积核(kernel_size),步长为1(stride)、边缘填充为1(padding),因此,按照参考书2.5.1节中介绍的卷积计算公式,使用该类型卷积层不会改变输入特征尺寸。每个卷积模块后面的最大池化层采用的核大小为2、步长为2、边缘填充为0,因此,使用该最大池化层计算后对应的特征图尺寸会变为原来的一半。

VGG的完整代码请参考PaddleClas/ppcls/arch/backbone/legendary_models/vgg.py,感兴趣的读者可以深入剖析该源码,提升对VGG模型的理解。

3.2.2ResNet算法

前面介绍的VGG模型证明了增加卷积层数可以提升模型性能。这里自然引申出来一个问题: 神经网络堆叠得越深,学习的效果就一定会越好吗?答案无疑是否定的。研究学者发现当模型层数增加到某种程度,模型的效果将会不升反降。为此,研究学者给出了两种可能的解释: 过拟合或梯度消失。但是进一步的研究表明,无论是过拟合还是梯度消失,都不能完美地解释这个现象。

目前,对于上述问题的一种直观解释就是神经网络的非线性表达能力让神经网络模型太发散,一旦走得太远太深,它就“忘记”了初心,使得特征随着层层前向传播越来越发散。这个解释有一定的哲学意味,应该说深度学习目前还存在很多理论上的不足,有些情形只能通过实验和直觉分析来定位,而在理论分析方面深度学习还有很多需要探索的地方。那么到底怎么解决深度学习模型随着网络层数加深而产生的性能下降问题呢?解决方法就是残差学习,这也是ResNet算法最核心的思想。

在ILSVRC2015图像分类任务竞赛中,由何恺明等提出的深度残差模型ResNet首次超越人类水平,斩获竞赛第一名,同时基于ResNet所发表的论文也获得2016年CVPR最佳论文奖。这篇论文提出了一种大道至简的残差模块,成功解决了前面所述的深度学习模型退化问题。

残差模块结构如图3.4所示。

■ 图3.4残差模块结构图

 从图3.4看到,残差网络让输入x经过两个神经网络层产生输出F(x),然后从输入直接引入一个短连接线到输出上。这样一种网络结构可以用下面的公式表示: 

前面提到过,深度学习模型的非线性特性使得神经网络如果堆叠得太深会容易“忘记”初始的输入特征,因此残差模型在输出的地方额外地加入输入特征,构建这样一个恒等映射(identity),从而让模型在探索求解空间时产生一个强约束,这个约束保证模型参数不会朝着一个过分发散的方向前进。这样的构建方式完全是一种直觉上的改进,为了验证它的有效性,何恺明等通过大量实验进行了证明。

有了上述残差模块,就可以进行堆叠,从而得到不同深度的深度残差模型ResNet。常见的ResNet模型有ResNet18、ResNet34、ResNet50、ResNet101、ResNet152和ResNet200等。大量的实验证明,残差模块堆叠得越深性能表现越强。目前,ResNet已作为最常见的深度学习模型被广泛应用。图3.5展示了ResNet18的模型结构,其中k表示卷积核大小,s表示步长,p表示边界扩充大小。

■ 图3.5ResNet18模型结构图

ResNet的完整实现代码请参考PaddleClas/ppcls/arch/backbone/legendary_models/resnet.py。感兴趣的读者可以深入剖析该源码,提升对ResNet模型的理解。

3.2.3MobileNet算法

目前的深度学习算法已经可以在GPU服务器上实时运行,但是如果将训练好的模型直接移植到手机或嵌入式终端,模型的推理速度和内存消耗就是非常致命的问题。因此,只有对深度学习模型进行优化才有可能在这类资源有限的设备中使用。

模型优化主要有三种方法: 设计轻量级的网络、压缩剪枝和量化加速。本章重点关注如何设计轻量级神经网络模型。

在轻量级网络设计中,MobileNet系列算法最为经典。从MobileNet的名字也可以看出,该系列算法旨在为移动设备进行AI赋能,其系列模型包括MobileNetV1、MobileNetV2和MobileNetV3。通过使用MobileNet模型,可以大幅减少计算参数,降低模型推理时的内存消耗,这在实际工业场景研发过程中尤为重要。如果从产品部署角度考虑,目前深度学习的热潮已经逐步从服务器端转向小型终端,即所谓的边缘计算设备。众多企业纷纷在此发力,力求能够推出带AI功能的终端硬件产品,实现离线运行,保护客户的数据安全,其中以英伟达推出的Jetson系列开发板最为成功。Jetson系列开发板不仅体积小巧,而且自带GPU,因此一经推出便受到广泛关注。尽管有GPU加持,但是在这种资源有限的开发板上运行重量级的深度学习模型依然是一个难题,在速度上面也依然难以满足实时性要求。因此,对原模型进行优化使得能够利用低廉的终端设备实现AI应用已经成为AI工程师必须掌握的技能。本章工程实践部分将采用MobileNet算法在Jetson开发板上进行高性能深度学习推理。

下面首先讲解MobileNetV1和MobileNetV2的模型结构,了解MobileNet系列模型到底“轻”在何处。

1. MobileNetV1

传统的卷积神经网络在移动设备上运行速度慢且会消耗大量运算资源。因此,MobileNetV1最大的贡献就是改进传统卷积神经网络的结构,降低卷积操作的计算量。

具体的,MobileNetV1提出了深度可分离卷积(Depthwise Separable Convolution,DSC),以此来代替传统的二维卷积。假设输入图像是3通道图像,长、宽均为256像素,采用5×5卷积核进行卷积操作,输出通道数为16(即16组卷积),步长为1,边缘填充为0,那么进行二维卷积后输出特征形状为252×252×16,如图3.6所示。

■ 图3.6传统CNN卷积操作

图3.6中的CNN卷积使用16个不同的5×5×3的卷积核以滑窗的形式遍历输入图像,因此需要学习的参数个数为5×5×3×16,实际对应的计算量为5×5×3×16×256×256。可以看到,传统卷积计算量还是非常大的。MobileNetV1的提出就是为了解决这个问题。

在MobileNetV1中,采用深度可分离卷积来代替传统的CNN。深度可分离卷积可以分为两部分: 深度卷积(Depthwise Convolution,DW)和逐点卷积(Pointwise Convolution,PW),如图3.7所示。

■ 图3.7深度可分离卷积

深度卷积在处理特征图时对于特征图的每个通道有一个独立的卷积核,并且这个卷积核仅作用在这个通道上。例如,对于图3.6所示的3通道输入图像,如果采用深度卷积进行操作,那么就变成了使用3个卷积滤波器,每个卷积滤波器单独地作用于图像的某个通道上,每个卷积滤波器得到一个通道特征,最后合并产生3通道输出特征。从这个过程可以看出,使用深度卷积不会改变原始特征的通道数。图3.8展示了对于3通道图像的深度卷积操作步骤。

■ 图3.8深度卷积操作示意图

从计算量上来分析,因为只采用了3个5×5大小的卷积滤波器,因此对应的参数量为5×5×3,计算量为5×5×3×256×256。很明显,计算量降低了很多。那么这种深度卷积如何使用PaddlePaddle实现呢?

答案是非常简单的,只需要修改paddle.nn.Conv2D()函数中的groups参数即可(paddle.nn.Conv2D的详细定义请参考2.5.1节),这里groups的意思就是将输入通道数分成多少组进行卷积运算。当groups等于1时(默认值),等价于传统CNN; 当groups等于输入通道数时,此时就对应深度卷积计算。因此,如果要将传统CNN改为深度卷积,只需要设置这个groups参数为输入通道数即可。

采用深度卷积实现了每个通道的特征计算,但是这些计算是在单一的特征通道上完成的,此时各个通道之间的信息是独立的,那么如何对各通道特征进行融合并改变最终的输出通道数呢?这里就需要通过逐点卷积来完成。逐点卷积使用卷积核为1×1的常规CNN来实现。使用逐点卷积并不会改变输入特征长宽尺寸,仅改变输入特征通道数。从本质上来说,逐点卷积的作用就是对特征通道进行升维和降维,如图3.9所示。

■ 图3.9逐点卷积操作示意图

 

对应图3.9,逐点卷积的参数量为1×1×3×16,计算量为1×1×3×252×252×16。

综合对比下,对于采用深度可分离卷积总的参数量为5×5×3+1×1×3×16,相比于普通卷积的5×5×3×16,占(1/16+1/25)。从计算量上来看,采用深度可分离卷积总的计算量为5×5×3×256×256+1×1×3×252×252×16,相比于普通卷积的5×5×3×16×256×256,同样占(1/16+1/25)左右。如果采用的不是5×5卷积,而是常用的3×3卷积,那么使用深度可分离卷积只需要普通卷积1/9左右的计算量。

MobileNetV1正是基于深度可分离卷积,实现了模型参数和计算量的减少。值得称赞的是,尽管参数量显著降低了,但是通过大量实验证明,MobileNetV1算法在精度上并不会下降很多,这也是为何MobileNetV1获得研究学者如此青睐的原因。

完整的MobileNetV1结构如图3.10所示。

■ 图3.10MobileNetV1模型结构图

MobileNetV1算法通过堆叠深度可分离卷积完成构建,完整代码请参考PaddleClas套件中的实现方案: PaddleClas/ppcls/arch/backbone/legendary_models/mobilenet_v1.py。

2. MobileNetV2

MobileNetV2是由Google团队在2018年提出的,相比于MobileNetV1而言准确率更高,模型更小。

MobileNetV2主要创新点就是在MobileNetV1中加入了残差模块,同时提出了一种新的激活函数ReLU6。在MobileNetV2论文中指出,当输出特征通道数较少的时候,使用ReLU对其进行操作会导致信息严重损耗。为此,MobileNetV2提出了ReLU6激活函数,其数学表达形式如下:

图片

从上述公式可以看到,输入值x如果为0~6,那么输出值不变,还是x;  当x超过6时输出值将被截断,恒等于6;  如果x小于0,则输出恒等于0。

ReLU6对应的函数曲线如图3.11所示。 

■ 图3.11ReLU6函数曲线

MobileNetV2通过实验验证了ReLU6激活函数的有效性。实际在使用PaddlePaddle编程时,可以直接使用已有的接口实现,如下所示: 

 输出结果如下: 

为了进一步提高分类性能,MobileNetV2使用了前面介绍的残差模块,但是在设计整个模型结构时与ResNet算法有明显不同,MobileNetV2设计了一种反向残差结构模型(Inverted Residuals)。ResNet中的残差模块和MobileNetV2中的反向残差模型如图3.12所示。

■ 图3.12ResNet中的残差模块和MobileNetV2中的反向残差模型

 

在ResNet提出的残差模块结构中,先使用1×1卷积实现降维,然后通过3×3卷积实现特征融合,最后通过1×1卷积实现升维,即两头大中间小。而MobileNetV2提出的反向残差模块,将降维和升维的顺序进行了调换,并且将3×3卷积替换成了3×3 深度可分离卷积,即两头小中间大。这样的修改主要是考虑到深度卷积(DW)如果在低维度上工作,特征融合效果不会很好,所以MobileNetV2首先会扩张通道。通过前面可以知道逐点卷积(PW)所使用的1×1卷积可以用来升维和降维,那就可以在深度卷积(DW)之前先使用逐点卷积(PW)进行升维(升维倍数为t,论文中t=6),然后再在一个更高维的空间中进行深度卷积(DW)操作来融合特征,最后再采用逐点卷积(PW)将通道数下降并还原回来。

MobileNetV2中设计了两种反向模块,如图3.13所示。

■ 图3.13MobileNetV2反向模块(bottleneck)结构图

 MobileNetV2完整结构如图3.14所示。

■ 图3.14MobileNetV2完整结构图

图3.14中,t表示扩展因子(维度扩增倍数); c表示输出特征通道数; n表示bottleneck的模块重复次数; s表示步长,bottleneck表示反向模块。

完整的MobileNetV2代码请参考PaddleClas套件中的实现方案,代码位于PaddleClas/ppcls/arch/backbone/model_zoo/mobilenet_v2.py。感兴趣的读者可以深入剖析该源码,提升对MobileNetV2模型的理解。

至此,已介绍完VGG、ResNet、MobileNet等常见的深度学习图像分类算法。VGG通过适当堆叠卷积模块来提高分类精度; ResNet通过恒等映射连接来解决网络层数过度加深后出现的性能退化问题; MobileNet则在传统CNN卷积结构基础上提出了深度可分离卷积来减少计算量。深度学习分类算法近些年一直在快速更新中,读者只有掌握这些经典的图像分类算法原理,了解其背后所面临的核心问题,才能洞察本质,提高实践能力。

下面将以图像分类算法套件PaddleClas为主,研发一款智能垃圾分类器应用,同时结合英伟达推出的Jetson Nano智能开发板,打造一款实战级的图像分类产品。为了能够在性能有限的Jetson Nano开发板上运行深度学习算法,将使用轻量级MobileNetV2算法来完成这个任务。

http://www.dtcms.com/a/306898.html

相关文章:

  • 360环视技术推荐的硬件平台:支持多摄像头与三屏异显的理想选择
  • LeetCode 刷题【22. 括号生成】
  • 敏捷与SCRUM三大支柱:数字化时代的韧性引擎
  • 【解决方案】frida-ps -Ua报错unable to perform ptrace pokedata: I/O error
  • [Python] -进阶理解10- 用 Python 实现简易爬虫框架
  • 外键列索引优化:加速JOIN查询的关键
  • 嵌入式摄像头深度解析
  • Ubuntu虚拟机介绍、命令、安装软件指令(一)
  • CNN实战项目
  • ica1靶场攻略
  • 二叉树算法之【二叉树的层序遍历】
  • python | numpy小记(八):理解 NumPy 中的 `np.meshgrid`
  • C++ Qt网络编程实战:跨平台TCP调试工具开发
  • 基于SpringBoot+MyBatis+MySQL+VUE实现的便利店信息管理系统(附源码+数据库+毕业论文+远程部署)
  • 虚幻基础:模型碰撞体
  • [Qt]QString 与Sqlite3 字符串互动[汉字不乱码]
  • C#垃圾回收机制:原理与实践
  • PyTorch 生态四件套:从图片、视频到文本、语音的“开箱即用”实践笔记
  • 电子电气架构 --- 汽车电子电气EEA架构开发流程
  • 通义万相文生图模型wan2.2-t2i-flash和wan2.2-t2i-plus全维度深度对比
  • Java试题-选择题(1)
  • 【C++】适配器模式手搓STL的stack和queue
  • LeetCode Hot 100:15. 三数之和
  • Nuxt3 全栈作品【通用信息管理系统】角色管理(含配置权限 -- 菜单权限 vs 操作权限)
  • 差分数组前缀和优化,降低时间复杂度
  • vue+elementui+vueCropper裁剪上传图片背景颜色为黑色解决方案
  • ‌我的第一个开源项目:跃动的心
  • 物流分拣漏检率↓78%!陌讯动态光流算法在包裹移动识别的技术突破
  • GCC链接技术深度解析:性能与空间优化
  • [mcp: McpSchema]-源码分析