【深度学习】读书笔记

深度学习作为人工智能时代最重要的技术之一,值得每一个 AI 从业者了解和学习,这里是我的读书笔记。

注:本笔记来源于这里


更新历史

  • 2017.05.29: 完成阅读
  • 2017.05.27: 开始阅读

数学符号

数和数组

  • $\alpha$ 标量(整数或实数)
  • $\mathbf{\alpha}$ 向量
  • $A$ 矩阵
  • $\mathbf{A}$ 张量
  • $I_n$ n 行 n 列的单位矩阵
  • $I$ 维度蕴含于上下文的单位矩阵
  • $e^{(i)}$ 标准基向量 [0,...,0,1,0,...,0],其中索引 i 处值为 1
  • $diag(\mathbf{\alpha})$ 对角方阵,其中对角元素由 $\mathbf{\alpha}$ 给定
  • $\mathrm{a}$ 标量随机变量
  • $\mathbf{a}$ 向量随机变量
  • $\mathrm{A}$ 矩阵随机变量

集合和图

  • $\mathbb{A}$ 集合
  • $\mathbb{R}$ 实数集
  • ${0, 1}$ 包含 0 和 1 的集合
  • ${0,1,\dots ,n}$ 包含 0 和 n 之间的所有整数的集合
  • $[a,b]$ 包含 a 和 b 的实数区间
  • $(a,b]$ 不包含 a 但包含 b 的实数区间
  • $\mathbb{A} \setminus \mathbb{B}$ 差集,即其元素包含于 $\mathbb{A}$ 但不包含于 $\mathbb{B}$
  • $\zeta$ 图
  • $Pa_\zeta(x_i )$ 图 $\zeta$ 中的父节点

前言

人工智能的真正挑战在于解决那些对人来说很容易执行但很难形式化描述的任务,人类往往可以凭借直觉轻易解决。

抽象和形式化的任务对人类而言是最困难的脑力任务之一,但对计算机而言却属于最容易的。一个人的日常生活需要关于世界的巨量知识。很多这方面的知识是主观的、直观的,因此很难通过形式化的方式表达清除。计算机需要获取同样的知识才能表现出智能。人工智能的一个关键挑战就是如何将这些非形式化的知识传达给计算机。

依靠硬编码的知识体系面对的困难表明,AI 系统需要具备自己获取知识的能力,即从原始数据中提取模式的能力,这种能力被称为机器学习。

在整个计算机科学乃至日常生活中,对表示的依赖都是一个普遍现象。在计算机科学中,如果数据集合被精巧地结构化并被智能地索引,那么诸如搜索之类的操作的处理速度就可以成指数级地加快。

许多人工智能任务都可以通过以下方式解决:先提取一个合适的特征集,然后将这些特征提供给简单的机器学习算法。然而,对于许多任务来说,我们很难知道应该提取哪些特征。

解决这个问题的途径之一是使用机器学习来发掘表示本身,而不仅仅把表示映射到输出,这种方法我们称为表示学习(representation learning)。

表示学习算法的典型例子是自编码器(autoencoder)。自编码器由一个编码器(encoder)和一个解码器(decoder)函数组合而成。编码器函数将输入数据转换为一种不同的表示,而解码器函数则将这个新的表示转换到原来的形式。我么期望当输入数据经过编码器和解码器之后尽可能多地保留信息,同时希望新的表示有各种号的特性,这也是自编码器的训练目标。为了实现不同的特性,我们可以设计不同形式的自编码器。

当设计特征或设计用于学习特征的算法时,我们的目标通常是分离出能解释观察数据的变差因素(factors of variation)。在许多现实的人工智能应用中,困难主要源于多个变差因素同时影响着我们能够观察到的每一个数据。

深度学习(deep learning)通过其他较简单的表示来表达复杂表示,解决了表示学习中的核心问题。

联结主义的中心思想是,当网络将大量简单的计算单元连接在一起时可以实现智能行为。这种见解同样适用于生物神经系统中的神经元,因为它和计算模型中隐藏单元起着类似的作用。

联结主义潮流的另一个重要成就是反向传播在训练具有内部表示的深度神经网络中的成功使用以及反向传播算法的普及。

概率与信息论

概率论是用于表示不确定性声明(statement)的数学框架。它不仅提供了量化不确定性的方法,也提供了用于导出新的不确定性声明的公里。在人工智能领域,概率论主要有两种用途。首先,概率法则告诉我们 AI 系统如何推理,据此我们设计一些算法来计算或者估算由概率论导出的表达式。其次,我们可以用概率和统计从理论上分析我们提出的 AI 系统的行为。

