时间:2024-05-04
刘晓,齐德昱,曹世轩
(1.华南理工大学计算机科学与工程学院,广州510006;2.广东实验中学,广州510375)
当前图像分类技术的迅猛发展,主要归功于深度学习模型训练的可行性。深度学习的训练方法发明于20 世纪70 年代[1],但因其模型层数及训练次数过高,而当时计算机的硬件水平无法满足训练要求,因此未被重视。如今,计算机的性能有了极大提升,借助深度学习框架搭建和训练神经网络模型,可以在短时间内得到更精确的结果。
目前深度学习框架蓬勃发展,国内有百度的PaddlePaddle 框架,国外有谷歌的TensorFlow 框架[2]、Facebook 的PyTorch、Amazon 的MXNet 以及Microsoft 的CNTK。其中,TensorFlow 框架以其高度的灵活性和可移植性,迅速成为最受欢迎深度学习框架。另外,基于深度学习的图像分类算法不断取得进展。因此,基于TensorFlow 构建深度学习模型,实现图像分类具备可行性,也是未来的发展趋势。
当今图像分类算法成为人工智能与计算机视觉领域的热点之一,图像分类的关键任务是特征提取,特征值的好坏直接影响了模型的分类效果。传统的图像分类方法依赖于人工设计特征,例如,1996 年Ojala T 等人提出并于2002 年拓展的局部二值模式(LBP)[3-4],用于图像纹理特征提取;1999 年David Lowe 提出并于2004 年完善的尺度不变转换特征(SIFT)[5],用于数字图像的特征描述;2005 年Dala 提出的方向梯度直方图(HOG)[6],用于行人检测及目标跟踪;2006 年Lazebnik等人提出的空间字塔模型(SPM)[7],将空间几何信息加入图像分类等。它们虽然在特定的领域取得了显著的成果,但是人工设计特征耗时费力,且难以提取图像的深层特征,存在一定的局限性。2006 年Hinton 等人[8]提出深度学习的概念,与传统的图像分类方法不同,深度学习能够自主地学习图像特征,并提取出更高维的图像特征,具有很强的泛化能力和表达能力,在提高了分类准确率的同时,大大减少了人力,使图像分类研究取得了突破性进展。
随着深度学习技术的快速发展,针对深度学习的各种算法不断完善,并在各个领域得到广泛应用,例如,Taigman 等人[9]提出的DeepFace 和汤晓鸥团队提出的DeepID,用于人脸识别;Sun 等人[10]提了一种融合卷积神经网络和支持向量机两种高级分类器协同进行功能磁共振成像识别的混合模型,用于医学领域;Zhou 等人[11]提出一种基于卷积神经网络的Landsat-8 多光谱遥感图像花生种植面积提取方法,用于遥感图像分类;Chang 等人[12]提出一种基于深度卷积神经网络的交通标志检测算法,用于交通领域等。尤其是基于卷积神经网络(CNN)的深度学习模型,对于高维复杂数据的有效特征提取具有显著优势。自2012 年Krizhevsky等人[13]提出基于卷积神经网络的AlexNet 模型,成功将ImageNet 数据集的Top-5 错误率降至15%,随后ZFNet、GoogLeNet、VGG、ResNet、DenseNet 相继提出,到2017 年SENet 成功将Top-5 错误率降至2.25%,完成了大规模计算机视觉挑战赛(ILSVRC)[14]的使命。此外,一些改进的卷积神经网络也取得了不俗的成绩。例如,用于目标识别的R-CNN[15]、Fast R-CNN[16]、Faster R-CNN[17];基于空间金字塔池化的卷积神经网络SPPNet[18];以及能够移植到移动端的MobileNet[19]、ShuffleNet[20]等。
随着深度学习的研究热潮持续高涨,开源深度学习框架不断涌现、合并或者没落,如TensorFlow、Py-Torch、MXNet、Deeplearning4j、PaddlePaddle、CNTK、Caffe、Theano 等,其中,PyTorch 是Caffe2 和Torch 合并得到,而CNTK、Theano 已经停止更新。这些框架极大简化了深度学习模型的实现,快速推动了深度学习在学术界的研究效率和工业界的落地应用。表1 总结了目前主流框架的主要信息。
表1 主流深度学习框架信息对比
表2 对比了主流深度学习框架在GitHub 上的活跃度,可以看出,TensorFlow 关注度占据绝对优势。
表2 主流深度学习框架活跃度对比
为应对使用大规模深度学习的技术难题,谷歌2011 年推出第一代分布式机器学习框架DistBelief[21],并基于DistBelief 建立了Ineption 模型[22]取得2014 年ImageNet 竞赛冠军。但由于DistBelief 使用了许多谷歌内部系统模型架构,涉及商业机密信息,使得该框架难以对外开源,仅在谷歌内部使用。为更好地推动机器学习和深度学习在学术界和工业界的发展应用,谷歌于2015 年11 月在GitHub 上发布了第二代深度学习框架TensorFlow,2016 年4 月又开放了带有分布式学习功能的增强版TensorFlow。截至目前,TensorFlow最新版本为2.0。
TensorFlow 是基于数据流图的数值计算软件库,为实现机器学习或深度学习算法提供接口和计算框架。它兼具灵活性和规模性,前端支持C++、Python、Java 等多种编程语言,后端使用C++、CUDA 等保证底层高效性和稳定性,可以将计算结果映射到不同的硬件或操作系统,例如Windows、Linux、Android、iOS、服务器,甚至是大规模GPU 集群,大大降低了开发难度,同时提供了大规模分布式训练方式,并允许用户使用不同设备更新模型参数,节省了开发成本,使用户可以快速实现模型设计并在海量数据集上训练模型。近年来,TensorFlow 被广泛应用到机器学习、深度学习以及其他计算领域,例如语音识别、自然语言处理、计算机视觉、机器人控制、信息提取等。
TensorFlow 由Tensor 和Flow 组成,Tensor 意为张量[23],是指某个计算图在边中流动的数据,可理解为多维数组;Flow 意为流,表示张量之间通过计算互相转化的过程。TensorFlow 用数据流的流向图表示计算流程,通过一个有向图或者计算图来表述计算,计算图的每一个节点代表了一个运算操作,节点之间的边代表了计算之间的依赖关系,若一个计算的输入依赖于其他计算的输出,那么这两个计算之间存在依赖关系。所有TensorFlow 的程序都可以使用计算图的形式表示,用户通过使用Python、C++、Java 等编程语言对计算图的分支进行条件控制或循环操作来定义数据的计算,样例代码如下:
TensorFlow 会自动将定义的计算转化为计算图上的节点,并自动维护一个默认的计算图,通过tf.get_default_graph 函数获取默认的计算图,此外,TensorFlow还支持通过tf.Graph 生成新的计算图。计算图不仅能描述数据的计算过程,还能维护或更新计算状态。
TensorFlow 的基本数据结构为张量,其中,零阶张量为标量即一个数,一阶张量为向量即一维数组,n 阶张量即n 维数组。张量是对TensorFlow 中运算结果的引用,例如,上例代码的运行结果为:
可以看出,张量保存的是数字的计算过程,包括name、shape、dtype 属性。
TensorFlow 基本的数据类型包括数值型、字符串型和布尔型,常用的精度类型包括tf.int16、tf.int32、tf.int64、tf.float16、tf.float32、tf.float64,张量的类型和精度的转换使用tf.cast 函数。TensorFlow 支持以下三种类型的张量:常量、变量、占位符。其中,常量是值不能改变的张量。声明一个常量使用tf.constant()函数;填充张量,使用tf.fill()函数;此外,TensorFlow 还提供生成等差序列、正态分布和张量的随机排列、随机剪裁等。变量是TensorFlow 的一个类,用来存储和更新机器学习模型中的参数,在神经网络中通常表示权重和偏置,使用前需要初始化,模型训练后必须存储在磁盘,未来模型训练和分析可直接加载它。创建变量,使用tf.Variable 函数;初始化变量,使用tf.Variable.initializer或assign()函数,此外,assign()函数还可更新变量;保存变量,使用Saver 类。占位符用于将数据输入TensorFlow 图,当要传入的数据不确定时,使用占位符声明一个没有传入具体值的数据格式,可使数据的使用更灵活。在训练神经网络时,通常用于提供新的训练样本,在会话中运行计算图时,可为占位符赋值。占位符不包含任何数据,因此不需要初始化。创建占位符,使用tf.placeholder()函数。
TensorBoard 是TensorFlow 内置的可视化工具,提供计算图的图像和网络执行的量化指标,通过可视化TensorFlow 输出的日志信息,使理解、调试和优化TensorFlow 程序更容易。图1 显示了利用TensorBoard 可视化训练指标的示例。
图1 TensorBoard可视化训练指标
2019 年10 月谷歌发布了TensorFlow2.0 正式版,其最大改变之一是Keras 得到官方内置和全面支持。Keras 是一个高级神经网络API,具有高度模块化、极简和可扩充的特性,并提供清晰、可操作的错误消息,支持CNN 和RNN,通过调用tf.keras 的Sequential、compile 和fit 方法来构建、编译和训练模型。
另一个最大改变是将图与会话机制(Graph Execution)改为动态图机制(Eager Execution)。Eager Execution 是一个由运行定义的命令式接口,允许用户在不构建图的情况下,立即执行操作,可直接使用numpy 作为输入操作,操作会返回具体的值。tf.contrib.eager 模块包含用于Eager Execution 和Graph Execution 环境的符号。
本文的实验环境为Windows 10 操作系统、Intel Core i7-8565U 处理器、8G 内存、集成显卡的普通PC,使用TensorFlow2.0 的Keras 高级API 构建一个卷积神经网络模型,来解析TensorFlow2.0 图像分类的实现过程。
本实验采用经典的CIFAR-10 数据集,它包含10类60000 个32×32 彩色图像,其中,训练集为50000 个样本,测试集为10000 个样本。图2 显示了每个类别的一些示例。
图2 CIFAR-10数据集示例
从TensorFlow2.0 中下载获取CIFAR-10 数据集,并传入训练集和测试集的数据和对应标签。
(train_image,train_label),(test_image,test_label)=keras.datasets.cifar10.load_data()
图像大小是32×32×3,像素值介于0 到255 之间。标签是从0 到9 的整数数组。图像标签与实际类别的对应关系,如表3 所示。
表3 图像标签与实际类别对应关系
将训练集和测试集的图片像素值归一化处理。
TensorFlow2.0 提供了完整的模型构建参数,包括基本的构建模块,如卷积层、池化层、全连接层、递归神经网络模块和非线性激活函数等来完成神经网络模型从输入到输出的计算;各种损失函数,如交叉熵、均方误差等来构建神经网络模型的前向传递;自微分(autodiff)函数和模型优化器,如adam、adagradumizer 等来自动构建神经网络的向后传递操作。
本文使用TensorFlow2.0 的Keras API 构建神经网络模型,通过调用tf.keras.Sequential 设计了一个卷积神经网络模型,其中,卷积层步长stride 设为1 不会跳过任何一个像素值,padding 为same 使卷积的输入和输出保持相同尺寸,使用ReLU 激活函数进行非线性化。
池化层使用最大池化来保留最显著的特征,步长stride 设为2 来缩小图片尺寸。
卷积层和池化层反复使用,需分别定义。全连接层前使用flatten 将输入数据展平,全连接层使用ReLU激活函数进行非线性化。
全连接层后使用Dropout 层,比例设为0.5,即随机使50%的节点数据失活来减轻模型过拟合。输出层使用Softmax 分类器来计算概率。模型的网络结构图如图3 所示。
图3 模型的网络结构
模型的具体参数如表4 所示。
调用model.compile()设置模型参数,本文使用adam 作为优化器,sparse_categorical_crossentropy 作为损失函数,accuracy 作为指标。
表4 模型的参数设计
调用model.fit()将训练数据输入模型;使用evaluate 评估准确率。
调用model.predict()对测试图像进行预测。
图4 所示为模型在训练集上的准确率及损失率变化曲线。可以看出,随着训练次数的增加,模型准确率逐渐升高,损失率逐渐降低,准确率在训练346 次时达到最高为98.78%,损失率在训练346 次时达到最低为0.08193,训练次数达350 次后,准确率和损失率趋于平缓。
图4 模型在训练集上的准确率及损失率变化曲线
图5 所示为模型在测试集上的准确率及损失率变化曲线。可以看出,随着训练次数的增加,模型准确率逐渐升高,损失率先降低后升高,训练次数达25 次时,准确率达到最高为76.12%,损失率达到最低为0.731,训练超过25 次后,准确率趋于平缓,损失率呈上升趋势。这是由于模型训练过程出现了过拟合问题,从而影响了模型的识别精度。
图5 模型在训练集上的准确率及损失率变化曲线
本文基于TensorFlow2.0 来研究图像分类算法,通过使用Keras API 构建卷积神经网络模型实现了CIFAR-10 的图像分类识别,具有实际意义,但是该模型在训练过程产生了过拟合问题,下一步计划引入L1、L2 正则化和批归一化[24]等方法对模型进行优化改进,此外,针对复杂背景下图像分类的精度低、噪点数据的难以处理和深层卷积神经网络模型的运行效率低等问题,有待继续深入研究。
TensorFlow2.0 是一种灵活的、可扩展的深度学习库,提供Python、C++、Java 等多种语言接口,用户能自定义构建深度学习模型,同时,可使用TensorBoard 可视化模型和有关网络执行的量化指标。由于Keras 的高度封装,TensorFlow2.0 使用户能快速构建并在海量数据集上训练模型,此外,TensorFlow2.0 还提供将模块部署到生产环境中,但也造成了模型细节不透明、难以进行创新性更改等问题,值得进一步深入研究。
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!