人工智能(Artificial Intelligence,AI)是将人类思维嵌入计算机的一个领域。换句话说,就是创建模仿生物大脑功能的人工大脑。现在,人们需要将使用智能可做的所有事情转移到机器中。第一代AI专注于人类可以规范描述的问题。进行智能操作的步骤以机器必须遵循的指令形式来描述。机器遵循人类给出的步骤,而不做任何改变。这些是第一代AI的特征。
人类可以完整描述一些简单问题,如井字游戏甚至是国际象棋,但无法描述更复杂的问题。在国际象棋中,将棋盘表示为8×8大小的矩阵可以简单地解释问题,描述每个棋子及其走法。机器将仅限于完成人类规范描述的那些任务。通过编写此类指令,机器可智能地下棋,此时机器智能是人工的。机器本身不是智能的,但人类能以几条静态代码行的形式将其智能传递给机器。所谓“静态”,这表示在所有情况下机器行为都是相同的。
这种状况下,机器与人类紧密相连,不能单独工作。这就像是主仆关系。人类是主人,机器是仆人,后者仅遵循人类的指令,而不能做其他事情。
将智能行为嵌入代码块并不能处理人类的所有智能行为。一些简单任务(如排序数字)可以由人类描述,然后交由机器处理,它们具有100%的人类智能。但某些复杂任务,例如语音转文本、图像识别、情感分析等,不能仅通过代码来解决。此类问题无法像国际象棋那样被人类描述。我们不可能编写代码识别猫等图片对象。由于不存在分类物体的单一规则,因此此类识别物体的智能行为不能简单地使用静态代码解决。例如,不存在识别猫的规则。即使某条规则能够成功创建,可以识别某个环境中的猫,但当应用到另一个环境中时,也必然失败。那么,对于此类任务,我们如何使机器拥有智能呢?这就要实现机器学习(Machine Learning,ML),即由机器学习规则。
为了使机器能够识别对象,我们可以按照机器可理解的方式提供来自专家的先验知识。这种基于知识的系统构成第二代AI。此类系统的其中一个挑战在于如何处理不确定性和未知知识。人类可以在不同的复杂环境中识别对象,能够智能地处理不确定性和未知知识,但机器不能。
在ML中,人类负责完成研究数据的复杂任务,要找出哪些类型的特征能够准确地对对象进行分类。遗憾的是,找到最佳类型的特征是一项艰巨的任务。这是研究人员针对不同应用正尝试进行回答的问题。例如,为诊断疾病,专业人士首先要收集患者和未患病者的数据,对这些数据进行正确标记,然后找到可以明确区分他们的某些类型的特征。这类特征可能是年龄、性别、血糖和血压。数据集越大,人类找到适用于所有样本的特征的难度就越大,因此这是一项非常具有挑战性的任务。
但如今,我们可以训练ML模型来了解如何区分不同的类别。ML算法可以找到合适的数学函数,在输入和输出之间建立最健壮的关系。
机器学习算法并不能解决所有问题。关键的智能仍然存在于人类专家的头脑中,而非机器中。人类收集和标记数据,提取最合适的特征,并选择最佳的ML算法。在这之后,机器学习算法仅学习人类所讲的内容。在寻找将输入映射到输出的规则的过程中,机器仍然起着重要的作用。
通常,使用来自特定环境的数据进行训练的ML算法不能用在其他环境中。这是一个关键的限制。整个世界存在着大量数据,数据每天都在增加,传统的机器学习技术不适合对其进行处理。例如,使用一组工程化的特征描述图像是非常复杂的,这是因为即使在同一环境中,情况也是富于变化的。我们应该重复这项工作(即特征工程),以使ML算法能够适用于其他环境。
随着类别数量的增加,人类找到好的区别性特征的能力会降低,因此我们不应该依赖于人类,而要将这些工作留给机器。机器本身会尝试探索数据,找到合适的特征,以区分不同的类别。我们仅需要提供数据给机器即可。这就是深度学习(Deep Learning,DL)。人们正趋于使用卷积神经网络(CNN)这个DL模型处理大量图像。
DL领域着重于学习如何从原始数据中得出结论,而无须进行特征工程之类的中间步骤。这就是实际上DL可以被称为“自动化特征工程”的原因。它对处理器和内存的要求比较高,可能需要数周的时间区分不同的类别。
《深度学习计算机视觉实战》针对的是未来的数据科学家,这些科学家正逐步开始了解DL的基本概念,以用于计算机视觉。读者应该对图像处理和Python有一个基本了解。以下是各章内容的概述。
第1章基于计算机视觉中一些常用特征描述子的介绍,选择了最适合的特征集对Fruits 360数据集进行分类。此类特征使用Python实现。通过在预处理步骤中过滤此类特征,可以使用最少数目的特征进行分类。该章得出的结论是,传统的手工特征不适用于复杂问题。DL是处理大量样本及类别的替代方法。
第2章讨论人工神经网络(Artificial Neural Network,ANN),这是DL模型的基础。它首先解释了ANN仅是线性模型的组合。我们通过指定最佳层数和神经元为一些简单示例设计ANN架构。基于数值示例和Python示例,我们可以清楚地知道ANN如何进行前向和后向传递。
第3章使用第2章中的特征集实现ANN,对Fruits 360 数据集的子集进行分类。由于在实现过程中未使用任何优化技术,因此分类正确率较低。
第4章简单介绍单目标和多目标优化技术。它使用基于随机技术的遗传算法优化ANN权重。这将分类正确率提高到97%以上。
第5章讨论识别多维信号的CNN。该章从强调全连接神经网络(FCNN)和CNN之间的差别以及CNN如何从FCNN中衍生出来开始。基于数值示例,CNN中的两个基本操作(即卷积和池化)的概念将逐渐变得清晰。我们可以使用NumPy实现CNN层,从而详细了解CNN如何工作。
第6章介绍DL库TensorFlow,我们使用这个库构建用于并行和分布式处理大量数据的DL模型。通过构建简单的线性模型和模拟XOR门的ANN等示例,我们讨论了TensorFlow占位符、变量、数据流图和TensorBoard。在该章结束时,使用tensorflow.nn 模块创建了CNN,用于分类CIFAR10数据集。
第7章将训练过的模型部署到Web服务器上,以便让互联网用户使用Web浏览器进行访问。我们使用Flask微框架创建Web应用,使用HTML、CSS和JavaScript构建前端页面来访问Web服务器。HTML页面发送带有一张图像的HTTP请求到服务器,服务器使用预测类别对请求进行响应。
第8章使用Kivy开源库构建跨平台应用。通过将Kivy链接到NumPy,我们可以构建数据科学应用,不作任何改变地在不同平台上进行工作。这消除了对特定平台自定义代码的开销。我们创建了一个Android应用,它读取图像并执行第5章中使用NumPy实现的CNN。
为了让他人从所创建的项目中受益,我们可以将其在线发布。附录A讨论了如何打包Python项目,将它们发布到Python包索引(PyPI)仓库。
在开始学习之前,让我们先简单了解《深度学习计算机视觉实战》中使用的Python环境。
《深度学习计算机视觉实战》中的所有代码都使用Python实现。由于使用原生Python处理图像的工作非常复杂,因此我们在各章中使用了多个库帮助生成高效的实现。
首先,我们可以从www.python.org/downloads这个链接下载原生Python代码。《深度学习计算机视觉实战》使用Python 3(请安装适用于你的系统的Python版本)。下一步是准备《深度学习计算机视觉实战》需要的所有库。我们不建议单独安装各个库,而推荐使用Anaconda Python发行版(可以通过链接www.anaconda.com/download进行下载)。它支持Windows、Mac和Linux并打包了超过1400个的数据科学库。我们可以从https://repo.anaconda. com/pkgs这个页面访问所有受支持的软件包的列表。只要在计算机上安装了Anaconda,所有支持的库就都可以使用。这有助于快速准备好Python环境。
《深度学习计算机视觉实战》所需的库为NumPy、SciPy、Matplotlib、scikit-image、scikit-learn、TensorFlow、Flask、werkzeug、Jinja、pickle、Pillow和Kivy。除了Kivy外,Anaconda支持所有这些库。在《深度学习计算机视觉实战》的各个章节中,我们可以看到各个库的函数。注意,此类库很容易安装。在安装了原生Python后,可使用pip安装程序下载并安装库,所基于的指令为pip install。我们仅需要输入库的名称。有些安装并不简单,可能随着系统的改变而改变。因此,我们无法涵盖不同的安装。出于这个原因,比起分别安装各个库,Anaconda是更好的选择。让我们继续讨论所需的库。
Python支持许多内置的数据结构:列表、元组、字典、集合和字符串。但在数据科学应用中,没有一种数据结构可提供灵活性。
这些数据结构支持同时使用不同的数据类型工作。相同的数据结构可能包含数字、字符、对象等。字符串是个例外,它只支持字符。此外,字符串和元组是不可变的,这意味着在创建后,我们不可能改变它们的值。使用字典保存图像像素要求为每个像素添加键,但这会增大所保存数据的量。集合仅限于集合操作,而图像不限于此类操作。
谈到图像,这是《深度学习计算机视觉实战》的主要内容,列表是合适的数据结构。这是一种可变的数据类型,能够存放矩阵。不过,使用列表会使过程变得复杂。由于不同的数值数据类型可以保存在相同的列表中,因此我们必须确定每一项都是某一特定类型的数值类型。为应用简单的操作(如将一个数字加到图像上),我们必须写一个循环访问每个元素,单独地应用此种操作。在数据科学应用中,我们推荐使用工具让操作变得简单。在构建应用时,我们需要克服一些富有挑战性的任务,而在编写此类任务时,我们没有必要增加另一个挑战。
出于这种原因,我们使用了NumPy库。它的基本作用是在Python语言中支持一种新的数据结构,即数组。使用NumPy数组比使用列表简单。例如,在将图像转换为NumPy数组后,仅使用加法操作,我们就可以将某个数字添加到图像中的每个元素上。许多其他的库也有相应函数接收并返回NumPy数组。
虽然在NumPy数组内部支持某些操作,但这不意味着要应用这些操作。SciPy库支持NumPy数组中的相同操作。它也支持使用scipy.ndimage子模块处理n维NumPy数组(例如图像)。对于有关图像的更多高级操作,我们使用scikit-image库。例如,使用此库可以提取图像特征。
在读取图像并应用一些操作后,我们使用Matplotlib显示图像。我们仅将其用于2D可视化,但是它也支持一些3D特征。
在读取图像、提取特征并进行可视化后,我们可以使用scikit-learn库构建ML模型。它支持备用的不同类型的模型。只需要提供输入、输出及其参数,即可获得已训练的模型。
训练完ML模型后,可使用pickle库将其保存,供以后使用。pickle库可以序列化和反序列化对象。此时,我们可构建和保存ML模型。然后,我们可以转向使用TensorFlow构建和保存DL模型。这是最常使用的DL库,它支持不同的API,可同时满足专业人士和初学者的需求。TensorFlow用自己的方式保存已训练的模型。
Flask是用于构建Web应用程序的微框架,我们使用它部署已训练的模型。通过将已训练的模型部署到Web服务器上,客户端可以使用Web浏览器进行访问。它们可以上传测试图像到服务器,接收类别标签。Flask使用Jinja2模板引擎和WSGI构建应用。因此,我们必须安装Jinja和werkzeug库。
为构建可以在设备上运行的数据科学移动应用,我们要使用Kivy。这是支持Python代码跨平台运行的Python库。在《深度学习计算机视觉实战》中,我们使用Kivy构建适用于Android设备的丰富数据科学应用。在市面上,我们可以使用Kivy生成的APK,它与通常使用Android Studio创建的APK一模一样。
Kivy使用python-for-android打包器,它允许添加所需的依赖包到Android应用程序中。由于scikit-image不支持python-for-android,因此我们使用Pillow读取图像,这个库支持在Android设备上运行。