深度学习之PyTorch物体检测实战(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-24 21:13:30

点击下载

作者:董洪义

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

深度学习之PyTorch物体检测实战

深度学习之PyTorch物体检测实战试读:

前言

随着深度学习的飞速发展,计算机视觉技术取得了令人瞩目的成果,尤其是物体检测这一基础又核心的分支,诞生了众多经典算法,在自动驾驶、智能医疗、智能安防及搜索娱乐等多个领域都得到了广泛应用。与此同时,诞生于2017年的PyTorch框架,凭借其简洁优雅、灵活易上手等优点,给开发人员留下了深刻的印象。

目前,国内图书市场上已经出版了几本PyTorch方面的图书,但大多数图书停留在浅层的概念与简单示例的讲解上,缺乏实用性,而且也没有一本系统讲解PyTorch物体检测方面的图书。因此,图书市场上迫切需要一本系统介绍PyTorch物体检测技术的书籍。这便是笔者写作本书的初衷。

本书是国内原创图书市场上首部系统介绍物体检测技术的图书。书中利用PyTorch深度学习框架,从代码层面讲解了Faster RCNN、SSD及YOLO这三大经典框架的相关知识,并进一步介绍了物体检测的细节与难点问题,让读者可以全面、深入、透彻地理解物体检测的种种细节,并能真正提升实战能力,从而将这些技术灵活地应用到实际开发中,享受深度学习带来的快乐。本书特色

1.系统介绍了PyTorch物体检测技术

本书深入物体检测这一基础又核心的技术,从其诞生背景、主流算法、难点问题、发展趋势等多个角度详细介绍了物体检测知识,并结合代码给出了多个算法的实现。

2.从代码角度详细介绍了物体检测的三大算法

本书介绍了Faster RCNN、SSD及YOLO这三个影响深远的检测算法,从代码层面详细介绍了它们所实现的每一个细节与难点,并进行了优缺点分析,而且给出了多种优化算法。

3.涵盖所有主流的物体检测算法

本书几乎涵盖所有主流的物体检测算法,包括VGGNet、ResNet、FPN、DenseNet和DetNet等卷积基础网络,以及从Faster RCNN、HyperNet、Mask RCNN、SSD、RefineDet、YOLO v1到YOLO v3、RetinaNet、CornerNet和CenterNet等物体检测算法,呈现给读者一个完整的知识体系。

4.给出了多个实际的物体检测实例,有很强的实用性

本书对PyTorch的知识体系进行了较为精炼的介绍,还结合物体检测算法重点介绍了PyTorch实现的多个物体检测实例。因此本书不仅是一本很好的PyTorch框架学习书籍,更是一本PyTorch物体检测实战宝典。

5.对物体检测技术常见的细节、难点及发展做了详细分析

本书不仅对物体检测技术的热门话题做了详细分析,例如非极大值抑制、样本不均衡、模型过拟合、多尺度检测、物体拥挤与遮挡等,而且对各种细节与常见问题做了详细分析,并给出了多种解决方法。本书内容

第1篇 物体检测基础知识

本篇涵盖第1~3章,介绍了物体检测技术与PyTorch框架的背景知识与必备的基础知识。主要内容包括物体检测技术的背景与发展;物体检测的多种有效工具;PyTorch背景知识与基础知识;多种基础卷积神经网络的相关知识与具体实现等。掌握本篇内容,可以为读者进一步学习物体检测技术奠定基础。

第2篇 物体检测经典框架

本篇涵盖第4~6章,介绍了Faster RCNN、SSD与YOLO三大经典算法的思想与实现。主要内容包括Faster RCNN两阶算法的思想;锚框Anchor的意义与实现;Faster RCNN的多种改进算法;SSD单阶算法的思想与实现;SSD的数据增强方法及多种改进算法;YOLO单阶算法的三个版本演变过程及具体实现等。掌握本篇内容,可以让读者从代码角度学习物体检测的种种细节。

第3篇 物体检测的难点与发展

本篇涵盖第7~10章,介绍了物体检测技术的细节、难点及未来发展。主要内容包括针对模型加速的多种轻量化网络思想与实现;非极大值抑制;样本不均衡及模型过拟合等物体检测细节问题的背景知识与解决方法;多尺度、拥挤与遮挡等物体检测难点问题的背景知识与解决方法;多种摆脱锚框的检测算法;物体检测的未来发展趋势等。掌握本篇内容,可以让读者更加深入地学习物体检测的相关技术。本书读者对象

·需要全面学习物体检测技术的人员;

·PyTorch框架爱好者和研究者;

·计算机视觉从业人员与研究者;

·深度学习从业人员与爱好者;

·自动驾驶、智能安防等领域的开发人员;

·人工智能相关产业的从业人员;

·计算机、机器人等专业的高校学生。阅读建议

·没有物体检测与PyTorch基础的读者,建议从第1章顺次阅读并演练每一个实例。

·有一定PyTorch与物体检测基础的读者,可以根据实际情况有重点地选择阅读各个算法的细节。

·对于每一个检测算法,建议读者先阅读一下原论文,多思考算法设计的动机与目的,并重点思考如何用代码实现,这会加深读者对检测算法的理解。原论文的下载地址和本书源代码文件一起提供。

·多思考各种物体检测算法的优缺点、相互之间的联系与区别,以及可以优化和改进的细节等,形成完整的知识体系树,这样会进一步加深读者对知识的理解。配书资源获取方式

本书涉及的全部源代码都放在了GitHub上,需要读者自行下载。下载地址如下:

https://github.com/dongdonghy/Detection-PyTorch-Notebook

有些章节的代码较多,但在书中仅给出了重要的片段代码,完整代码以GitHub上的代码为准。

另外,读者也可以登录华章公司的网站www.hzbook.com,搜索到本书,然后单击“资料下载”按钮,即可在本书页面上找到相关的下载链接。致谢

本书的编写得到了许多人的帮助。可以说,本书是多人共同努力的结晶。感谢北京源智天下科技有限公司的王蕾,她在稿件整理方面帮我做了大量的工作!感谢王田苗教授、陶吉博士、夏添博士、侯涛刚博士、严德培、单增光、王策、鄂俊光、李成、丁宁、付航、高鹏、朱本金、彭强、王粟瑶、张腾、王兆玮、黄彬效和拓万琛等人,他们对本书提出了许多宝贵的意见和建议!感谢我的女朋友及家人,他们一直以来都对我鼓励有加,给我写作本书以最大的动力!感谢为本书付出辛勤工作的每一位编辑,他们认真、细致的工作让本书质量提高不少!

由于本书涉及的知识点较多,难免有错漏与不当之处,敬请各位读者指正。如有疑问,请随时通过电子邮件与笔者联系,笔者将不胜感激。联系邮箱:hzbook2017@163.com。董洪义第1篇 物体检测基础知识

·第1章 浅谈物体检测与PyTorch

·第2章 PyTorch基础

·第3章 网络骨架:Backbone第1章 浅谈物体检测与PyTorch

在2012年的ImageNet图像识别竞赛中,Hinton率领的团队利用卷积神经网络构建的AlexNet一举夺得了冠军,从此点燃了学术界、工业界等对于深度学习、卷积网络的热情。短短六七年的时间,在图像分类、物体检测、图像分割、人体姿态估计等一系列计算机视觉领域,深度学习都收获了极大的成功。

作为本书的开篇,为了使读者有一个全面的认知,本章将专注于介绍物体检测的基础知识、发展历史,以及为什么选择PyTorch作为深度学习的框架。1.1 深度学习与计算机视觉

近年来,人工智能、机器学习、深度学习、物体检测这样的名词经常会出现在大家的眼前,但大家对这些技术之间的区别与联系却经常混淆。基于此,本节将会介绍每一个技术的基本概念与发展历史。1.1.1 发展历史

当前的计算机无论是处理多复杂的计算任务,其基本逻辑始终是0与1的位运算,凭借其每秒亿万的计算次数,计算机可以快速完成复杂的数学运算,这是人类无法比拟的。然而,涉及高语义的理解、判断,甚至是情感、意识(如判断一张图像中有几个儿童)这种对于人类轻而易举的任务,对计算机而言却很难处理,因为这种问题无法建立明确的数学规则。

为了赋予计算机以人类的理解能力与逻辑思维,诞生了人工智能(Artificial Intelligence,AI)这一学科。在实现人工智能的众多算法中,机器学习是发展较为快速的一支。机器学习的思想是让机器自动地从大量的数据中学习出规律,并利用该规律对未知的数据做出预测。在机器学习的算法中,深度学习是特指利用深度神经网络的结构完成训练和预测的算法。

人工智能、机器学习、深度学习这三者的关系如图1.1所示。可以看出,机器学习是实现人工智能的途径之一,而深度学习则是机器学习的算法之一。如果把人工智能比喻成人类的大脑,机器学习则是人类通过大量数据来认知学习的过程,而深度学习则是学习过程中非常高效的一种算法。图1.1 人工智能、机器学习与深度学习三者间的关系

下面详细介绍这三者的发展历程。

1.人工智能

人工智能的概念最早来自于1956年的计算机达特茅斯会议,其本质是希望机器能够像人类的大脑一样思考,并作出反应。由于极具难度与吸引力,人工智能从诞生至今,吸引了无数的科学家与爱好者投入研究。搭载人工智能的载体可以是近年来火热的机器人、自动驾驶车辆,甚至是一个部署在云端的智能大脑。

根据人工智能实现的水平,我们可以进一步分为3种人工智能,如图1.2所示。图1.2 人工智能分类

弱人工智能(Artificial Narrow Intelligence,ANI):擅长某个特定任务的智能。例如语言处理领域的谷歌翻译,让该系统去判断一张图片中是猫还是狗,就无能无力了。再比如垃圾邮件的自动分类、自动驾驶车辆、手机上的人脸识别等,当前的人工智能大多是弱人工智能。

强人工智能:在人工智能概念诞生之初,人们期望能够通过打造复杂的计算机,实现与人一样的复杂智能,这被称做强人工智能,也可以称之为通用人工智能(Artificial General Intelligence,AGI)。这种智能要求机器像人一样,听、说、读、写样样精通。目前的发展技术尚未达到通用人工智能的水平,但已经有众多研究机构展开了研究。

超人工智能(Artificial Super Intelligence,ASI):在强人工智能之上,是超人工智能,其定义是在几乎所有领域都比人类大脑聪明的智能,包括创新、社交、思维等。人工智能科学家Aaron Saenz曾有一个有趣的比喻,现在的弱人工智能就好比地球早期的氨基酸,可能突然之间就会产生生命。超人工智能不会永远停留在想象之中。

人类追求人工智能的脚步永不会停止,例如鼎鼎有名的智能围棋学习系统AlphaGo,由谷歌大脑团队开发,在2016年3月15日以4∶1的总比分战胜了韩国围棋选手李世石,引发了全世界巨大的反响。谷歌在时隔一年后推出了AlphaGo Zero,可以在不使用人类棋谱经验的前提下成为一个围棋高手,具有划时代的意义。我们也有理由相信,实现更高级的人工智能指日可待。

2.机器学习

机器学习是实现人工智能的重要途径,也是最早发展起来的人工智能算法。与传统的基于规则设计的算法不同,机器学习的关键在于从大量的数据中找出规律,自动地学习出算法所需的参数。

机器学习最早可见于1783年的贝叶斯定理中。贝叶斯定理是机器学习的一种,根据类似事件的历史数据得出发生的可能性。在1997年,IBM开发的深蓝(Deep Blue)象棋电脑程序击败了世界冠军。当然,最令人振奋的成就还当属2016年打败李世石的AlphaGo。

机器学习算法中最重要的就是数据,根据使用的数据形式,可以分为三大类:监督学习(Supervised Learning)、无监督学习(Unsupervised Learning)与强化学习(Reinforcement Learning),如图1.3所示。

·监督学习:通常包括训练与预测阶段。在训练时利用带有人工标注标签的数据对模型进行训练,在预测时则根据训练好的模型对输入进行预测。监督学习是相对成熟的机器学习算法。监督学习通常分为分类与回归两个问题,常见算法有决策树(Decision Tree,DT)、支持向量机(Support Vector Machine,SVM)和神经网络等。

·无监督学习:输入的数据没有标签信息,也就无法对模型进行明确的惩罚。无监督学习常见的思路是采用某种形式的回报来激励模型做出一定的决策,常见的算法有K-Means聚类与主成分分析(Principal Component Analysis,PCA)。

·强化学习:让模型在一定的环境中学习,每次行动会有对应的奖励,目标是使奖励最大化,被认为是走向通用人工智能的学习方法。常见的强化学习有基于价值、策略与模型3种方法。

机器学习涉及概率、统计、凸优化等多个学科,目前已在数据挖掘、计算机视觉、自然语言处理、医学诊断等多个领域有了相当成熟的应用。图1.3 机器学习算法总览

3.深度学习

深度学习是机器学习的技术分支之一,主要是通过搭建深层的人工神经网络(Artificial Neural Network)来进行知识的学习,输入数据通常较为复杂、规模大、维度高。深度学习可以说是机器学习问世以来最大的突破之一。

深度学习的发展经历了一番波折,具体历程如图1.4所示。

最早的神经网络可以追溯到1943年的MCP(McCulloch and Pitts)人工神经元网络,希望使用简单的加权求和与激活函数来模拟人类的神经元过程。在此基础上,1958年的感知器(Perception)模型使用了梯度下降算法来学习多维的训练数据,成功地实现了二分类问题,也掀起了深度学习的第一次热潮。图1.5代表了一个最简单的单层感知器,输入有3个量,通过简单的权重相加,再作用于一个激活函数,最后得到了输出y。图1.4 深度学习发展历程图1.5 单层感知器

然而,1969年,Minsky证明了感知器仅仅是一种线性模型,对简单的亦或判断都无能为力,而生活中的大部分问题都是非线性的,这直接让学者研究神经网络的热情难以持续,造成了深度学习长达20年的停滞不前。

1986年,深度学习领域“三驾马车”之一的Geoffrey Hinton创造性地将非线性的Sigmoid函数应用到了多层感知器中,并利用反向传播(Backpropagation)算法进行模型学习,使得模型能够有效地处理非线性问题。1998年,“三驾马车”中的卷积神经网络之父Yann LeCun发明了卷积神经网络LeNet模型,可有效解决图像数字识别问题,被认为是卷积神经网络的鼻祖。

然而在此之后的多年时间里,深度学习并没有代表性的算法问世,并且神经网络存在两个致命问题:一是Sigmoid在函数两端具有饱和效应,会带来梯度消失问题;另一个是随着神经网络的加深,训练时参数容易陷入局部最优解。这两个弊端导致深度学习陷入了第二次低谷。在这段时间内,反倒是传统的机器学习算法,如支持向量机、随机森林等算法获得了快速的发展。

2006年,Hinton提出了利用无监督的初始化与有监督的微调缓解了局部最优解问题,再次挽救了深度学习,这一年也被称为深度学习元年。2011年诞生的ReLU激活函数有效地缓解了梯度消失现象。

真正让深度学习迎来爆发式发展的当属2012年的AlexNet网络,其在ImageNet图像分类任务中以“碾压”第二名算法的姿态取得了冠军。深度学习从此一发不可收拾,VGGNet、ResNet等优秀的网络接连问世,并且在分类、物体检测、图像分割等领域渐渐地展现出深度学习的实力,大大超过了传统算法的水平。

当然,深度学习的发展离不开大数据、GPU及模型这3个因素,如图1.6所示。图1.6 深度学习中的核心因素

·大数据:当前大部分的深度学习模型是有监督学习,依赖于数据的有效标注。例如,要做一个高性能的物体检测模型,通常需要使用上万甚至是几十万的标注数据。数据的积累也是一个公司深度学习能力雄厚的标志之一,没有数据,再优秀的模型也会面对无米之炊的尴尬。

·GPU:当前深度学习如此“火热”的一个很重要的原因就是硬件的发展,尤其是GPU为深度学习模型的快速训练提供了可能。深度学习模型通常有数以千万计的参数,存在大规模的并行计算,传统的以逻辑运算能力著称的CPU面对这种并行计算会异常缓慢,GPU以及CUDA计算库专注于数据的并行计算,为模型训练提供了强有力的工具。

·模型:在大数据与GPU的强有力支撑下,无数研究学者的奇思妙想,催生出了VGGNet、ResNet和FPN等一系列优秀的深度学习模型,并且在学习任务的精度、速度等指标上取得了显著的进步。

根据网络结构的不同,深度学习模型可以分为卷积神经网络(Convolutional Neural Network,CNN)、循环神经网络(Recurrent Neural Network,RNN)及生成式对抗网络(Generative Adviserial Network,GAN)。1.1.2 计算机视觉

视觉是人类最为重要的感知系统,大脑皮层中近一半的神经元与视觉有关系。计算机视觉则是研究如何使机器学会“看”的学科,最早起源于20世纪50年代,当时主要专注于光学字符识别、航空图片的分析等特定任务。在20世纪90年代,计算机视觉在多视几何、三维重建、相机标定等多个领域取得了众多成果,也走向了繁荣发展的阶段。

然而在很长的一段时间里,计算机视觉的发展都是基于规则与人工设定的模板,很难有鲁棒的高语义理解。真正将计算机视觉的发展推向高峰的,当属深度学习的爆发。由于视觉图像丰富的语义性与图像的结构性,计算机视觉也是当前人工智能发展最为迅速的领域之一。

进入深度学习发展阶段后,计算机视觉在多个领域都取得了令人瞩目的成就,如图1.7所示。

·图像成像:成像是计算机视觉较为底层的技术,深度学习在此发挥的空间更多的是成像后的应用,如修复图像的DCGAN网络,图像风格迁移的CycleGAN,这些任务中GAN有着广阔的发挥空间。此外,在医学成像、卫星成像等领域中,超分辨率也至关重要,例如SRCNN(Super-Resolution CNN)。

·2.5D空间:我们通常将涉及2D运动或者视差的任务定义为2.5D空间问题,因为其任务跳出了单纯的2D图像,但又缺乏3D空间的信息。这里包含的任务有光流的估计、单目的深度估计及双目的深度估计。

·3D空间:3D空间的任务通常应用于机器人或者自动驾驶领域,将2D图像检测与3D空间进行结合。这其中,主要任务有相机标定(Camera Calibration)、视觉里程计(Visual Odometry,VO)及SLAM(Simultaneous Localization and Mapping)等。

·环境理解:环境的高语义理解是深度学习在计算机视觉中的主战场,相比传统算法其优势更为明显。主要任务有图像分类(Classification)、物体检测(Object Detection)、图像分割(Segmentation)、物体跟踪(Tracking)及关键点检测。其中,图像分割又可以细分为语义分割(Semantic Segmentation)与实例分割(Instance Segmentation)。图1.7 深度学习在计算机视觉中的应用1.2 物体检测技术

在计算机视觉众多的技术领域中,物体检测是一项非常基础的任务,图像分割、物体追踪、关键点检测等通常都要依赖于物体检测。此外,由于每张图像中物体的数量、大小及姿态各不相同,也就是非结构化的输出,这是与图像分类非常不同的一点,并且物体时常会有遮挡截断,物体检测技术也极富挑战性,从诞生以来始终是研究学者最为关注的焦点领域之一。

物体检测技术,通常是指在一张图像中检测出物体出现的位置及对应的类别。对于图1.8中的人,我们要求检测器输出5个量:物体类别、x、y、x与y。当然,对于一个边框,检测器也可以minminmaxmax输出中心点与宽高的形式,这两者是等价的。图1.8 物体检测示例

在计算机视觉中,图像分类、物体检测与图像分割是最基础、也是目前发展最为迅速的3个领域。图1.9列出了这3个任务之间的区别。图1.9 图像分类、物体检测与图像分割的区别

·图像分类:输入图像往往仅包含一个物体,目的是判断每张图像是什么物体,是图像级别的任务,相对简单,发展也最快。

·物体检测:输入图像中往往有很多物体,目的是判断出物体出现的位置与类别,是计算机视觉中非常核心的一个任务。

·图像分割:输入与物体检测类似,但是要判断出每一个像素属于哪一个类别,属于像素级的分类。图像分割与物体检测任务之间有很多联系,模型也可以相互借鉴。1.2.1 发展历程

在利用深度学习做物体检测之前,传统算法对于物体的检测通常分为区域选取、特征提取与特征分类这3个阶段,如图1.10所示。图1.10 传统物体检测算法思路

·区域选取:首先选取图像中可能出现物体的位置,由于物体位置、大小都不固定,因此传统算法通常使用滑动窗口(Sliding Windows)算法,但这种算法会存在大量的冗余框,并且计算复杂度高。

·特征提取:在得到物体位置后,通常使用人工精心设计的提取器进行特征提取,如SIFT和HOG等。由于提取器包含的参数较少,并且人工设计的鲁棒性较低,因此特征提取的质量并不高。

·特征分类:最后,对上一步得到的特征进行分类,通常使用如SVM、AdaBoost的分类器。

深度学习时代的物体检测发展过程如图1.11所示。深度神经网络大量的参数可以提取出鲁棒性和语义性更好的特征,并且分类器性能也更优越。2014年的RCNN(Regions with CNN features)算是使用深度学习实现物体检测的经典之作,从此拉开了深度学习做物体检测的序幕。图1.11 深度学习检测器的发展历程

在RCNN基础上,2015年的Fast RCNN实现了端到端的检测与卷积共享,Faster RCNN提出了锚框(Anchor)这一划时代的思想,将物体检测推向了第一个高峰。在2016年,YOLO v1实现了无锚框(Anchor-Free)的一阶检测,SSD实现了多特征图的一阶检测,这两种算法对随后的物体检测也产生了深远的影响,在本书中将分别用一章的篇幅详细介绍。

在2017年,FPN利用特征金字塔实现了更优秀的特征提取网络,Mask RCNN则在实现了实例分割的同时,也提升了物体检测的性能。进入2018年后,物体检测的算法更为多样,如使用角点做检测的CornerNet、使用多个感受野分支的TridentNet、使用中心点做检测的CenterNet等。

在物体检测算法中,物体边框从无到有,边框变化的过程在一定程度上体现了检测是一阶的还是两阶的。

·两阶:两阶的算法通常在第一阶段专注于找出物体出现的位置,得到建议框,保证足够的准召率,然后在第二个阶段专注于对建议框进行分类,寻找更精确的位置,典型算法如Faster RCNN。两阶的算法通常精度准更高,但速度较慢。当然,还存在例如Cascade RCNN这样更多阶的算法。

·一阶:一阶的算法将二阶算法的两个阶段合二为一,在一个阶段里完成寻找物体出现位置与类别的预测,方法通常更为简单,依赖于特征融合、Focal Loss等优秀的网络经验,速度一般比两阶网络更快,但精度会有所损失,典型算法如SSD、YOLO系列等。

Anchor是一个划时代的思想,最早出现在Faster RCNN中,其本质上是一系列大小宽高不等的先验框,均匀地分布在特征图上,利用特征去预测这些Anchors的类别,以及与真实物体边框存在的偏移。Anchor相当于给物体检测提供了一个梯子,使得检测器不至于直接从无到有地预测物体,精度往往较高,常见算法有Faster RCNN和SSD等。

当然,还有一部分无锚框的算法,思路更为多样,有直接通过特征预测边框位置的方法,如YOLO v1等。最近也出现了众多依靠关键点来检测物体的算法,如CornerNet和CenterNet等。1.2.2 技术应用领域

由于检测性能的迅速提升,物体检测也是深度学习在工业界取得大规模应用的领域之一。以下列举了5个广泛应用的领域。

·安防:受深度学习的影响,安防领域近年来取得了快速的发展与落地。例如广为人知的人脸识别技术,在交通卡口、车站等已有了成熟的应用。此外,在智慧城市的安防中,行人与车辆的检测也是尤为重要的一环。在安防领域中,有很大的趋势是将检测技术融入到摄像头中,形成智能摄像头,以海康威视、地平线等多家公司最为知名。

·自动驾驶:自动驾驶的感知任务中,行人、车辆等障碍物的检测尤为重要。由于涉及驾驶的安全性,自动驾驶对于检测器的性能要求极高,尤其是召回率这个指标,自动驾驶也堪称人工智能应用的“珠穆朗玛峰”。此外,由于车辆需要获取障碍物相对于其自身的三维位置,因此通常在检测器后还需要增加很多的后处理感知模块。

·机器人:工业机器人自动分拣中,系统需要识别出要分拣的各种部件,这是极为典型的机器人应用领域。此外,移动智能机器人需要时刻检测出环境中的各种障碍物,以实现安全的避障与导航。从广泛意义来看,自动驾驶车辆也可以看做是机器人的一种形式。

·搜索推荐:在互联网公司的各大应用平台中,物体检测无处不在。例如,对于包含特定物体的图像过滤、筛选、推荐和水印处理等,在人脸、行人检测的基础上增加更加丰富的应用,如抖音等产品。

·医疗诊断:基于人工智能与大数据,医疗诊断也迎来了新的春天,利用物体检测技术,我们可以更准确、迅速地对CT、MR等医疗图像中特定的关节和病症进行诊断。1.2.3 评价指标

对于一个检测器,我们需要制定一定的规则来评价其好坏,从而选择需要的检测器。对于图像分类任务来讲,由于其输出是很简单的图像类别,因此很容易通过判断分类正确的图像数量来进行衡量。

物体检测模型的输出是非结构化的,事先并无法得知输出物体的数量、位置、大小等,因此物体检测的评价算法就稍微复杂一些。对于具体的某个物体来讲,我们可以从预测框与真实框的贴合程度来判断检测的质量,通常使用IoU(Intersection of Union)来量化贴合程度。

IoU的计算方式如图1.12所示,使用两个边框的交集与并集的比值,就可以得到IoU,公式如式(1-1)所示。显而易见,IoU的取值区间是[0,1],IoU值越大,表明两个框重合越好。图1.12 IoU的计算过程

利用Python可以很方便地实现IoU的计算,代码如下:def iou(boxA, boxB): # 计算重合部分的上、下、左、右4个边的值,注意最大最小函数的使用 left_max = max(boxA[0], boxB[0]) top_max = max(boxA[1], boxB[1]) right_min = min(boxA[2], boxB[2]) bottom_min = min(boxA[3], boxB[3]) # 计算重合部分的面积 inter =max(0,(right_min-left_max))* max(0,(bottom_min-top_max) Sa = (boxA[2]-boxA[0])*(boxA[3]-boxA[1]) Sb = (boxB[2]-boxB[0])*(boxB[3]-boxB[1]) # 计算所有区域的面积并计算iou,如果是Python 2,则要增加浮点化操作 union = Sa+Sb-inter iou = inter/union return iou

对于IoU而言,我们通常会选取一个阈值,如0.5,来确定预测框是正确的还是错误的。当两个框的IoU大于0.5时,我们认为是一个有效的检测,否则属于无效的匹配。如图1.13中有两个杯子的标签,模型产生了两个预测框。图1.13 正、负样本判别示例

由于图像中存在背景与物体两种标签,预测框也分为正确与错误,因此在评测时会产生以下4种样本。

·正确检测框TP(True Positive):预测框正确地与标签框匹配了,两者间的IoU大于0.5,如图1.13中右下方的检测框。

·误检框FP(False Positive):将背景预测成了物体,如图1.13中左下方的检测框,通常这种框与图中所有标签的IoU都不会超过0.5。

·漏检框FN(False Negative):本来需要模型检测出的物体,模型没有检测出,如图1.13中左上方的杯子。

·正确背景(True Negative):本身是背景,模型也没有检测出来,这种情况在物体检测中通常不需要考虑。

有了上述基础知识,我们就可以开始进行检测模型的评测。对于一个检测器,通常使用mAP(mean Average Precision)这一指标来评价一个模型的好坏,这里的AP指的是一个类别的检测精度,mAP则是多个类别的平均精度。评测需要每张图片的预测值与标签值,对于某一个实例,二者包含的内容分别如下:

·预测值(Dets):物体类别、边框位置的4个预测值、该物体的得分。

·标签值(GTs):物体类别、边框位置的4个真值。

在预测值与标签值的基础上,AP的具体计算过程如图1.14所示。我们首先将所有的预测框按照得分从高到低进行排序(因为得分越高的边框其对于真实物体的概率往往越大),然后从高到低遍历预测框。图1.14 AP的计算过程

对于遍历中的某一个预测框,计算其与该图中同一类别的所有标签框GTs的IoU,并选取拥有最大IoU的GT作为当前预测框的匹配对象。如果该IoU小于阈值,则将当前的预测框标记为误检框FP。

如果该IoU大于阈值,还要看对应的标签框GT是否被访问过。如果前面已经有得分更高的预测框与该标签框对应了,即使现在的IoU大于阈值,也会被标记为FP。如果没有被访问过,则将当前预测框Det标记为正确检测框TP,并将该GT标记为访问过,以防止后面还有预测框与其对应。

在遍历完所有的预测框后,我们会得到每一个预测框的属性,即TP或FP。在遍历的过程中,我们可以通过当前TP的数量来计算模型的召回率(Recall,R),即当前一共检测出的标签框与所有标签框的比值,如式(1-2)所示。

除了召回率,还有一个重要指标是准确率(Precision,P),即当前遍历过的预测框中,属于正确预测边框的比值,如式(1-3)所示。

遍历到每一个预测框时,都可以生成一个对应的P与R,这两个值可以组成一个点(R,P),将所有的点绘制成曲线,即形成了P-R曲线,如图1.15所示。图1.15 物体检测的P-R曲线

然而,即使有了P-R曲线,评价模型仍然不直观,如果直接取曲线上的点,在哪里选取都不合适,因为召回率高的时候准确率会很低,准确率高的时候往往召回率很低。这时,AP就派上用场了,计算公式如式(1-4)所示。

从公式中可以看出,AP代表了曲线的面积,综合考量了不同召回率下的准确率,不会对P与R有任何偏好。每个类别的AP是相互独立的,将每个类别的AP进行平均,即可得到mAP。严格意义上讲,还需要对曲线进行一定的修正,再进行AP计算。除了求面积的方式,还可以使用11个不同召回率对应的准确率求平均的方式求AP。

下面从代码层面详细讲述AP求解过程。假设当前经过标签数据与预测数据的加载,我们得到了下面两个变量:

·det_boxes:包含全部图像中所有类别的预测框,其中一个边框包含了[left,top,right,bottom,score,NameofImage]。

·gt_boxes:包含了全部图像中所有类别的标签,其中一个标签的内容为[left,top,right,bottom,0]。需要注意的是,最后一位0代表该标签有没有被匹配过,如果匹配过则会置为1,其他预测框再去匹配则为误检框。

下面是所有类别的评测过程。for c in classes: # 通过类别作为关键字,得到每个类别的预测、标签及总标签数 dects = det_boxes[c] gt_class = gt_boxes[c] npos = num_pos[c] # 利用得分作为关键字,对预测框按照得分从高到低排序 dects = sorted(dects, key=lambda conf: conf[5], reverse=True) # 设置两个与预测边框长度相同的列表,标记是True Positive还是False Positive TP = np.zeros(len(dects)) FP = np.zeros(len(dects)) # 对某一个类别的预测框进行遍历 for d in range(len(dects)): # 将IoU默认置为最低 iouMax = sys.float_info.min # 遍历与预测框同一图像中的同一类别的标签,计算IoU if dects[d][-1] in gt_class: for j in range(len(gt_class[dects[d][-1]])): iou = Evaluator.iou(dects[d][:4], gt_class[dects[d][-1]][j][:4]) if iou > iouMax: iouMax = iou jmax = j # 记录与预测有最大IoU的标签 # 如果最大IoU大于阈值,并且没有被匹配过,则赋予TP if iouMax >= cfg['iouThreshold']: if gt_class[dects[d][-1]][jmax][4] == 0: TP[d] = 1 gt_class[dects[d][-1]][jmax][4] = 1 # 标记为匹配过 # 如果被匹配过,赋予FP else: FP[d] = 1 # 如果最大IoU没有超过阈值,赋予FP else: FP[d] = 1 # 如果对应图像中没有该类别的标签,赋予FP else: FP[d] = 1 # 利用NumPy的cumsum()函数,计算累计的FP与TP acc_FP = np.cumsum(FP) acc_TP = np.cumsum(TP) rec = acc_TP / npos # 得到每个点的Recall prec = np.divide(acc_TP, (acc_FP + acc_TP)) # 得到每个点的Precision # 利用Recall与Precision进一步计算得到AP [ap, mpre, mrec, ii] = Evaluator.CalculateAveragePrecision(rec, prec)1.3 PyTorch简介

工欲善其事,必先利其器。对于物体检测的学习,选择一个优秀的框架是一件十分重要的事情。笔者综合考虑了框架性能、简洁性、长远发展等多个因素,最终选择了PyTorch作为本书的深度学习框架。

本节将会介绍PyTorch框架的诞生与发展历程,以及为什么选择PyTorch,最后将介绍多种安装PyTorch的方法。1.3.1 诞生与特点

2017年的1月,来自于Facebook的研究人员在GitHub上推出了PyTorch,并凭借其简洁易用的特性,迅速在人工智能的各大应用领域流行起来,一时间成为最炙手可热的深度学习框架。

PyTorch的前身是诞生于2002年的Torch框架。Torch使用了小众化的Lua作为编程接口,虽然对于深度神经网络的实现比较高效,但由于Lua使用人数不多,Torch并没有受到广泛的关注。而在计算科学领域,Python由于其简单易用与完整的生态,优势渐渐体现了出来。在此基础上,2017年Facebook的团队对Torch张量之上的所有模块进行了重构,并增加了自动求导这一先进的理念,实现了一个高效的动态图框架PyTorch。

在2018年NeurIPS大会上,Facebook推出了PyTorch 1.0版本,该版本吸收了Caffe 2和ONNX模块化及面向生产的特点,使得算法可以从研究原型快速无缝衔接到生产部署中。这意味着,PyTorch的生态将更加完备,在进行算法原型研究、移动部署时将更加便利。1.3.2 各大深度学习框架对比

为了更好地支持深度学习算法的研究与落地,各大公司和研究机构陆续推出了多种深度学习框架,除了PyTorch之外,还有几种知名的框架,如TensorFlow、MXNet、Keras、Caffe和Theano等,广泛应用于计算机视觉、自然语言处理、语音识别等领域,如图1.16所示。图1.16 各大主流深度学习计算框架

不同的深度学习框架通常有不同的设计理念,优势和劣势也各不相同,本节将简要介绍这几种主流的框架。

1.TensorFlow简介

2015年,谷歌大脑(Google Brain)团队推出了深度学习开源框架TensorFlow,其前身是谷歌的DistBelief框架。凭借其优越的性能与谷歌在深度学习领域的巨大影响力,TensorFlow一经推出就引起了广泛的关注,逐渐成为用户最多的深度学习框架。

TensorFlow使用数据流图进行网络计算,图中的节点代表具体的数学运算,边则代表了节点之间流动的多维张量Tensor。TensorFlow有Python与C++两种编程接口,并且随着发展,也渐渐支持Java、Go等语言,并且可以在ARM移动式平台上进行编译与优化,因此,TensorFlow拥有非常完备的生态与生产环境。

TensorFlow的优点很明显,功能完全,对于多GPU的支持更好,有强大且活跃的社区,并且拥有强大的可视化工具TensorBoard。当然,其缺点在于系统设计较为复杂,接口变动较快,兼容性较差,并且由于其构造的图是静态的,导致图必须先编译再执行,不利于算法的预研等。

2.MXNet简介

MXNet由DMLC(Distributed Machine Learning Community)组织创建,该组织成员以陈天奇、李沐为代表,大部分都为中国人。MXNet项目于2015年在GitHub上正式开源,于2016年被亚马逊AWS正式选择为其云计算的官方深度学习平台,并在2017年进入Apache软件基金会,正式成为了Apache的孵化器项目。

MXNet的特色是将命令式编程与声明式编程进行结合,在命令式编程上提供了张量计算,在声明式编程上支持符号表达式,用户可以自由地进行选择。此外,MXNet提供了多种语言接口,有超强的分布式支持,对于内存和显存做了大量优化,尤其适用于分布式环境中。

但是,MXNet的推广不够有力,文档的更新没有跟上框架的迭代速度,导致新手上手MXNet较难,因此MXNet也一直没有得到大规模的应用。目前国内的众多AI创业公司都在使用MXNet框架。

3.Keras简介

Keras是建立在TensorFlow、Theano及CNTK等多个框架之上的神经网络API,对深度学习的底层框架作了进一步封装,提供了更为简洁、易上手的API。Keras使用Python语言,并且可以在CPU与GPU间无缝切换。

Keras的首要设计原则就是用户的使用体验,把神经网络模块化,因此Keras使用相对简单,入门快。但是,Keras构建于第三方框架之上,导致其灵活性不足,调试不方便,用户在使用时也很难学习到神经网络真正的内容。从性能角度看,Keras也是较慢的一个框架。

4.Caffe与Caffe 2简介

Caffe(Convolutional Architecture for Fast Feature Embedding)发布于2013年,作者是贾扬清博士。Caffe的核心语言是C++,支持CPU与GPU两种模式的计算。Caffe的优点是设计清晰、实现高效,尤其是对于C++的支持,使工程师可以方便地在各种工程应用中部署Caffe模型,曾经占据了神经网络框架的半壁江山。

Caffe的主要缺点是灵活性不足。在Caffe中,实现一个神经网络新层,需要利用C++来完成前向传播与反向传播的代码,并且需要编写CUDA代码实现在GPU端的计算,总体上更偏底层,显然与当前深度学习框架动态图、灵活性的发展趋势不符。

在2017年,Facebook推出了Caffe 2,主要开发者仍然是贾扬清博士。Caffe 2是一个轻量化与跨平台的深度学习框架,继承了Caffe大量的设计理念,同时为移动端部署做了很多优化,性能极佳。Caffe 2的核心库是C++,但也提供了Python的API,可以方便地在多个平台进行模型训练与部署。

作为Facebook推出的框架,Caffe 2的优点是高性能与跨平台部署。PyTorch的优点是灵活性与原型的快速实现。为了进一步提升开发者的效率,Facebook于2018年宣布将Caffe 2代码全部并入PyTorch。1.3.3 为什么选择PyTorch

前面介绍的深度学习框架多多少少都有一些缺陷,而PyTorch作为后起之秀,是一个难得的集简洁与高性能于一身的一个框架,笔者在本书中选择PyTorch来实现物体检测算法,主要原因有4点,如图1.17所示。

·简洁优雅:PyTorch是一个十分Pythonic的框架,代码风格与普通的Python代码很像,甚至可以看做是带有GPU优化的NumPy模块,这使得使用者很容易理解模型的框架与逻辑。此外,PyTorch是一个动态图框架,拥有自动求导机制,对神经网络有着尽量少的概念抽象,这使得使用者更容易调试、了解模型的每一步到底发生了什么,而不至于是一个黑箱。

·易上手:PyTorch与Python一样,追求用户的使用体验,所有的接口都十分易用,对于使用者极为友好。与Keras不同的是,在接口易用的同时,PyTorch很难得地保留了灵活性,使用者可以利用PyTorch自由地实现自己的算法。另外,PyTorch的文档简洁又精髓,建议初学者可以通读一遍。

·速度快:PyTorch在追求简洁易用的同时,在模型的速度表现上也极为出色,相比TensorFlow等框架,很多模型在PyTorch上的实现可能会更快。这一点也使得学术界有大量PyTorch的忠实用户,因为使用PyTorch既可以快速实现自己的想法,又能够保证优秀的速度性能。

·发展趋势:PyTorch在问世的两年多时间里,发展趋势十分迅猛,fast.ai、NVIDIA等知名公司也选择使用PyTorch作为深度学习框架。PyTorch背后是Facebook人工智能研究院,有这一顶级AI机构强有力的支持,生态完备,尤其是在Caffe 2并入PyTorch之后,PyTorch未来的发展值得期待。图1.17 PyTorch的优势1.3.4 安装方法

PyTorch目前支持Ubuntu、Mac OS、Windows等多个系统,本书将主要围绕Ubuntu系统进行讲解。PyTorch官网中提供了pip、Conda、源码等多种安装方法,由于源码安装较为复杂,通常情况下使用不到,在此只介绍pip与Conda两种安装方法。

由于本书介绍的物体检测算法模型通常较大,因此我们需要使用带有GPU加速版本的PyTorch。在安装PyTorch之前,你需要有一台带有GPU的机器,并从NVIDIA官网下载安装对应的显卡驱动,在终端中输入以下命令可以证明驱动已装好,并显示GPU的内存、使用情况等信息:nvidia-smi

在安装完显卡驱动后,我们还需要安装CUDA(Compute Unified Device Architecture)。CUDA是NVIDIA推出的通用并行计算架构,可以使类似于PyTorch之类的深度学习框架调用GPU来解决复杂的计算问题。

为了实现更高效的GPU并行计算,通常我们还需要安装cuDNN库。cuDNN库是由NVIDIA开发的专用于深度神经网络的GPU加速库。由于CUDA与cuDNN的安装较为简单,在此就不展开了,读者可以参考官网教程进行安装。在完成上述步骤后,即可使用pip或者Conda安装PyTorch。

1.pip安装

pip是一个通用的Python包管理工具,可以便捷地实现Python包的查找、下载、安装与卸载。使用pip安装PyTorch的方法可以参考官网教程,我们以Python 3.6、CUDA 9.0、PyTorch 0.4.0为例,使用下面的指令即可完成PyTorch安装:pip3 install torch==0.4.0

安装后,在终端中输入python3,再输入以下指令:>>> import torch>>> torch.cuda.is_available() #判断当前GPU是否可用True

如果没有报错,则表明PyTorch安装成功。

2.Conda安装

Conda是一个开源的软件管理包系统和环境管理系统,可以安装多个版本的软件包,并在其间自由切换。相比于pip,Conda功能更为强大,可以提供多个Python环境,并且解决包依赖的能力更强。我们可以通过安装Anaconda来使用Conda,安装方式可以参考官网教程,在此不再展开介绍。

安装好Conda后,可以使用如下指令安装PyTorch。conda install pytorch=0.4.0 cuda90 -c pytorch注意:在使用pip或者Conda安装软件包时,如果下载速度较慢,可以考虑将pip或者Conda的源更换为国内的源,这样速度会更快。1.4 基础知识准备

在后续的物体检测学习过程中,我们会涉及数据集的操作,以及模型的设计、优化、训练与评测等,这些内容都需要有一定的Linux基础。此外,PyTorch框架使用了Python作为基本编程语言,因此读者也需要具备一定的Python基础。

因此,本节将会简要地介绍本书所需的Linux与Python基础,并介绍几种笔者认为十分好用的工具,可以极大地方便读者的学习。1.4.1 Linux基础

Linux诞生于1991年,是一个免费使用与自由传播的类UNIX操作系统,凭借其稳定的性能与开放的社区,在手机、电脑、超级计算机等各种计算机设备中都能看到Linux的身影。我们现今使用的更多是Linux发行版系统,即将Linux内核与应用软件做了打包,并进行依赖管理,如Ubuntu、CentOS和Fedora等。Linux内核与发行版系统的关系如图1.18所示。需要注意的是,Linux内核是独立的程序,每个发行版维护自己修改的内核。图1.18 Linux内核与多个发行版

由于Linux系统知识树很大,本节不可能对所有知识点都覆盖到,因此这里将简要介绍基本目录结构和环境变量这两个知识点。

1.基本目录结构

Linux的首要思想是“一切都是文件”,数据与程序都是以文件形式存在,甚至是主机与外围众多设备之间的交互也抽象成对文件的操作,因此对于Linux系统,我们首先需要了解其目录树结构。为了统一各大Linux发行版对目录文件的定义,FHS结构在1994年对Linux根目录做了统一的规范,必须包含boot、lib、home、usr和opt等文件。下面对几个主要的目录进行说明:

·boot:Linux系统启动时用到的文件,建议单独分区,大小512MB即可。

·lib:系统使用到的函数库目录,协助系统中程序的执行,比较重要的有lib/modules目录,存放着内存文件。

·bin:可执行的文件目录,包含了如ls、mv和cat等常用的命令。

·home:默认的用户目录,包含了所有用户的目录与数据,建议设置较大的磁盘空间。

·usr:应用程序存放的目录,其中,usr/local目录下存放一些软件升级包,如Python、CUDA等,usr/lib目录下存放一些不能直接运行但却是其他程序不可或缺的库文件,usr/share目录下存放一些共享的数据。

·opt:额外安装的软件所在的目录,例如常用的ROS可执行文件,一般就存放在opt/ros目录下。

2.环境变量

环境变量,通俗讲是指操作系统执行程序时默认设定的参数,如各种可执行文件、库的路径等。在本书中,我们将会用到Python、PyTorch和CUDA等多个库,具体使用时调用的是哪一个版本的库,需要设定环境变量。

环境变量有系统级与用户级之分。系统级的环境变量是每一个登录到系统的用户都要读取的变量,可通过以下两个文件进行设置:

·/etc/environment:用于为所有进程设置环境变量,是系统登录时读取的第一个文件,与登录用户无关,一般要重启系统才会生效。

·/etc/profile:用于设置针对系统所有用户的环境变量,是系统登录时读取的第二个文件,与登录用户有关。

用户级环境变量是指针对当前登录用户设定的环境变量,也可以通过两个文件进行设置:

·~/.profile:对应当前用户的profile文件,用于设置当前用户的工作环境,默认执行一次。

·~/.bashrc:对应当前用户的bash初始化文件,每打开一个终端,就会被执行一次。

我们可以在终端中使用echo来查看当前的环境变量,例如:echo $PYTHONPATH

如果想永久性地设置环境变量,可以在上述的多种文件中添加环

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载