概率论使我们能够作出不确定的声明以及在不确定性存在的情况下进行推理,而信息论使我们能够量化概率分布中的不确定性总量。

如果我们对于同一个随机变量 x 有两个单独的概率分布 P(x) 和 Q(x),我们可以使用KL 散度(Kullback-Leibler(KL) divergence) 来衡量这两个分布的差异。KL 散度有很多有用的性质,最重要的是它是非负的。KL 散度为 0 当且仅当 P 和 Q 在离散型变量的情况下是相同的分布,或者在连续型变量的情况下是『几乎处处』相同的。

数值计算

连续数学在数字计算机上的根本困难是,我们需要通过有限数量的位模式来表示无限多的实数。这意味着我们在计算机中表示实数时,几乎总会引入一些近似误差。在许多情况下,这仅仅是舍入误差。舍入误差会导致一些问题,特别是当许多操作复合时,即使是理论上可行的算法,如果在设计时没有考虑最小化舍入误差的积累,在实践时也可能会导致算法失效。

一种极具毁灭性的舍入误差是下溢(underflow)。当接近零的数被四舍五入为零时发生下溢。许多函数在其参数为零而不是一个很小的正数时才会表现出质的不同。另一个极具破坏力的数值错误形式是上溢(overflow)。

必须对上溢和下溢进行数值稳定的一个例子是 softmax 函数(softmax function)

基于梯度的优化方法

大多数深度学习算法都涉及某种形式的优化。我们把要最小化或最大化的函数称为目标函数(objective function)或准则(criterion)。当我们对其进行最小化时,我们也把它称为代价函数(cost function)、损失函数(loss function)或误差函数(error function)

KKT 方法。这部分数学,如果不想深究,也不需要过分在意

机器学习基础

机器学习本质上属于应用统计学,更多地关注于如何用计算机统计地估计复杂函数,不太关注为这些函数提供置信区间。

促使深度学习发展的挑战

维数灾难

当数据的维数很高时,很多机器学习问题变得相当困难。这种现象被称为维数灾难(curse of dimensionality)。特别值得注意的是,一组变量不同的可能配置数量会随着变量数目的增加贰指数级增长。

局部不变性和平滑正则化

深度前馈网络

深度前馈网络(deep feedforward network),也叫做前馈神经网络(feedforward neural network)或者多层感知机(multilayer perceptron, MLP),是典型的深度学习模型。前馈神经网络的目标是近似某个函数 $f^$。例如,对于分类器,$y=f^(\mathbf{x})$ 将输入 $\mathbf{x}$ 映射到一个类别 y。前馈网络定义了一个映射 $y=f(\mathbf{x};\theta)$,并且学习参数 $\theta$ 的值,使它能够得到最佳的函数近似。

这种模型被称为前向(feedforward)的,是因为信息留过 $\mathbf{x}$ 的函数,刘静用于定义 $f$ 的中间计算过程,最终到达输出 $y$。在模型的输出和模型本身之间没有反馈(feedback)连接。当前馈神经网络被扩展成包含反馈连接时,它们被称为循环神经网络(recurrent neural network)。

前馈神经网络被称作网络(network)是因为它们通常用许多不同函数复合起来一起表示。该模型与一个有向无环图相关联,而图描述了函数是如何复合在一起的。

网络中的每个隐藏层通常都是向量值的。这些隐藏层的维数决定了模型的宽度(width)。向量的每个元素都可以被视为起到类似一个神经元的做用。除了将层想象成向量到向量的单个函数,我们也可以把层想象成由许多并行操作的单元(unit)组成,每个单元表示一个向量到标量的函数。每个单元在某种意义上类似一个神经元,它接收的输入来源于许多其他的单元,并计算它自己的激活值。

深度学习中的正则化

机器学习中的一个核心问题是设计不仅在训练数据上表现好,并且能在新输入上泛化好的算法。在机器学习中,许多策略显式地被设计为减少测试误差(可能会以增大训练误差为代价),这些策略被统称为正则化。事实上,开发更有效的正则化策略已成为本领域的主要研究工作之一。

