赞
踩
学习深度学习和人工智能是一次旅程, 读完本书只是旅程的第一站。我希望你认识到这一点,并能准备好独自迈向下一步。
首先我们将概览本书的重要内容,这应该会让你回忆起已经学过的一些概念。接下来,我 们将会概述深度学习一些关键的局限性。想要正确地使用工具,你不仅应该知道它能够做什么, 还应该知道它不能做什么。最后,我会给出我对于深度学习、机器学习和人工智能这些领域未来发展的猜测和思考。如果你想从事基础研究,应该对这一部分特别感兴趣。本章最后列出了 一份资源和策略的简要清单,供你进一步学习人工智能并掌握最新进展参考。
本节简要综述了全书的重点内容。如果你需要快速过一下所学过的内容,那么可以阅读本节。
首先,深度学习不是人工智能的同义词,甚至也不是机器学习的同义词。
**人工智能(artificial intelligence)**是一个古老而宽泛的领域,通常可将其定义为“将认知过程自动化的所有尝试”, 换句话说,就是思想的自动化。它的范围非常广泛,既包括很基本的内容,比如 Excel 电子表格, 也包括非常高级的内容,比如会走路和说话的人形机器人。
机器学习(machine learning)是人工智能的一个特殊子领域,其目标是仅靠观察训练数据来自动开发程序[即模型(model)]。将数据转换为程序的这个过程叫作学习(learning)。虽然 机器学习已经存在了很长时间,但它在 20 世纪 90 年代才开始取得成功。
深度学习(deep learning)是机器学习的众多分支之一,它的模型是一长串几何函数,一个 接一个地作用在数据上。这些运算被组织成模块,叫作层(layer)。深度学习模型通常都是层的 堆叠,或者更通俗地说,是层组成的图。这些层由权重(weight)来参数化,权重是在训练过程中需要学习的参数。模型的知识(knowledge)保存在它的权重中,学习的过程就是为这些权重找到正确的值。
虽然深度学习只是机器学习的众多方法之一,但它与其他方法并不处于同等地位。深度学 习是突破性的成功。原因如下
在深度学习中,一切都是向量,即一切都是几何空间(geometric space)中的点(point)。
首先将模型输入(文本、图像等)和目标向量化(vectorize),即将其转换为初始输入向量空间和目标向量空间。深度学习模型的每一层都对通过它的数据做一个简单的几何变换。模型中的层链共同形成了一个非常复杂的几何变换,它可以分解为一系列简单的几何变换。这个复杂变换试图将输入空间映射到目标空间,每次映射一个点。这个变换由层的权重来参数化, 权重根据模型当前表现进行迭代更新。这种几何变换有一个关键性质,就是它必须是可微的 (differentiable),这样我们才能通过梯度下降来学习其参数。直观上来看,这意味着从输入到输出的几何变形必须是平滑且连续的,这是一个很重要的约束条件。
将这个复杂的几何变换应用于输入数据的过程,可以用三维的形式可视化——你可以想象 一个人试图将一个纸球展平,这个皱巴巴的纸球就是模型初始输入数据的流形。这个人对纸球做的每个动作都类似于某一层执行的简单几何变换。完整的展平动作系列就是整个模型所做的 复杂变换。深度学习模型就是用于解开高维数据复杂流形的数学机器。
这就是深度学习的神奇之处:将意义转换为向量,转换为几何空间,然后逐步学习将一个空间映射到另一个空间的复杂几何变换。你需要的只是维度足够大的空间,以便捕捉到原始数据中能够找到的所有关系。
整件事情完全取决于一个核心思想:意义来自于事物之间的成对关系(一门语言的单词之间,一张图像的像素之间等),而这些关系可以用距离函数来表示。但请注意,大脑是否通过几何空间来实现意义,这完全是另一个问题。从计算的角度来看,处理向量空间是很高效的,但也很容易想到用于智能的其他数据结构,特别是图。神经网络最初来自于使用图对意义进行编码这一思路,这也是它被命名为神经网络(neural network)的原因,相关的研究领域曾经被称为联结主义(connectionism)。如今仍在使用神经网络这一名称,纯粹是出于历史原因,这是一 个极具误导性的名称,因为它与神经或网络都没有关系,尤其是和大脑几乎没有任何关系。更合适的名称应该是分层表示学习(layered representations learning)或层级表示学习(hierarchical representations learning),甚至还可以叫深度可微模型(deep differentiable model)或链式几何变换(chained geometric transform),以强调其核心在于连续的几何空间操作。
我们已经拥有非常强大的工具,能够创建将任何输入空间映射到任何目标空间的模型,这 非常好,但机器学习工作流程的难点通常是设计并训练这种模型之前的工作(对于生产模型而言, 也包括设计和训练这种模型之后的工作)。理解问题领域从而能够确定想要预测什么、需要哪些 数据以及如何衡量成功,这些都是所有成功的机器学习应用的前提,而 Keras 和 TensorFlow 等 高级工具是无法帮你解决这些问题的。提醒一下,第 4 章介绍过典型的机器学习工作流程,下 面我们来快速回顾总结一下。
你应该熟悉以下三种网络架构:密集连接网络、卷积网络和循环网络。每种类型的网络都 针对于特定的输入模式,网络架构(密集网络、卷积网络、循环网络)中包含对数据结构的假设, 即搜索良好模型所在的假设空间。某种架构能否解决某个问题,这完全取决于数据结构与网络架构的假设之间的匹配度。
这些不同的网络类型组合起来,很容易实现更大的多模式网络,就像组合乐高积木一样。 某种程度上来说,深度学习的层就是信息处理的乐高积木。我们来快速看一下输入模式与适当 的网络架构之间的对应关系。
下面快速回顾一下每种网络架构的特点。
密集连接网络是 Dense 层的堆叠,它用于处理向量数据(向量批量)。这种网络假设输入特征中没有特定结构:之所以叫作密集连接,是因为 Dense 层的每个单元都和其他所有单元相连接。这种层试图映射任意两个输入特征之间的关系,它与二维卷积层不同,后者仅查看局部关系。
密集连接网络最常用于分类数据(比如输入特征是属性的列表),比如第 3 章的波士顿房价数据集。它还用于大多数网络最终分类或回归的阶段。例如,第 5 章介绍的卷积神经网络,最后通常是一两个 Dense 层,第 6 章的循环神经网络也是如此。
请记住:对于二分类问题(binary classification),层堆叠的最后一层是使用 sigmoid 激活且只有一个单元的 Dense 层,并使用 binary_crossentropy 作为损失。目标应该是 0 或 1。靠近0就是分类到0,靠近1就是分类到1,不需要softmax。
from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(32, activation='relu', input_shape=(num_input_features,)))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy')
对于单标签多分类问题(single-label categorical classification,每个样本只有一个类别,不会超过一个),层堆叠的最后一层是一个 Dense 层,它使用 softmax 激活,其单元个数等于类别个数。如果目标是 one-hot 编码的,那么使用 categorical_crossentropy 作为损失;如果目标是整数,那么使用 sparse_categorical_crossentropy 作为损失。
model = models.Sequential()
model.add(layers.Dense(32, activation='relu', input_shape=(num_input_features,)))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(num_classes, activation='softmax'))
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
对于多标签多分类问题(multilabel categorical classification,每个样本可以有多个类别), 层堆叠的最后一层是一个 Dense 层,它使用 sigmoid 激活,其单元个数等于类别个数,并使 用 binary_crossentropy 作为损失。目标应该是 k-hot 编码的。
model = models.Sequential()
model.add(layers.Dense(32, activation='relu', input_shape=(num_input_features,)))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(num_classes, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy')
对于连续值向量的回归(regression)问题,层堆叠的最后一层是一个不带激活 Dense 层, 其单元个数等于你要预测的值的个数(通常只有一个值,比如房价)。有几种损失可用于回归问题,最常见的是 mean_squared_error(均方误差,MSE)和 mean_absolute_error(平均 绝对误差,MAE)。
model = models.Sequential()
model.add(layers.Dense(32, activation='relu', input_shape=(num_input_features,)))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(num_values))
model.compile(optimizer='rmsprop', loss='mse')
卷积层能够查看空间局部模式,其方法是对输入张量的不同空间位置(图块)应用相同的 几何变换。这样得到的表示具有平移不变性,这使得卷积层能够高效利用数据,并且能够高度 模块化。这个想法适用于任何维度的空间,包括一维(序列)、二维(图像)、三维(立体数据)等。 你可以使用 Conv1D 层来处理序列(特别是文本,它对时间序列的效果并不好,因为时间序列 通常不满足平移不变的假设),使用 Conv2D 层来处理图像,使用 Conv3D 层来处理立体数据。
卷积神经网络或卷积网络是卷积层和最大池化层的堆叠。池化层可以对数据进行空间下采样, 这么做有两个目的:随着特征数量的增大,我们需要让特征图的尺寸保持在合理范围内;让后面的卷积层能够“看到”输入中更大的空间范围。卷积神经网络的最后通常是一个 Flatten 运算或全局池化层,将空间特征图转换为向量,然后再是 Dense 层,用于实现分类或回归。
注意,大部分(或者全部)普通卷积很可能不久后会被深度可分离卷积(depthwise separable convolution,SeparableConv2D 层)所替代,后者与前者等效,但速度更快、表示效率更高。 对于三维、二维和一维的输入来说都是如此。如果你从头开始构建一个新网络,那么一定要使用深度可分离卷积。SeparableConv2D 层可直接替代 Conv2D 层,得到一个更小、更快的网络, 在任务上的表现也更好。
一个常见的图像分类网络如下所示(本例是多分类)。
model = models.Sequential() model.add(layers.SeparableConv2D(32, 3, activation='relu', input_shape=(height, width, channels))) model.add(layers.SeparableConv2D(64, 3, activation='relu')) model.add(layers.MaxPooling2D(2)) model.add(layers.SeparableConv2D(64, 3, activation='relu')) model.add(layers.SeparableConv2D(128, 3, activation='relu')) model.add(layers.MaxPooling2D(2)) model.add(layers.SeparableConv2D(64, 3, activation='relu')) model.add(layers.SeparableConv2D(128, 3, activation='relu')) model.add(layers.GlobalAveragePooling2D()) model.add(layers.Dense(32, activation='relu')) model.add(layers.Dense(num_classes, activation='softmax')) model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
循环神经网络(RNN,recurrent neural network)的工作原理是,对输入序列每次处理一个 时间步,并且自始至终保存一个状态(state,这个状态通常是一个向量或一组向量,即状态几何空间中的点)。如果序列中的模式不具有时间平移不变性(比如时间序列数据,最近的过去比遥远的过去更加重要),那么应该优先使用循环神经网络,而不是一维卷积神经网络。
Keras 中有三种 RNN 层:SimpleRNN、GRU 和 LSTM。对于大多数实际用途,你应该使用 GRU 或 LSTM。两者中 LSTM 更加强大,计算代价也更高。你可以将 GRU 看作是一种更简单、计算代价更小的替代方法。
想要将多个 RNN 层逐个堆叠在一起,最后一层之前的每一层都应该返回输出的完整序列 (每个输入时间步都对应一个输出时间步)。如果你不再堆叠更多的 RNN 层,那么通常只返回最后一个输出,其中包含关于整个序列的信息。
下面是一个单层 RNN 层,用于向量序列的二分类。
model = models.Sequential()
model.add(layers.LSTM(32, input_shape=(num_timesteps, num_features)))
model.add(layers.Dense(num_classes, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy')
下面是 RNN 层的堆叠,用于向量序列的二分类。
model = models.Sequential()
model.add(layers.LSTM(32, return_sequences=True,
input_shape=(num_timesteps, num_features)))
model.add(layers.LSTM(32, return_sequences=True))
model.add(layers.LSTM(32))
model.add(layers.Dense(num_classes, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy')
你想要用深度学习来做什么?请记住,构建深度学习模型就像是玩乐高积木:将许多层组 合在一起,基本上可以在任意数据之间建立映射,前提是拥有合适的训练数据,同时这种映射 可以通过具有合理复杂度的连续几何变换来实现。可能性空间是无限的。本节将会用几个例子 来激发你的思考,思考除基本的分类和回归任务之外的可能性,这二者一直是机器学习最基本 的任务。
下面是我提到的应用领域,我将其按输入模式和输出模式进行了分类。请注意,其中不少 应用扩展了可能性的范围。虽然在所有这些任务上都可以训练一个模型,但在某些情况下,这 样的模型可能无法泛化到训练数据之外的数据。9.2 节和 9.3 节将会讨论未来可以如何突破这些局限。
将向量数据映射到向量数据
预测性医疗保健:将患者医疗记录映射到患者治疗效果的预测。
行为定向:将一组网站属性映射到用户在网站上所花费的时间数据。
产品质量控制:将与某件产品制成品相关的一组属性映射到产品明年会坏掉的概率。
将图像数据映射到向量数据
将时间序列数据映射为向量数据
将文本映射到文本
将图像映射到文本
将文本映射到图像
将图像映射到图像
将图像和文本映射到文本
将视频和文本映射到文本
几乎是一切皆有可能,但不完全是一切。下一节我们将会看到深度学习不能做什么。
对于深度学习可以实现的应用,其可能性空间几乎是无限的。但是,对于当前的深度学习技术,许多应用是完全无法实现的,即使拥有大量人工标注的数据也无法实现。比如说,你可以收集一个数据集,其中包含数十万条(甚至上百万条)由产品经理编写的软件产品功能的英文说明,还包含由一个工程师团队开发的满足这些要求的相应源代码。即使有了这些数据,你也无法训练一个读取产品说明就能生成相应代码库的深度学习模型。这只是众多例子中的一个。 一般来说,任何需要推理(比如编程或科学方法的应用)、长期规划和算法数据处理的东西,无论投入多少数据,深度学习模型都无法实现。即使是排序算法,用深度神经网络来学习也是非常困难的。
这是因为深度学习模型只是将一个向量空间映射到另一个向量空间的简单而又连续的几何变换链。它能做的只是将一个数据流形 X 映射到另一个流形 Y,前提是从 X 到 Y 存在可学习的 连续变换。深度学习模型可以被看作一种程序,但反过来说,大多数程序都不能被表示为深度学习模型。对于大多数任务而言,要么不存在相应的深度神经网络能够解决任务,要么即使存 在这样的网络,它也可能是不可学习的(learnable)。后一种情况的原因可能是相应的几何变换 过于复杂,也可能是没有合适的数据用于学习。
通过堆叠更多的层并使用更多训练数据来扩展当前的深度学习技术,只能在表面上缓解一些问题,无法解决更根本的问题,比如深度学习模型可以表示的内容非常有限,比如大多数你想要学习的程序都不能被表示为数据流形的连续几何变形。
当代人工智能有一个实实在在的风险,那就是人们误解了深度学习模型的作用,并高估了它们的能力。人类的一个基本特征就是我们的心智理论:我们倾向于将意图、信念和知识投射到身边的事物上。在石头上画一个笑脸,石头就突然变得“快乐”了——在我们的意识中。将人类的这个特征应用于深度学习,举个例子,如果我们能够大致成功训练一个模型来生成描述图像的说明文字,我们就会相信这个模型能够“理解”图像内容和它生成的说明文字。然后, 如果某张图像与训练数据中的那一类图像略有不同,并导致模型生成非常荒谬的说明文字,我们就会感到很惊讶(见图 9-1)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q6LHnuLG-1672461086929)(C:\Users\10555\AppData\Roaming\Typora\typora-user-images\image-20221228174510206.png)]
对抗样本尤其能够突出说明这一点。对抗样本是深度学习网络的输入样本,其目的在于欺 骗模型对它们进行错误归类。比如你已经知道,在输入空间中进行梯度上升,可以生成能够让 卷积神经网络某个过滤器激活最大化的输入,这正是第 5 章介绍的过滤器可视化技术的基本原 理,也是第 8 章 DeepDream 算法的基本原理。与此类似,通过梯度上升,你也可以对图像稍做 修改,使其能够将某一类别的类别预测最大化。将长臂猿的梯度添加到一张熊猫照片中,我们 可以让神经网络将这个熊猫归类为长臂猿(见图 9-2)。这既表明了这些模型的脆弱性,也表明 这些模型从输入到输出的映射与人类感知之间的深刻差异。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMwKZxwX-1672461086930)(C:\Users\10555\AppData\Roaming\Typora\typora-user-images\image-20221228174649150.png)]
简而言之,深度学习模型并不理解它们的输入,至少不是人类所说的理解。我们自己对图像、声音和语言的理解是基于我们作为人类的感觉运动体验。机器学习模型无法获得这些体验, 因此也就无法用与人类相似的方式来理解它们的输入。通过对输入模型的大量训练样本进行标记,我们可以让模型学会一个简单几何变换,这个变换在一组特定样本上将数据映射到人类概念, 但这种映射只是我们头脑中原始模型的简化。我们头脑中的原始模型是从我们作为具身主体的体验发展而来的。机器学习模型就像是镜子中的模糊图像(见图 9-3)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4vYbXJVS-1672461086930)(C:\Users\10555\AppData\Roaming\Typora\typora-user-images\image-20221228174824783.png)]
作为机器学习从业者,你一定要始终记住这一点,永远不要陷入这样一个陷阱,即相信神经网络能够理解它们所执行的任务——它们并不理解,至少不是用我们可以理解的方式。我们希望教神经网络学会某项任务,但它们是在一个不同的、更加狭窄的任务上进行训练,这个任务就是将训练输入逐点映射到训练目标。如果向神经网络展示与训练数据不一样的数据,它们可能会给出荒谬的结果。
深度学习模型从输入到输出的简单几何变形与人类思考和学习的方式之间存在根本性的区 别。区别不仅在于人类是从具身体验中自我学习,而不是通过观察显式的训练样例来学习。除 了学习过程不同,底层表示的性质也存在根本性的区别。
深度网络能够将即时刺激映射到即时反应(昆虫可能也是这样),但人类能做的比这远远 更多。对于现状、对于我们自己、对于其他人,我们都使用一个复杂的抽象模型,并可以利用 这些模型来预测各种可能的未来并执行长期规划。我们可以将已知的概念融合在一起,来表示 之前从未体验过的事物,比如绘制一匹穿着牛仔裤的马,或者想象我们如果中了彩票会做什么。 这种处理假想情况的能力,将我们的心智模型空间扩展到远远超出我们能够直接体验的范围, 让我们能够进行抽象和推理,这种能力可以说是人类认知的决定性特征。我将其称为极端泛化, 即只用很少的数据,甚至没有新数据,就可以适应从未体验过的新情况的能力。
这与深度网络的做法形成了鲜明对比,我将后者称为局部泛化,如图 9-4 所示。深度网络执行从输入到输出的映射,如果新的输入与网络训练时所见到的输入稍有不同,这种映射就会 立刻变得没有意义。比如,思考这样一个问题,想要学习让火箭登陆月球的正确的发射参数。 如果使用深度网络来完成这个任务,并用监督学习或强化学习来训练网络,那么我们需要输入 上千次、甚至上百万次发射试验,也就是说,我们需要为它提供输入空间的密集采样,以便它 能够学到从输入空间到输出空间的可靠映射。相比之下,我们人类可以利用抽象能力提出物理 模型(火箭科学),并且只用一次或几次试验就能得到让火箭登陆月球的精确解决方案。同样, 如果你开发一个能够控制人体的深度网络,并且希望它学会在城市里安全行走,不会被汽车撞上, 那么这个网络不得不在各种场景中死亡数千次,才能推断出汽车是危险的,并做出适当的躲避 行为。将这个网络放到一个新城市,它将不得不重新学习已知的大部分知识。但人类不需要死 亡就可以学会安全行为,这也要归功于我们对假想情景进行抽象建模的能力。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H2DJSCsp-1672461086930)(C:\Users\10555\AppData\Roaming\Typora\typora-user-images\image-20221228222105471.png)]
总之,尽管我们在机器感知方面取得了进展,但离达到人类水平的人工智能仍然很遥远。 我们的模型只能进行局部泛化,只能适应与过去数据类似的新情况,而人类的认知能够进行极 端泛化,能够快速适应全新情况并为长期的未来情况做出规划。
我们应该记住以下内容:到目前为止,深度学习唯一的真正成功之处就是,给定大量的人 工标注数据,它能够使用连续的几何变换将空间 X 映射到空间 Y。做好这一点已经可以引起基 本上所有行业的变革,但离达到人类水平的人工智能还有很长的路要走。
想要突破我们这里所讨论的一些局限性,并创造出能够与人类大脑匹敌的人工智能,我们 需要抛弃简单的从输入到输出的映射,转而研究推理和抽象。对各种情况和概念进行抽象建模, 一个合适的基础可能是计算机程序。我们之前说过,机器学习模型可以被定义为可学习的程序。
目前我们能学习的程序只是所有程序一个狭小的特定子集。但如果我们能够以一种模块化的、 可重复使用的方式来学习任何程序呢?下一节将会介绍深度学习的未来之路可能是什么样的。
本节的内容更加带有推测性,其目的在于为希望加入研究项目或开始独立研究的人开拓视 野。根据已知的深度网络的工作原理、局限性及其研究现状,我们能否预测未来一段时间内事 情的发展趋势?下面是一些纯个人想法。注意,我并没有水晶球,所以很多预测可能都无法实现。 之所以分享这些预测,并不是因为我希望它们在未来被证明是完全正确的,而是因为这些预测 很有趣,而且现在就可以付诸实践。
从较高层面来看,我认为下面这些重要方向很有前途。
与通用的计算机程序更加接近的模型,它建立在比当前可微层要更加丰富的原语之上。 这也是我们实现推理和抽象的方法,当前模型的致命弱点正是缺少推理和抽象。
使上一点成为可能的新学习形式,这种学习形式能够让模型抛弃可微变换。
需要更少人类工程师参与的模型。不停地调节模型不应该是我们的工作。
更好地、系统性地重复使用之前学到的特征和架构,比如使用可复用和模块化子程序的元学习系统。
此外请注意,到目前为止,监督学习已成为深度学习的基本内容,这些思考并不仅针对于监督学习,而是适用于任何形式的机器学习,包括无监督学习、自监督学习和强化学习。标签来自哪里或训练循环是什么样子,这些都不重要,机器学习这些不同的分支是同一概念的不同方面。我们来具体看一下。
正如上一节所述,我们可以预测机器学习领域的一个必要转型是,抛弃只能进行纯模式识别并且只能实现局部泛化的模型,转而研究能够进行抽象和推理并且能够实现极端泛化的模型。 目前的人工智能程序能够进行基本形式的推理,它们都是由人类程序员硬编码的,如依赖于搜索算法、图操作和形式逻辑的软件。比如 DeepMind 的 AlphaGo,它所展示的大部分智能都是由专业程序员设计和硬编码的(如蒙特卡洛树搜索),从数据中进行学习只发生在专门的子模块中 (价值网络与策略网络)。但在未来,这样的人工智能系统可以完全通过学习得到,不需要人类参与其中。
如何才能实现这一未来?我们来考虑一个众所周知的网络类型:循环神经网络(RNN)。 值得注意的是,RNN 的局限性比前馈网络要略小。这是因为 RNN 不仅仅是几何变换,它是在 for 循环内不断重复的几何变换。时序 for 循环本身就是由开发人员硬编码的,它是网络的内 置假设。当然,RNN 在能够表示的内容方面仍然非常有限,这主要是因为它执行的每一步都是 一个可微的几何变换,从一步到另一步都是通过连续几何空间中的点(状态向量)来携带信息。 现在想象一个神经网络,它用一种类似编程原语的方式得到了增强,但网络并不是单一硬编码 的 for 循环,具有硬编码的几何记忆,而是包含大量的编程原语,模型可以自由地操作这些原语来扩展其处理功能,比如 if 分支、while 语句、变量创建、长期记忆的磁盘存储、排序运算符、 高级数据结构(如列表、图和散列表)等。这种网络能够表示的程序空间要远远大于当前深度 学习模型的表示范围,其中某些程序还可以实现优秀的泛化能力。
一方面,我们将不再使用硬编码的算法智能(手工软件),另一方面,我们也不再使用学到 的几何智能(深度学习)。相反,我们要将正式的算法模块和几何模块融合在一起,前者可以提 供推理和抽象能力,后者可以提供非正式的直觉与模式识别能力。整个系统的学习过程只需要 很少人参与,甚至不需要人参与。
我认为人工智能有一个与此相关的子领域即将迎来春天,它就是程序合成,特别是神经程 序合成。程序合成是指利用搜索算法(在遗传编程中也可能是遗传搜索)来探索可能程序的巨 大空间,从而自动生成简单的程序。如果找到了满足规格要求的程序(规格要求通常由一组输 入 / 输出对提供),那么搜索就会停止。这很容易让人联想到机器学习:给定输入 / 输出对作为 训练数据,我们找到一个程序,它能够将输入映射到输出,还能够泛化到新的输入。区别在于, 我们通过离散的搜索过程来生成源代码,而不是在硬编码的程序(神经网络)中学习参数值。
我非常期待未来几年人们对这个子领域重新燃起兴趣。我特别期待在深度学习和程序合成 之间出现一个交叉子领域,这一子领域不是用通用语言来生成程序,而是生成被大量丰富的算 法原语(如 for 循环等)所增强的神经网络(几何数据处理流程),见图 9-5。与直接生成源代 码相比,这种方法应该更加容易处理,也更加有用,它将大大扩展机器学习所能解决问题的范 围(即给定适当的训练数据,我们能够自动生成的程序空间的范围)。当代 RNN 可以看作这种 算法 - 几何混合模型的鼻祖。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Iq0eATok-1672461086931)(C:\Users\10555\AppData\Roaming\Typora\typora-user-images\image-20221228223913416.png)]
如果机器学习模型变得更像程序,那么通常就不再是可微的了。这些程序仍然使用连续的 几何层作为子程序,这些子程序是可微的,但整个模型是不可微的。因此,使用反向传播在固 定的硬编码的网络中调节权重值,可能不是未来训练模型的首选方法,至少不会只用这种方法。 我们需要找到能够有效地训练不可微系统的方法。目前的方法包括遗传算法、进化策略、某些 强化学习方法和交替方向乘子法(ADMM)。当然,梯度下降也不会被淘汰,梯度信息对于可微 的参数化函数的最优化总是很有用的。但我们的模型会变得越来越不满足于可微的参数化函数, 因此模型的自动开发(即机器学习中的学习)需要的也不仅仅是反向传播。
此外,反向传播是端到端的,这对于学习良好的链式变换是很有用的,但它没有充分利用 深度网络的模块化,所以计算效率很低。为了提高效率,有一个通用的策略:引入模块化和层 次结构。因此,我们可以引入解耦的训练模块以及训练模块之间的同步机制,并用一种层次化 的方式来组织,从而使反向传播更加高效。DeepMind 最近关于合成梯度的工作就稍稍反映了 这种策略。我希望在不远的将来,人们在这一方向上能走得更远。我可以设想的一个未来就是, 模型在全局上是不可微的(但部分是可微的),我们使用一种有效的搜索过程(不使用梯度)来 训练(生长)模型,而可微的部分则利用更高效版本的反向传播得到的梯度进行训练,其训练 速度更快。
未来,模型架构将是通过学习得到的,而不是由工程师人为设计的。学习架构与使用更丰 富的原语、类似程序的机器学习模型是密切相关的。
目前,深度学习工程师的大部分工作都是用 Python 脚本整理数据,然后花很长时间调节深度网络的架构和超参数,以得到一个有效模型。如果这名工程师有野心,他可能还想得到一个 最先进的模型。毫无疑问,这种方法肯定不是最佳的,但人工智能可以提供帮助。只是数据整 理很难实现自动化,因为这一步通常需要领域知识,还需要对工程师想要实现的目标有一个清晰、 深刻的理解。但是,超参数调节是一个简单的搜索过程,我们也知道在这种情况下工程师想要 实现的目标,它由所调节网络的损失函数来定义。建立基本的自动化机器学习(AutoML)系统 已经是很常见的做法。多年前我甚至也建立过自己的 AutoML 系统,用来赢得 Kaggle 竞赛。
在最基本的层面上,这样的自动化机器学习系统可以调节堆叠的层数、层的顺序以及每一 层中单元或过滤器的个数。这通常使用 Hyperopt 等库来实现,我们在第 7 章介绍过。但我们还可以更有野心,尝试从头开始学习合适的架构,让约束尽可能少,比如可以通过强化学习或遗传算法来实现。
另一个重要的自动化机器学习方向是联合学习模型架构和模型权重。我们每次尝试一个略有不同的架构,都要从头训练一个新模型,这种方法是极其低效的,因此,真正强大的自动化机器学习系统,在训练数据上进行反向传播来调节模型特征的同时,还能够不断调节其模型架构。 在我写到本节内容时,这种方法已经开始出现了。
这种方法出现之后,机器学习工程师的工作并不会消失;相反,工程师会做更多具有创造 价值的工作。他们开始投入更多精力来设计可以真实反映业务目标的复杂的损失函数,还可以深入理解模型如何影响它们所部署的数字生态系统(比如,消费模型预测并生成模型训练数据 的用户),目前只有那些最大的公司才有精力考虑这些问题。
如果模型变得更加复杂,并且构建于更加丰富的算法原语之上,对于这种增加的复杂度, 需要在不同的任务之间实现更多的复用,而不是每次面对一个新任务或新数据集时,都从头开始训练一个新模型。许多数据集包含的信息都不足以让我们从头开发一个复杂的新模型,利用以往数据集中包含的信息是很必要的(就像你每次打开一本新书时,也不会从头开始学习英语—— 那是不可能的)。每开始一个新任务都从头训练模型也是非常低效的,因为当前任务与之前遇到 的任务有很多重复之处。——新的数据应该在以前训练好的模型上继续学习,而不是从头学习。
近年来有一个反复出现的观察结果值得注意:训练同一个模型同时完成几个几乎没有联系的 任务,这样得到的模型在每个任务上的效果都更好。例如,训练同一个神经机器翻译模型来实现 英语到德语的翻译和法语到意大利语的翻译,这样得到的模型在两组语言上的表现都变得更好。 同样,联合训练一个图像分类模型和一个图像分割模型,二者共享相同的卷积基,这样得到的模型在两个任务上的表现都变得更好。这是很符合直觉的:看似无关的任务之间总是存在一些信息重叠,与仅在特定任务上训练的模型相比,联合模型可以获取关于每项任务的更多信息。——一个模型两个任务。
目前,对于不同任务之间的模型复用,我们使用执行通用功能(比如视觉特征提取)的模 型的预训练权重。第 5 章介绍过这种用法。未来我希望这种方法的更一般的版本能够更加常见: 我们不仅重复使用之前学到的特征(子模型权重),还会重复使用模型架构和训练过程。随着模型变得越来越像程序,我们将开始重复使用程序的子程序(program subroutine),就像重复使用人类编程语言中的函数和类那样。——将模型架构及其参数当作一个函数来用。甚至可以通过搜索的方法将这些模型进行遍历找到那个最合适得模型。
想想如今的软件开发过程:每当工程师解决了一个具体问题(比如 Python 中的 HTTP 查询), 他们就会将其打包成一个抽象的、可复用的库。日后面临类似问题的工程师可以搜索现有的库, 然后下载,并在自己的项目中使用。同样,在未来,元学习系统能够在高级可复用模块的全局库中筛选,从而组合成新程序。如果系统发现自己对几个不同的任务都开发出了类似的子程序, 那么它可以对这个子程序提出一个抽象的、可复用的版本,并将其存储在全局库中(见图 9-6)。 这一过程可以实现抽象,抽象是实现极端泛化的必要组件。如果一个子程序在不同任务和不同领域中都很有用,我们可以说它对解决问题的某些方面进行了抽象化(abstract)。这个抽象的定义与软件工程中的抽象概念类似。这些子程序可能是几何子程序(带有预训练表示的深度学习模块),也可能是算法子程序(更接近于当代软件工程师所操作的库)。模块化子程序,复用到不同领域。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6GKc3fbc-1672461086931)(C:\Users\10555\AppData\Roaming\Typora\typora-user-images\image-20221228225721553.png)]
简而言之,以下是我对机器学习的长期愿景。
作为最后的临别语,我希望给你一些建议,让你在翻完本书最后一页之后知道如何继续学 习并更新知识和技能。正如我们今天所知道的,现代深度学习领域只有几年的历史,尽管它有 一个很长、很缓慢的史前历史并长达数十年。自 2013 年以来,随着资金来源和研究人数呈指数 式增长,整个领域目前正在以狂热的步伐前进。你在本书学到的知识不会永不过时,这些知识 也不是你职业生涯的剩余时间所需要掌握的全部内容。
幸运的是,网上有大量免费的在线资源,你可以用来了解最新进展,还可以拓展视野。下 面介绍其中一些资源。
想要获得现实世界的经验,一种有效的方法是参加 Kaggle 上的机器学习竞赛。唯一的真正 学习方式就是通过实践与实际写代码来学习,这也是本书的哲学,而 Kaggle 竞赛就是这一哲学 的自然延续。在 Kaggle 上,你会发现一系列不断更新的数据科学竞赛,其中许多都涉及深度学习。一些公司想要在最具挑战性的机器学习问题上获得新颖的解决方案,就举办了这些竞赛,还为 顶尖参赛者提供了相当丰厚的奖金。
大部分竞赛的获胜者都使用 XGBoost 库(用于浅层机器学习)或 Keras(用于深度学习)。 所以你非常适合参加这些竞赛!通过参加一些竞赛,也可能是作为团队的一员,你将会更加熟 悉本书所介绍的一些高级最佳实践的用法,特别是超参数优化、避免验证集过拟合与模型集成。
深度学习研究与某些其他科学领域不同,它是完全公开化的。论文一旦定稿,就会公开发布供 人们自由获取,而且许多相关软件也都是开源的。arXiv(读作 archive,其中 X 代表希腊字母 χ) 是物理、数学和计算机科学研究论文的开放获取预印本服务器。arXiv 已经成为了解机器学习 和深度学习最新进展的重要方法。大多数深度学习研究人员在完成他们的论文后会立刻上传到 arXiv 上。这样他们可以插一面旗子,无需等待会议接收(这需要几个月)就可以宣称某项研究 成果的所有权,鉴于该领域研究速度很快、竞争很激烈,这种做法是很有必要的。它还可以让这 一领域快速向前发展,对于所有新的研究成果,所有人都可以立刻看到,并可以在其基础上扩展。
一个要命的缺点是,arXiv 上每天发布大量新论文,全部略读一遍也是不可能的。这些论文没有经过同行评议,想要筛选出重要且质量很高的论文是很困难的。
在噪声中找到信号很困难,而且正在变得越来越难。目前,这个问题还没有好的解决方案。 但有一些工具可以提供帮助:一个名叫 arXiv Sanity Preserver 的辅助网站可以作为新论文的推荐 引擎,还可以帮你在深度学习某个狭窄的垂直领域中跟踪最新进展。此外,你还可以使用谷歌学术(Google Scholar)来跟踪你最喜欢的作者的出版物。
,无需等待会议接收(这需要几个月)就可以宣称某项研究 成果的所有权,鉴于该领域研究速度很快、竞争很激烈,这种做法是很有必要的。它还可以让这 一领域快速向前发展,对于所有新的研究成果,所有人都可以立刻看到,并可以在其基础上扩展。
一个要命的缺点是,arXiv 上每天发布大量新论文,全部略读一遍也是不可能的。这些论文没有经过同行评议,想要筛选出重要且质量很高的论文是很困难的。
在噪声中找到信号很困难,而且正在变得越来越难。目前,这个问题还没有好的解决方案。 但有一些工具可以提供帮助:一个名叫 arXiv Sanity Preserver 的辅助网站可以作为新论文的推荐 引擎,还可以帮你在深度学习某个狭窄的垂直领域中跟踪最新进展。此外,你还可以使用谷歌学术(Google Scholar)来跟踪你最喜欢的作者的出版物。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。