目前为止,最流行和广泛使用的参数共享出现在应用于计算机视觉的卷积神经网络(CNN)中。自然图像有许多统计属性是对转换不变的。相同的特征(具有相同权重的隐藏单元)在输入的不同位置上计算获得。参数共享显著降低了 CNN 模型的参数数量,并显著提高了网络的大小贰不需要相应地增加训练数据。它仍然是将领域知识有效地整合到网络架构的最佳范例之一。

Bagging(bootstrap aggregating)是通过结合几个模型降低泛化误差的技术。

Dropout(Dropout)提供了正则化一大类模型的方法,计算方便但功能强大。在第一种近似下,Dropout 可以被认为是集成大量深层神经网络的实用 Bagging 方法。Bagging 涉及训练多个模型,并在每个测试样本上评估多个模型。

具体而言,Dropout 训练的集成包括所有从基础网络除去与非输出单元后形成的子网络。在 Dropout 的情况下,所有模型共享参数,其中每个模型继承父神经网络参数的不同子集。参数共享使得在有限可用的内存下表示指数级数量的模型变得可能。在 Bagging 的情况下,每一个模型在其相应训练集上训练到收敛。在 Dropout 情况下,通常大部分模型都没有显式地被训练,因为通常父神经网络会很大,以至于到宇宙毁灭都不可能采样完所有的子网络。取而代之的是,在单个步骤中我们训练一小部分的子网络,参数共享会使得剩余的子网络也能有好的参数设定。

只有极少的训练样本可用时,Dropout 不会很有效。一个关于 Dropout 的重要见解是,通过随机行为训练网络并平均多个随机决定进行预测,实现了一种参数共享的 Bagging 形式。Dropout 不仅仅是训练一个 Bagging 的集成模型,并且是共享隐藏单元的继承模型。这意味着无论其他隐藏单元是否在模型中,每个隐藏单元都必须能够表现良好。隐藏单元必须准备好进行模型之间的交换和互换(有性生殖涉及到两个不同生物体之间交换基因,进化产生的压力使得基因不仅是良好的而且要准备好不同有机体之间的交换。这样的基因和这些特点对环境的变化是非常稳健的,因为它们一定会正确适应任何一个有机体或模型不寻常的特性)。因此 Dropout 正则化每个隐藏单元不仅是一个很好的特征,更要在许多情况下是良好的特征。

Dropout 强大的大部分原因来自施加到隐藏单元的掩码噪声,了解这一事实是重要的。这可以看作是对输入内容的信息高度智能化、自适应破坏的一种形式,而不是对输入原始值的破坏。

深度模型中的优化

随机梯度下降(SGD)及其变种很可能是一般机器学习中应用最多的优化算法,特别是在深度学习中。按照数据生成分布抽取 m 个小批量(独立同分布的)样本,通过计算它们梯度均值,我们可以得到梯度的无偏估计。SGD 算法中的一个关键参数是学习率。

虽然 SGD 仍然是非常受欢迎的优化方法,但其学习过程有时会很慢。动量(momentum)方法可以加速学习,特别是处理高曲率、小但一致的梯度,或是带噪声的梯度。

自适应学习率算法

AdaGrad

AdaGrad 算法独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平方值综合的平方根。

RMSProp

RMSProp 算法修改 AdaGrad 以在非凸设定下效果更好,改变梯度积累为指数加权的移动平均。经验上,RMSProp 已被证明是一种有效且实用的深度神经网络优化算法。目前它是深度学习从业者经常采用的优化方法之一。

Adam

Adam 是另一种学习率自适应优化算法。Adam 通常被认为对超参数的选择相当鲁棒,尽管学习率有时需要从建议的默认修改。

卷积网络

卷积网络(convolutional network),也叫做卷积神经网络(convolutional neural network, CNN),是一种专门用来处理具有类似网格结构的数据的神经网络。例如时间序列数据(可以认为是在时间轴上有规律采样形成的一维网格)和图像数据(可以看作是二维的像素网格)。

卷积运算通过三个重要的思想来帮助改进机器学习系统:稀疏交互(sparse interactions)、参数共享(parameter sharing)、等变表示(equivariant representations)。

池化函数使用某一位置的相邻输出的总体统计特征来代替网络在该位置的输出。例如最大池化(max pooling)函数给出相邻矩形区域内的最大值。其他常用的池化函数包括相邻矩形区域内的平均值、$L^2$范数以及基于据中心像素距离的加权平均函数。

不管采用什么样的池化函数,当输入作出少量平移时,池化能够帮助输入的表示近似不变(invariant)。因为池化综合了全部邻居的反馈,这使得池化单元少于探测单元成为可能,我们可以通过综合池化区域的 k 个像素的统计特征而不是单个像素来实现。

在很多任务中,池化对于处理不同大小的输入具有重要做用。例如我们想对不同大小的图像进行分类时,分类层的输入必须是固定的大小,而这通常通过调整池化区域的偏置大小来实现。

把卷积神经网络当作一个具有无限强先验的全连接网络来实现会导致极大的计算浪费。但把卷积神经网络想成具有无限强先验的全连接网络可以帮助我们更好地洞察卷积神经网络是如何工作的。

序列建模:循环和递归网络

循环神经网络(recurrent neural network) 或 RNN 是一类用于处理序列数据的神经网络。

大多数 RNN 中的计算可以分解成三块参数及其相关的变换:

  1. 从输入到隐藏状态
  2. 从前一隐藏状态到下一隐藏状态,以及
  3. 从隐藏状态到输出

实践方法论

要成功地使用深度学习技术,仅仅知道存在哪些算法和解释他们为何有效的原理是不够的。一个优秀的机器学习实践者还需要知道如何针对具体应用挑选一个合适的算法以及如何监控,并根据实验反馈改进机器学习系统。在机器学习系统的日常开发中,实践者需要决定是否收集更多的数据、增加或减少模型容量、添加或删除正则化项、改进模型的优化、改进模型的近似推断或调试模型的软件实现。尝试这些操作都需要大量时间,因此确定正确做法,而不盲目猜测尤为重要。

我们建议参考以下几个实践设计流程:

  • 确定目标 - 使用什么样的误差度量,并为此误差度量指定目标值。这些目标和误差度量取决于该应用旨在解决的问题
  • 尽快建立一个端到端的工作流程,包括估计合适的性能度量
  • 搭建系统,并确定性能瓶颈。检查哪个部分的性能差于预期,以及是否是因为过拟合、欠拟合,或者数据或软件缺陷造成的
  • 根据具体观察反复地进行增量式的改动,如收集新数据、调整超参数或改进算法

性能度量

对于大多数应用而言,不可能实现绝对零误差。即使你有无限的训练数据,并且恢复了真正的概率分布,贝叶斯误差仍定义了能达到的最小错误率。这是因为输入特征可能无法包含输出变量的完整信息,或是因为系统可能本质上是随机的。

在现实世界中,一个应用的错误率有必要是安全的、具有成本效益的或吸引消费者的。一旦你确定了想要达到的错误率,那么你的设计将由如何达到这个错误率来指导。

决定是否收集更多数据

在建立第一个端到端的系统后,就可以度量算法性能并决定如何改进算法。许多机器学习新手都忍不住尝试很多不同的算法。然而,收集更多的数据往往比改进学习算法要有用得多。

怎样判断是否要收集更多的数据?首先,确定训练集上的性能是否可接受。如果模型在训练集上的性能就很差,学习算法都不能在训练集上学习出良好的模型,那么就没必要收集更多的数据。反之,可以尝试增加更多的网络层或每层增加更多的隐藏单元,以增加模型的规模。此外,也可以调整学习率等超参数的措施来改进学习算法。如果更大的模型和仔细调试的优化算法效果不佳,那么问题可能源自训练数据的质量。数据可能含太多噪声,或是可能不包含预测输出所需的正确输入。这意味着我们需要重新开始,收集更干净的数据或是收集特征更丰富的数据集。

如果训练集上的性能是可接受的,那么我们开始度量测试集上的性能。如果测试集上的性能也是可以接受的,那么就顺利完成了。这时主要的考虑是收集更多数据的代价和可行性,其他方法降低误差的代价和可行性,和增加数据数量能否显著提升测试集性能。

调试策略

当一个机器学习系统效果不好时,通常很难判断效果不好的原因是算法本身,还是算法实现错误。由于各种原因,机器学习系统很难调试

应用

大规模深度学习

深度学习的基本思想基于联结主义:尽管机器学习模型中单个生物性的神经元或者说是单个特征不是智能的,但是大量的神经元或者特征作用在一起往往能够表现出智能。由于规模的大小对于神经网络来说至关重要,因此深度学习需要高性能的硬件设施和软件实现。

计算机视觉

一直以来,计算机视觉就是深度学习应用中几个最活跃的研究方向之一。因为视觉是一个对人类以及许多动物毫不费力,但对计算机却充满挑战的任务。

预处理

由于原始输入往往已深度学习架构难以表示的形式出现,许多应用领域需要复杂精细的预处理。计算机视觉通常只需要相对少的这种预处理。图像应该被标准化,从而使得它们的像素都在相同并且合理的范围内,比如 [0,1] 或者 [-1,1]。将 [0,1] 中的图像与 [0,255] 中的图像混合通常会导致失败。将图像格式化为相同比例严格上说是唯一一种必要的预处理。许多计算机视觉框架需要标准尺寸的图像,因此必须裁剪或缩放图像以适应该尺寸。

对比度归一化

在许多任务中,对比度是能够安全移除的最为明显的变化源之一。简单地说,对比度指的是图像中亮像素和暗像素之间差异的大小。量化图像对比度有许多方式。在深度学习中,对比度通常指的是图像或图像区域中像素的标准差。

自然语言处理

非常通用的神经网络技术可以成功地应用于自然语言处理。然而,为了实现卓越的性能并扩展到大型应用程序,一些领域特定的策略也很重要。

n-gram

语言模型(language model)定义了自然语言中标记序列的概率分布。根据模型的设计,标记可以是词、字符、甚至是字节。标记总是离散的实体,最早成功的语言模型基于固定长度序列的标记模型,称为 n-gram。

神经语言模型

神经语言模型(Neural Language Model, NLM)是一类用来客服维数灾难的语言模型,它使用词的分布式表示对自然语言序列建模。不同于基于类的 n-gram 模型,神经语言模型在能够识别两个相似的词,并且不丧失每个词编码为彼此不同的能力。神经语言模型共享一个词(及其上下文)和其他类似词(和上下文之间)的统计强度。

我们有时将这些词表示为词嵌入(word embedding)。在这个解释下,我们将原始符号视为维度等于词表大小的空间中的点。词表示将这些点嵌入到较低维度的特征空间中

推荐系统

当向用户推荐时,会产生超出普通监督学习范围的问题,并进入强化学习的领域。理论上,许多推荐问题最准确的描述是 contextual bandit。问题是,当我们使用推荐系统收集数据时,我们得到是一个有偏且不完整的用户偏好观:我们只能看到用户对推荐给他们的项目的反应,而不是其他项目。更糟糕的是,如果我们不够小心,即使收集越来越多的数据,我们得到的系统可能会继续选择错误的决定,因为正确的决定最初只有很低的概率:直到学习者选择正确的决定之前,该系统都无法学习正确的决定。这类似于强化学习的情况,其中仅观察到所选动作的奖励。一般来说,强化学习会涉及许多动作和许多奖励的序列。

在一般的强化学习场景中,高奖励或地奖励可能是由最近的动作或很久以前的动作引起的。术语 contextual bandit 指的是在一些输入变量可以通知决定的上下文中采取动作的情况。例如,我们至少知道用户身份,并且我们要选择一个项目。从上下文到动作的映射也称为策略(policy)。学习者和数据分布(现在取决于学习者的动作)之间的反馈是强化学习和 bandit 研究的中心问题。

强化学习需要权衡探索(exploration)与开发(exploitation)。开发指的是从目前学到的最好策略采取动作,也就是我们所知的将获得高奖励的动作。探索(exploration)是指采取行动以获得更多的训练数据。

知识表示、推理和回答

因为使用符号和词嵌入,深度学习方法在语言模型、机器翻译和自然语言处理方面非常成功。这些嵌入表示关于单个词或概念的语义只是。研究前言是为短语或词和事实之间的关系开发嵌入。

一个有趣的研究方向是确定如何训练分布式表示才能捕获两个实体之间的关系(relation).

知识库和分布式表示的另一个应用是词义消岐(word-sense disambiguation),这个任务决定在某些语境中词的哪个意义是恰当的。

知识的关系结合一个推理过程和对自然语言的理解可以让我们建立一个一般的问答系统。一般的问答系统必须能够处理输入信息并记住重要的事实,并以之后能检索和推理的方式组织。这热鞥然是一个困难的开放性问题,只能在受限的『玩具』环境下解决。目前,记住和检索特定声明性事实的最佳方法是使用显式记忆机制。记忆网络最开始是被用来解决一个玩具问答任务。Kumar 在 2015 年提出了一种扩展,使用 GRU 循环网络将输入读入存储器并且在给定存储器的内容后产生回答。

捧个钱场?