斯坦福大学深度学习手册全集


UFLDL 教程 说明:本教程将阐述无监督特征学习和深度学习的主要观点。通过学习,你也 将实现多个功能学习/深度学习算法,能看到它们为你工作,并学习如何应用/ 适应这些想法到新问题上。 本教程假定机器学习的基本知识(特别是熟悉的监督学习,逻辑回归,梯度下 降的想法),如果你不熟悉这些想法,我们建议你去这里 机器学习课程,并先完成第 II,III,IV 章(到逻辑回归)。 稀疏自编码器 神经网络 Contents [hide] 1 概述 2 神经网络模型 3 中英文对照 4 中文译者 概述 以监督学习为例,假设我们有训练样本集 ,那么神经网络算法能够 提供一种复杂且非线性的假设模型 ,它具有参数 ,可以以此参数 来拟合我们的数据。 为了描述神经网络,我们先从最简单的神经网络讲起,这个神经网络仅由一个 “神经元”构成,以下即是这个“神经元”的图示: 这个“神经元”是一个以 及截距 为输入值的运算单元,其输出 为 ,其中函数 被 称为“激活函数”。在本教程中,我们选用 sigmoid 函数作为激活函数 可以看出,这个单一“神经元”的输入-输出映射关系其实就是一个逻辑回归 (logistic regression)。 虽然本系列教程采用 sigmoid 函数,但你也可以选择双曲正切函数(tanh): 以下分别是 sigmoid 及 tanh 的函数图像 函数是 sigmoid 函数的一种变体,它的取值范围为 ,而不是 sigmoid 函数的 。 注意,与其它地方(包括 OpenClassroom 公开课以及斯坦福大学 CS229 课程) 不同的是,这里我们不再令 。取而代之,我们用单独的参数 来表示 截距。 最 后 要 说 明 的 是 , 有一个等式我们以后会经常用到 : 如 果 选 择 , 也 就 是 sigmoid 函 数 , 那 么 它 的 导 数 就 是 ( 如 果 选 择 tanh 函 数 , 那 它 的 导 数 就 是 ,你可以根据 sigmoid(或 tanh)函数的定义自行推导 这个等式。 神经网络模型 所谓神经网络就是将许多个单一“神经元”联结在一起,这样,一个“神经元”的 输出就可以是另一个“神经元”的输入。例如,下图就是一个简单的神经网络: 我们使用圆圈来表示神经网络的输入,标上“”的圆圈被称为偏置节点,也就 是截距项。神经网络最左边的一层叫做输入层,最右的一层叫做输出层(本例 中,输出层只有一个节点)。中间所有节点组成的一层叫做隐藏层,因为我们 不能在训练样本集中观测到它们的值。同时可以看到,以上神经网络的例子中 有 3 个输入单元(偏置单元不计在内),3 个隐藏单元及一个输出单元。 我们用 来表示网络的层数,本例中 ,我们将第 层记为 ,于 是 是输入层,输出层是 。本例神经网络有参数 , 其中 (下面的式子中用到)是第 层第 单元与第 层第 单元之 间的联接参数(其实就是连接线上的权重,注意标号顺序), 是 第 层第 单元的偏置项。因此在本例 中, , 。注意,没有其他单元连向偏置单元(即 偏置单元没有输入),因为它们总是输出 。同时,我们用 表示第 层的节 点数(偏置单元不计在内)。 我们用 表示第 层第 单元的激活值(输出值)。 当 时, ,也就是第 个输入值(输入值的第 个特 征)。对于给定参数集合 ,我们的神经网络就可以按照函 数 来计算输出结果。本例神经网络的计算步骤如下: 我们用 表示第 层第 单元输入加权和(包括偏置单元),比 如, ,则 。 这样我们就可以得到一种更简洁的表示法。这里我们将激活函数 扩展为用 向量(分量的形式)来表示,即 , 那么,上面的等式可以更简洁地表示为: 我们将上面的计算步骤叫作前向传播。回想一下,之前我们用 表示 输入层的激活值,那么给定第 层的激活值 后,第 层的激活 值 就可以按照下面步骤计算得到: 将参数矩阵化,使用矩阵-向量运算方式,我们就可以利用线性代数的优势对 神经网络进行快速求解。 目前为止,我们讨论了一种神经网络,我们也可以构建 另一种结构的神经网络(这里结构指的是神经元之间的 联接模式),也就是包含多个隐藏层的神经网络。最常 见的一个例子是 层的神经网络,第 层是输入层, 第 层是输出层,中间的每个层 与层 紧密相 联。这种模式下,要计算神经网络的输出结果,我们可 以按照之前描述的等式,按部就班,进行前向传播,逐 一计算第 层的所有激活值,然后是第 层的激活 值,以此类推,直到第 层。这是一个前馈神经网络 的例子,因为这种联接图没有闭环或回路。 神经网络也可以有多个输出单元。比如,下面的神经网 络有两层隐藏层: 及 ,输出层 有两个输出 单元。 要求解这样的神经网络,需要样本集 ,其中 。如果你想 预测的输出是多个的,那这种神经网络很适用。(比如,在医疗诊断应用中, 患者的体征指标就可以作为向量的输入值,而不同的输出值 可以表示不同 的疾病存在与否。) 中英文对照 neural networks 神经网络 activation function 激活函数 hyperbolic tangent 双曲正切函数 bias units 偏置项 activation 激活值 forward propagation 前向传播 feedforward neural network 前馈神经网络(参照 Mitchell 的 《机器学习》的翻译) 反向传导算法 假设我们有一个固定样本集 ,它包含 个样例。 我们可以用批量梯度下降法来求解神经网络。具体来讲,对于单个样例 , 其代价函数为: 这是一个(二分之一的)方差代价函数。给定一个包含 个样例的数据集, 我们可以定义整体代价函数为: 以上公式中的第一项 是一个均方差项。第二项是一个规则化项(也叫 权重衰减项),其目的是减小权重的幅度,防止过度拟合。 [注:通常权重衰减的计算并不使用偏置项 ,比如我们在 的定义中 就没有使用。一般来说,将偏置项包含在权重衰减项中只会对最终的神经网络 产生很小的影响。如果你在斯坦福选修过 CS229(机器学习)课程,或者在 YouTube 上看过课程视频,你会发现这个权重衰减实际上是课上提到的贝叶斯 规则化方法的变种。在贝叶斯规则化方法中,我们将高斯先验概率引入到参数 中计算 MAP(极大后验)估计(而不是极大似然估计)。] 权重衰减参数 用于控制公式中两项的相对重要性。在此重申一下这两 个复杂函数的含义: 是针对单个样例计算得到的方差代价函数; 是整体样本代价函数,它包含权重衰减项。 以上的代价函数经常被用于分类和回归问题。在分类问题中,我们 用 或 ,来代表两种类型的标签(回想一下,这是因为 sigmoid 激活函数 的值域为 ;如果我们使用双曲正切型激活函数,那么应该选用 和 作 为标签)。对于回归问题,我们首先要变换输出值域(译者注:也就是 ), 以保证其范围为 (同样地,如果我们使用双曲正切型激活函数,要使输 出值域为 )。 我们的目标是针对参数 和 来求其函数 的最小值。为了求解神经网 络,我们需要将每一个参数 和 初始化为一个很小的、接近零的随机值 (比如说,使用正态分布 生成的随机值,其中 设置为 ), 之后对目标函数使用诸如批量梯度下降法的最优化算法。因为 是一个非 凸函数,梯度下降法很可能会收敛到局部最优解;但是在实际应用中,梯度下 降法通常能得到令人满意的结果。最后,需要再次强调的是,要将参数进行随 机初始化,而不是全部置为 。如果所有参数都用相同的值作为初始值,那么 所有隐藏层单元最终会得到与输入值有关的、相同的函数(也就是说,对于所 有 , 都会取相同的值,那么对于任何输入 都会有: )。随机初始化的目的是使对称失效。 梯度下降法中每一次迭代都按照如下公式对参数 和 进行更新: 其中 是学习速率。其中关键步骤是计算偏导数。我们现在来讲一下反向传播 算法,它是计算偏导数的一种有效方法。 我们首先来讲一下如何使用反向传播算法来计 算 和 ,这两项是单个样例 的代 价函数 的偏导数。一旦我们求出该偏导数,就可以推导出整体 代价函数 的偏导数: 以上两行公式稍有不同,第一行比第二行多出一项,是因为权重衰减是作用 于 而不是 。 反向传播算法的思路如下:给定一个样例 ,我们首先进行“前向传导”运 算,计算出网络中所有的激活值,包括 的输出值。之后,针对第 层 的每一个节点 ,我们计算出其“残差” ,该残差表明了该节点对最终输出值 的残差产生了多少影响。对于最终的输出节点,我们可以直接算出网络产生的 激活值与实际值之间的差距,我们将这个差距定义为 (第 层表示输出 层)。对于隐藏单元我们如何处理呢?我们将基于节点(译者注:第 层 节点)残差的加权平均值计算 ,这些节点以 作为输入。下面将给出反 向传导算法的细节: 1. 进行前馈传导计算,利用前向传导公式,得 到 直到输出层 的激活值。 2. 对于第 层(输出层)的每个输出单元 ,我们根据 以下公式计算残差: [译者注: ] 3. 对 的各个层, 第 层的第 个节点的残差计算方法如下: {译者注: 将上式中的 与 的关系替换为 与 的关系,就可以得到: 以上逐次从后向前求导的过程即为“反向传导”的本意所在。 ] 4. 计算我们需要的偏导数,计算方法如下: 最后,我们用矩阵-向量表示法重写以上算法。我们使用“” 表示向量乘积运算 符(在 Matlab 或 Octave 里用“.*”表示,也称作阿达马乘积)。若 , 则 。在上一个教程中我们扩展了 的定义,使其包含向量运算, 这里我们也对偏导数 也做了同样的处理(于是又 有 )。 那么,反向传播算法可表示为以下几个步骤: 1. 进行前馈传导计算,利用前向传导公式,得 到 直到输出层 的激活值。 2. 对输出层(第 层),计算: 3. 对于 的各层, 计算: 4. 计算最终需要的偏导数值: 实现中应注意:在以上的第 2 步和第 3 步中,我们需要为每一个 值计算 其 。假设 是 sigmoid 函数,并且我们已经在前向传导运算中得到 了 。那么,使用我们早先推导出的 表达式,就可以计算得 到 。 最后,我们将对梯度下降算法做个全面总结。在下面的伪代码中, 是一 个与矩阵 维度相同的矩阵, 是一个与 维度相同的向量。注意 这里“”是一个矩阵,而不是“ 与 相乘”。下面,我们实现批量梯 度下降法中的一次迭代: 1. 对于所有 ,令 , (设置为 全零矩阵或全零向量) 2. 对于 到 , a. 使用反向传播算法计 算 和 。 b. 计 算 。 c. 计 算 。 3. 更新权重参数: 现在,我们可以重复梯度下降法的迭代步骤来减小代价函数 的值,进 而求解我们的神经网络。 中英文对照 反向传播算法 Backpropagation Algorithm (批量)梯度下降法 (batch) gradient descent (整体)代价函数 (overall) cost function 方差 squared-error 均方差 average sum-of-squares error 规则化项 regularization term 权重衰减 weight decay 偏置项 bias terms 贝叶斯规则化方法 Bayesian regularization method 高斯先验概率 Gaussian prior 极大后验估计 MAP 极大似然估计 maximum likelihood estimation 激活函数 activation function 双曲正切函数 tanh function 非凸函数 non-convex function 隐藏层单元 hidden (layer) units 对称失效 symmetry breaking 学习速率 learning rate 前向传导 forward pass 假设值 hypothesis 残差 error term 加权平均值 weighted average 前馈传导 feedforward pass 阿达马乘积 Hadamard product 前向传播 forward propagation 梯度检验与高级优化 众所周知,反向传播算法很难调试得到正确结果,尤其是当实现程序存 在很多难于发现的 bug 时。举例来说,索引的缺位错误(off-by-one error)会导 致只有部分层的权重得到训练,再比如忘记计算偏置项。这些错误会使你得到 一个看似十分合理的结果(但实际上比正确代码的结果要差)。因此,但从计 算结果上来看,我们很难发现代码中有什么东西遗漏了。本节中,我们将介绍 一种对求导结果进行数值检验的方法,该方法可以验证求导代码是否正确。另 外,使用本节所述求导检验方法,可以帮助你提升写正确代码的信心。 缺位错误(Off-by-one error)举例说明:比如 循环中循环 次,正确应该 是 ,但有时程序员疏忽,会写 成 ,这就是缺位错误。 假设我们想要最小化以 为自变量的目标函数 。假设 , 则 。在一维的情况下,一次迭代的梯度下降公式是 再假设我们已经用代码实现了计算 的函数 ,接着我们使 用 来实现梯度下降算法。那么我们如何检验 的实现是否正 确呢? 回忆导数的数学定义: 那么对于任意 值,我们都可以对等式左边的导数用: 来近似。 实际应用中,我们常将 设为一个很小的常量,比如在 数量 级(虽然 的取值范围可以很大,但是我们不会将它设得太小, 比如 ,因为那将导致数值舍入误差。) 给定一个被认为能计算 的函数 ,我们可以用下面的数值检验公式 计算两端是否一样来检验函数是否正确。 上式两端值的接近程度取决于 的具体形式。但是在假定 的情况下,你通常会发现上式左右两端至少有 4 位有效 数字是一样的(通常会更多)。 现在,考虑 是一个向量而非一个实数(那么就有 个参数要学习得 到),并且 。在神经网络的例子里我们使用 ,可以想 象为把参数 组合扩展成一个长向量 。现在我们将求导检验方法推广到 一般化,即 是一个向量的情况。 假设我们有一个用于计算 的函数 ;我们想要检验 是否输出正 确的求导结果。我们定义 ,其中 是第 个基向量(维度和 相同,在第 行是“”而其他行是“”)。所以, 和 几乎相同,除了第 行元素增加了 。类似地, 得到的第 行减小了 。然后我 们可以对每个 检查下式是否成立,进而验证 的正确性: 当用反射传播算法求解神经网络时,正确算法实现会得到: 以上结果与反向传播算法中的最后一段伪代码一致,都是计算梯度下降。 为了验证梯度下降代码的正确性,使用上述数值检验方法计算 的导数, 然后验证 与 是否能够给出正确的求导结果。 迄今为止,我们的讨论都集中在使用梯度下降法来最小化 。如果你 已经实现了一个计算 和 的函数,那么其实还有更精妙的算法来最小 化 。举例来说,可以想象这样一个算法:它使用梯度下降,并能够自动调 整学习速率 ,以得到合适的步长值,最终使 能够快速收敛到一个局部最优 解。还有更妙的算法:比如可以寻找一个 Hessian 矩阵的近似,得到最佳步长 值,使用该步长值能够更快地收敛到局部最优(和牛顿法类似)。此类算法的 详细讨论已超出了这份讲义的范围,但是 L-BFGS 算法我们以后会有论述(另 一个例子是共轭梯度算法)。你将在编程练习里使用这些算法中的一个。使用 这些高级优化算法时,你需要提供关键的函数:即对于任一个 ,需要你计算 出 和 。之后,这些优化算法会自动调整学习速率/步长值 的大小 (并计算 Hessian 近似矩阵等等)来自动寻找 最小化时 的值。诸如 L- BFGS 和共轭梯度算法通常比梯度下降法快很多。 中英文对照 off-by-one error 缺位错误 bias term 偏置项 numerically checking 数值检验 numerical roundoff errors 数值舍入误差 significant digits 有效数字 unrolling 组合扩展 learning rate 学习速率 Hessian matrix Hessian 矩阵 Newton's method 牛顿法 conjugate gradient 共轭梯度 step-size 步长值 自编码算法与稀疏性 目前为止,我们已经讨论了神经网络在有监督学习中的应用。在有监督学习中, 训练样本是有类别标签的。现在假设我们只有一个没有带类别标签的训练样本 集合 ,其中 。自编码神经网络是一种无监督学习算 法,它使用了反向传播算法,并让目标值等于输入值,比如 。下图是 一个自编码神经网络的示例。 自编码神经网络尝试学习一个 的函数。换句话说,它尝试逼近一个 恒等函数,从而使得输出 接近于输入 。恒等函数虽然看上去不太有学习的 意义,但是当我们为自编码神经网络加入某些限制,比如限定隐藏神经元的数 量,我们就可以从输入数据中发现一些有趣的结构。举例来说,假设某个自编 码神经网络的输入 是一张 图像(共 100 个像素)的像素灰度值, 于是 ,其隐藏层 中有 50 个隐藏神经元。注意,输出也是 100 维 的 。由于只有 50 个隐藏神经元,我们迫使自编码神经网络去学习输 入数据的压缩表示,也就是说,它必须从 50 维的隐藏神经元激活度向 量 中重构出 100 维的像素灰度值输入 。如果网络的输入数据是 完全随机的,比如每一个输入 都是一个跟其它特征完全无关的独立同分布 高斯随机变量,那么这一压缩表示将会非常难学习。但是如果输入数据中隐含 着一些特定的结构,比如某些输入特征是彼此相关的,那么这一算法就可以发 现输入数据中的这些相关性。事实上,这一简单的自编码神经网络通常可以学 习出一个跟主元分析(PCA)结果非常相似的输入数据的低维表示。 我们刚才的论述是基于隐藏神经元数量较小的假设。但是即使隐藏神经 元的数量较大(可能比输入像素的个数还要多),我们仍然通过给自编码神经 网络施加一些其他的限制条件来发现输入数据中的结构。具体来说,如果我们 给隐藏神经元加入稀疏性限制,那么自编码神经网络即使在隐藏神经元数量较 多的情况下仍然可以发现输入数据中一些有趣的结构。 稀疏性可以被简单地解释如下。如果当神经元的输出接近于 1 的时候我 们认为它被激活,而输出接近于 0 的时候认为它被抑制,那么使得神经元大部 分的时间都是被抑制的限制则被称作稀疏性限制。这里我们假设的神经元的激 活函数是 sigmoid 函数。如果你使用 tanh 作为激活函数的话,当神经元输出为- 1 的时候,我们认为神经元是被抑制的。 注意到 表示隐藏神经元 的激活度,但是这一表示方法中并未明确 指出哪一个输入 带来了这一激活度。所以我们将使用 来表示在给定输 入为 情况下,自编码神经网络隐藏神经元 的激活度。 进一步,让 表示隐藏神经元 的平均活跃度(在训练集上取平均)。我们可以近似的加入 一条限制 其中, 是稀疏性参数,通常是一个接近于 0 的较小的值(比 如 )。换句话说,我们想要让隐藏神经元 的平均活跃度接近 0.05。 为了满足这一条件,隐藏神经元的活跃度必须接近于 0。 为了实现这一限制,我们将会在我们的优化目标函数中加入一个额外的 惩罚因子,而这一惩罚因子将惩罚那些 和 有显著不同的情况从而使得隐藏 神经元的平均活跃度保持在较小范围内。惩罚因子的具体形式有很多种合理的 选择,我们将会选择以下这一种: 这里, 是隐藏层中隐藏神经元的数量,而索引 依次代表隐藏层中的每一 个神经元。如果你对相对熵(KL divergence)比较熟悉,这一惩罚因子实际上 是基于它的。于是惩罚因子也可以被表示为 其中 是一个以 为均值和一个以 为均值 的两个伯努利随机变量之间的相对熵。相对熵是一种标准的用来测量两个分布 之间差异的方法。(如果你没有见过相对熵,不用担心,所有你需要知道的内 容都会被包含在这份笔记之中。) 这一惩罚因子有如下性质,当 时 ,并且随着 与 之间 的差异增大而单调递增。举例来说,在下图中,我们设定 并且画出了相 对熵值 随着 变化的变化。 我们可以看出,相对熵在 时达到它的最小值 0,而当 靠近 0 或者 1 的 时候,相对熵则变得非常大(其实是趋向于 )。所以,最小化这一惩罚因子 具有使得 靠近 的效果。 现在,我们的总体代价函数可以表示为 其中 如之前所定义,而 控制稀疏性惩罚因子的权重。 项则也(间 接地)取决于 ,因为它是隐藏神经元 的平均激活度,而隐藏层神经元的 激活度取决于 。 为了对相对熵进行导数计算,我们可以使用一个易于实现的技巧,这只需要在 你的程序中稍作改动即可。具体来说,前面在后向传播算法中计算第二层 ( )更新的时候我们已经计算了 现在我们将其换成 就可以了。 有一个需要注意的地方就是我们需要知道 来计算这一项更新。所以在 计算任何神经元的后向传播之前,你需要对所有的训练样本计算一遍前向传播, 从而获取平均激活度。如果你的训练样本可以小到被整个存到内存之中(对于 编程作业来说,通常如此),你可以方便地在你所有的样本上计算前向传播并 将得到的激活度存入内存并且计算平均激活度 。然后你就可以使用事先计算好 的激活度来对所有的训练样本进行后向传播的计算。如果你的数据量太大,无 法全部存入内存,你就可以扫过你的训练样本并计算一次前向传播,然后将获 得的结果累积起来并计算平均激活度 (当某一个前向传播的结果中的激活 度 被用于计算平均激活度 之后就可以将此结果删除)。然后当你完成平 均激活度 的计算之后,你需要重新对每一个训练样本做一次前向传播从而可 以对其进行后向传播的计算。对于后一种情况,你对每一个训练样本需要计算 两次前向传播,所以在计算上的效率会稍低一些。 证明上面算法能达到梯度下降效果的完整推导过程不再本教程的范围之 内。不过如果你想要使用经过以上修改的后向传播来实现自编码神经网络,那 么你就会对目标函数 做梯度下降。使用梯度验证方法,你可以自己 来验证梯度下降算法是否正确。。 中英文对照 自编码算法 Autoencoders 稀疏性 Sparsity 神经网络 neural networks 监督学习 supervised learning 无监督学习 unsupervised learning 反向传播算法 backpropagation 隐藏神经元 hidden units 像素灰度值 the pixel intensity value 独立同分布 IID 主元分析 PCA 激活 active 抑制 inactive 激活函数 activation function 激活度 activation 平均活跃度 the average activation 稀疏性参数 sparsity parameter 惩罚因子 penalty term 相对熵 KL divergence 伯努利随机变量 Bernoulli random variable 总体代价函数 overall cost function 后向传播 backpropagation 前向传播 forward pass 梯度下降 gradient descent 目标函数 the objective 梯度验证方法 the derivative checking method 可视化自编码器训练结果 训练完(稀疏)自编码器,我们还想把这自编码器学到的函数可视化出来,好 弄明白它到底学到了什么。我们以在 10×10 图像(即 n=100)上训练自编码器 为例。在该自编码器中,每个隐藏单元 i 对如下关于输入的函数进行计算: 我们将要可视化的函数,就是上面这个以 2D 图像为输入、并由隐藏单元 i 计算 出来的函数。它是依赖于参数 的(暂时忽略偏置项 bi)。需要注意的是, 可看作输入 的非线性特征。不过还有个问题:什么样的输入图像 可让 得到最大程度的激励?(通俗一点说,隐藏单元 要找个什么样的特征?)。这 里我们必须给 加约束,否则会得到平凡解。若假设输入有范数约束 ,则可证(请读者自行推导)令隐藏单元 得到最大激励的 输入应由下面公式计算的像素 给出(共需计算 100 个像素,j=1,…,100): 当我们用上式算出各像素的值、把它们组成一幅图像、并将图像呈现在我们面 前之时,隐藏单元 所追寻特征的真正含义也渐渐明朗起来。 假如我们训练的自编码器有 100 个隐藏单元,可视化结果就会包含 100 幅这样 的图像——每个隐藏单元都对应一幅图像。审视这 100 幅图像,我们可以试着 体会这些隐藏单元学出来的整体效果是什么样的。 当我们对稀疏自编码器(100 个隐藏单元,在 10X10 像素的输入上训练 )进行 上述可视化处理之后,结果如下所示: 上图的每个小方块都给出了一个(带有有界范数 的)输入图像 ,它可使这 100 个隐藏单元中的某一个获得最大激励。我们可以看到,不同的隐藏单元学 会了在图像的不同位置和方向进行边缘检测。 显而易见,这些特征对物体识别等计算机视觉任务是十分有用的。若将其用于 其他输入域(如音频),该算法也可学到对这些输入域有用的表示或特征。 中英文对照 可视化 Visualizing 自编码器 Autoencoder 隐藏单元 hidden unit 非线性特征 non-linear feature 激励 activate 平凡解 trivial answer 范数约束 norm constrained 稀疏自编码器 sparse autoencoder 有界范数 norm bounded 输入域 input domains 稀疏自编码器符号一览表 下面是我们在推导 sparse autoencoder 时使用的符号一览表: 符号 含义 训练样本的输入特征,. 输出值/目标值. 这里 可以是向量. 在 autoencoder 中,. 第 个训练样本 输入为 时的假设输出,其中包含参数 . 该输出应当与目标 值 具有相同的维数. 连接第 层 单元和第 层 单元的参数. 第 层 单元的偏置项. 也可以看作是连接第 层偏置单元和 第 层 单元的参数. 参数向量. 可以认为该向量是通过将参数 组合展开为一个长的 列向量而得到. 网络中第 层 单元的激活(输出)值. 另外,由于 层是输入层,所以 . 激活函数. 本文中我们使用 . 第 层 单元所有输入的加权和. 因此有 . 学习率 第 层的单元数目(不包含偏置单元). 网络中的层数. 通常 层是输入层, 层是输出层. 权重衰减系数. 对于一个 autoencoder,该符号表示其输出值;亦即输入值 的重 构值. 与 含义相同. 稀疏值,可以用它指定我们所需的稀疏程度 (sparse autoencoder 中)隐藏单元 的平均激活值. (sparse autoencoder 目标函数中)稀疏值惩罚项的权重. Vectorized implementation 矢量化编程 当使用学习算法时,一段更快的代码通常意味着项目进展更快。例如,如果你 的学习算法需要花费 20 分钟运行完成,这意味着你每个小时能“尝试”3 个新主 意。但是假如你的程序需要 20 个小时来运行,这意味着你一天只能“尝试”一个 新主意,因为你需要花费这么长时间来等待程序的反馈。对于后者,假如你可 以提升代码的效率让其只需要运行 10 个小时,那么你的效率差不多提升一倍。 矢量化编程是提高算法速度的一种有效方法。为了提升特定数值运算操作(如 矩阵相乘、矩阵相加、矩阵-向量乘法等)的速度,数值计算和并行计算的研究 人员已经努力了几十年。矢量化编程的思想就是尽量使用这些被高度优化的数 值运算操作来实现我们的学习算法。 例如,假设 和 为向量,需要计算 ,那么可以 按以下方式实现(使用 Matlab): z = 0; for i=1:(n+1), z = z + theta(i) * x(i); end; 或者可以更加简单的写为: z = theta' * x; 第二段程序代码不仅简单,而且运行速度更快。 通常,一个编写 Matlab/Octave 程序的诀窍是: 代码中尽可能避免显式的 for 循环。 上面的第一段代码使用了一个显式的 for 循环。通过不使用 for 循环实现相同功 能,可以显著提升运行速度。对 Matlab/Octave 代码进行矢量化的工作很大一部 分集中在避免使用 for 循环上,因为这可以使得 Matlab/Octave 更多地利用代码 中的并行性,同时其解释器的计算开销更小。 关于编写代码的策略,开始时你会觉得矢量化代码更难编写、阅读和调试,但 你需要在编码和调试的便捷性与运行时间之间做个权衡。因此,刚开始编写程 序的时候,你可能会选择不使用太多矢量化技巧来实现你的算法,并验证它是 否正确(可能只在一个小问题上验证)。在确定它正确后,你可以每次只矢量 化一小段代码,并在这段代码之后暂停,以验证矢量化后的代码计算结果和之 前是否相同。最后,你会有望得到一份正确的、经过调试的、矢量化且有效率 的代码。 一旦对矢量化常见的方法和技巧熟悉后,你将会发现对代码进行矢量化通常并 不太费劲。矢量化可以使你的代码运行的更快,而且在某些情况下,还简化了 你的代码。 中英文对照 矢量化 vectorization 逻辑回归的向量化实现样例 我们想用批量梯度上升法对 logistic 回归分析模型进行训练,其模型如下: 让我们遵从公开课程视频与 CS229 教学讲义的符号规范,设 ,于 是 ,, 为截距。假设我们有 m 个训练样本{( , ) ,...,( , )},而批量梯度上升法的更新法则是: ,这里的 是对数似然函数, 是其导函数。 [注:下文的符号规范与<公开课程视频>或<教学讲义 CS229:机器学习>中的相 同,详细内容可以参见公开课程视频或教学讲义#1http://cs229.stanford.edu/] 于是,我们需要如下计算梯度: 我们用 Matlab/Octave 风格变量 x 表示输入数据构成的样本矩阵,x(:,i)代表第 i 个训练样本 ,x(j,i)就代表 (译者注:第 i 个训练样本向量的第 j 个元 素)。同样,用 Matlab/Octave 风格变量 y 表示由训练样本集合的全体类别标号 所构成的行向量,则该向量的第 i 个元素 y(i)就代表上式中的 。 (注意这里跟公开课程视频及 CS229 的符号规范不同,矩阵 x 按列而不是按行 存放输入训练样本,同样, 是行向量而不是列向量。) 以下是梯度运算代码的一种实现,非常恐怖,速度极慢: % 代码 1 grad = zeros(n+1,1); for i=1:m, h = sigmoid(theta'*x(:,i)); temp = y(i) - h; for j=1:n+1, grad(j) = grad(j) + temp * x(j,i); end; end; 嵌套的 for 循环语句使这段代码的运行非常缓慢。以下是更典型的实现方式, 它对算法进行部分向量化,带来更优的执行效率: % 代码 2 grad = zeros(n+1,1); for i=1:m, grad = grad + (y(i) - sigmoid(theta'*x(:,i)))* x(:,i); end; 但是,或许可以向量化得更彻底些。如果去除 for 循环,我们就可以显著地改 善代码执行效率。特别的,假定 b 是一个列向量,A 是一个矩阵,我们用以下 两种方式来计算 A*b: % 矩阵-向量乘法运算的低效代码 grad = zeros(n+1,1); for i=1:m, grad = grad + b(i) * A(:,i); % 通常写法为 A(:,i)*b(i) end; % 矩阵-向量乘法运算的高效代码 grad = A*b; 我们看到,代码 2 是用了低效的 for 循环语句执行梯度上升(译者注:原文是下 降)运算,将 b(i)看成(y(i) - sigmoid(theta'*x(:,i))),A 看成 x,我们就可以使用 以下高效率的代码: % 代码 3 grad = x * (y- sigmoid(theta'*x)); 这里我们假定 Matlab/Octave 的 sigmoid(z)函数接受一个向量形式的输入 z,依 次对输入向量的每个元素施行 sigmoid 函数,最后返回运算结果,因此 sigmoid(z)的输出结果是一个与 z 有相同维度的向量。 当训练数据集很大时,最终的实现(译者注:代码 3)充分发挥了 Matlab/Octave 高度优化的数值线性代数库的优势来进行矩阵-向量操作,因此, 比起之前代码要高效得多。 想采用向量化实现并非易事,通常需要周密的思考。但当你熟练掌握向量化操 作后,你会发现,这里面有固定的设计模式(对应少量的向量化技巧),可以 灵活运用到很多不同的代码片段中。 中英文对照 逻辑回归 Logistic Regression 批量梯度上升法 batch gradient ascent 截距 intercept term 对数似然函数 the log likelihood 导函数 derivative 梯度 gradient 神经网络向量化 在本节,我们将引入神经网络的向量化版本。在前面关于神经网络介绍的章节 中,我们已经给出了一个部分向量化的实现,它在一次输入一个训练样本时是 非常有效率的。下边我们看看如何实现同时处理多个训练样本的算法。具体来 讲,我们将把正向传播、反向传播这两个步骤以及稀疏特征集学习扩展为多训 练样本版本。 Contents [hide] 1 正向传播 2 反向传播 3 稀疏自编码网络 4 中英文对照 5 中文译者 正向传播 考虑一个三层网络(一个输入层、一个隐含层、以及一个输出层),并且假定 x 是包含一个单一训练样本 的列向量。则向量化的正向传播步骤如下: 这对于单一训练样本而言是非常有效的一种实现,但是当我们需要处理 m 个训 练样本时,则需要把如上步骤放入一个 for 循环中。 更具体点来说,参照逻辑回归向量化的例子,我们用 Matlab/Octave 风格变量 x 表示包含输入训练样本的矩阵,x(:,i)代表第 个训练样本。则 x 正向传播步骤可 如下实现: % 非向量化实现 for i=1:m, z2 = W1 * x(:,i) + b1; a2 = f(z2); z3 = W2 * a2 + b2; h(:,i) = f(z3); end; 这个 for 循环能否去掉呢?对于很多算法而言,我们使用向量来表示计算过程 中的中间结果。例如在前面的非向量化实现中,z2,a2,z3 都是列向量,分别用来 计算隐层和输出层的激励结果。为了充分利用并行化和高效矩阵运算的优势, 我们希望算法能同时处理多个训练样本。让我们先暂时忽略前面公式中的 b1 和 b2(把它们设置为 0),那么可以实现如下: % 向量化实现 (忽略 b1, b2) z2 = W1 * x; a2 = f(z2); z3 = W2 * a2; h = f(z3) 在这个实现中,z2,a2,z3 都是矩阵,每个训练样本对应矩阵的一列。在对多个训 练样本实现向量化时常用的设计模式是,虽然前面每个样本对应一个列向量 (比如 z2),但我们可把这些列向量堆叠成一个矩阵以充分享受矩阵运算带来 的好处。这样,在这个例子中,a2 就成了一个 s2 X m 的矩阵(s2 是网络第二层中 的神经元数,m 是训练样本个数)。矩阵 a2 的物理含义是,当第 i 个训练样本 x(:i)输入到网络中时,它的第 i 列就表示这个输入信号对隐神经元 (网络第二层) 的激励结果。 在上面的实现中,我们假定激活函数 f(z)接受矩阵形式的输入 z,并对输入矩阵 按列分别施以激活函数。需要注意的是,你在实现 f(z)的时候要尽量多用 Matlab/Octave 的矩阵操作,并尽量避免使用 for 循环。假定激活函数采用 Sigmoid 函数,则实现代码如下所示: % 低效的、非向量化的激活函数实现 function output = unvectorized_f(z) output = zeros(size(z)) for i=1:size(z,1), for j=1:size(z,2), output(i,j) = 1/(1+exp(-z(i,j))); end; end; end % 高效的、向量化激活函数实现 function output = vectorized_f(z) output = 1./(1+exp(-z)); % "./" 在 Matlab 或 Octave 中表示对矩阵的每个元 素分别进行除法操作 end 最后,我们上面的正向传播向量化实现中忽略了 b1 和 b2,现在要把他们包含 进来,为此我们需要用到 Matlab/Octave 的内建函数 repmat: % 正向传播的向量化实现 z2 = W1 * x + repmat(b1,1,m); a2 = f(z2); z3 = W2 * a2 + repmat(b2,1,m); h = f(z3) repmat(b1,1,m)的运算效果是,它把列向量 b1 拷贝 m 份,然后堆叠成如下矩阵: 这就构成一个 s2 X m 的矩阵。它和 W1 * x 相加,就等于是把 W1 * x 矩阵(译 者注:这里 x 是训练矩阵而非向量, 所以 W1 * x 代表两个矩阵相乘,结果还是 一个矩阵)的每一列加上 b1。如果不熟悉的话,可以参考 Matlab/Octave 的帮 助文档获取更多信息(输入“help repmat”)。rampat 作为 Matlab/Octave 的内建函 数,运行起来是相当高效的,远远快过我们自己用 for 循环实现的效果。 反向传播 现在我们来描述反向传播向量化的思路。在阅读这一节之前,强烈建议各位仔 细阅读前面介绍的正向传播的例子代码,确保你已经完全理解。下边我们只会 给出反向传播向量化实现的大致纲要,而由你来完成具体细节的推导(见向量 化练习)。 对于监督学习,我们有一个包含 m 个带类别标号样本的训练集 。 (对于自编码网络,我们只需令 y(i) = x(i)即 可, 但这里考虑的是更一般的情况。) 假定网络的输出有 s3 维,因而每个样本的类别标号向量就记为 。在 我们的 Matlab/Octave 数据结构实现中,把这些输出按列合在一起形成一个 Matlab/Octave 风格变量 y,其中第 i 列 y(:,i)就是 y(i)。 现在我们要计算梯度项 和 。对于梯度中的第一项, 就像过去在反向传播算法中所描述的那样,对于每个训练样本(x,y),我们可以 这样来计算: 在这里 表示对两个向量按对应元素相乘的运算(译者注:其结果还是一个向 量)。为了描述简单起见,我们这里暂时忽略对参数 b(l)的求导,不过在你真正 实现反向传播时,还是需要计算关于它们的导数的。 假定我们已经实现了向量化的正向传播方法,如前面那样计算了矩阵形式的变 量 z2, a2, z3 和 h,那么反向传播的非向量化版本可如下实现: gradW1 = zeros(size(W1)); gradW2 = zeros(size(W2)); for i=1:m, delta3 = -(y(:,i) - h(:,i)) .* fprime(z3(:,i)); delta2 = W2'*delta3(:,i) .* fprime(z2(:,i)); gradW2 = gradW2 + delta3*a2(:,i)'; gradW1 = gradW1 + delta2*a1(:,i)'; end; 在这个实现中,有一个 for 循环。而我们想要一个能同时处理所有样本、且去 除这个 for 循环的向量化版本。 为做到这一点,我们先把向量 delta3 和 delta2 替换为矩阵,其中每列对应一个 训练样本。我们还要实现一个函数 fprime(z),该函数接受矩阵形式的输入 z, 并且对矩阵的按元素分别执行 。这样,上面 for 循环中的 4 行 Matlab 代码 中每行都可单独向量化,以一行新的(向量化的)Matlab 代码替换它(不再需 要外层的 for 循环)。 在向量化练习中,我们要求你自己去推导出这个算法的向量化版本。如果你已 经能从上面的描述中了解如何去做,那么我们强烈建议你去实践一下。虽然我 们已经为你准备了反向传播的向量化实现提示,但还是鼓励你在不看提示的情 况下自己去推导一下。 稀疏自编码网络 稀疏自编码网络中包含一个额外的稀疏惩罚项,目的是限制神经元的平均激活 率,使其接近某个(预设的)目标激活率 ρ。其实在对单个训练样本上执行反 向传播时,我们已经考虑了如何计算这个稀疏惩罚项,如下所示: 在非向量化的实现中,计算代码如下: % 稀疏惩罚 Delta sparsity_delta = - rho ./ rho_hat + (1 - rho) ./ (1 - rho_hat); for i=1:m, ... delta2 = (W2'*delta3(:,i) + beta*sparsity_delta).* fprime(z2(:,i)); ... end; 但在上面的代码中,仍旧含有一个需要在整个训练集上运行的 for 循环,这里 delta2 是一个列向量。 作为对照,回想一下在向量化的情况下,delta2 现在应该是一个有 m 列的矩阵, 分别对应着 m 个训练样本。还要注意,稀疏惩罚项 sparsity_delta 对所有的训练 样本一视同仁。这意味着要向量化实现上面的计算,只需在构造 delta2 时,往 矩阵的每一列上分别加上相同的值即可。因此,要向量化上面的代码,我们只 需简单的用 repmat 命令把 sparsity_delta 加到 delta2 的每一列上即可(译者注: 这里原文描述得不是很清楚,看似应加到上面代码中 delta2 行等号右边第一项, 即 W2'*delta3 上)。 中英文对照 向量化 vectorization 正向传播 forward propagation 反向传播 backpropagation 训练样本 training examples 激活函数 activation function 稀疏自编码网络 sparse autoencoder 稀疏惩罚 sparsity penalty 平均激活率 average firing rate Preprocessing: PCA and Whitening 主成分分析 Contents [hide] 1 引言 2 实例和数学背景 3 旋转数据 4 数据降维 5 还原近似数据 6 选择主成分个数 7 对图像数据应用 PCA 算法 8 参考文献 9 中英文对照 10 中文译者 引言 主成分分析(PCA)是一种能够极大提升无监督特征学习速度的数据降维算法。 更重要的是,理解 PCA 算法,对实现白化算法有很大的帮助,很多算法都先用 白化算法作预处理步骤。 假设你使用图像来训练算法,因为图像中相邻的像素高度相关,输入数据是有 一定冗余的。具体来说,假如我们正在训练的 16x16 灰度值图像,记为一个 256 维向量 ,其中特征值 对应每个像素的亮度值。由于相邻像素 间的相关性,PCA 算法可以将输入向量转换为一个维数低很多的近似向量,而 且误差非常小。 实例和数学背景 在我们的实例中,使用的输入数据集表示为 ,维 度 即 。假设我们想把数据从 2 维降到 1 维。(在实际应用 中,我们也许需要把数据从 256 维降到 50 维;在这里使用低维数据,主要是为 了更好地可视化算法的行为)。下图是我们的数据集: 这些数据已经进行了预处理,使得每个特征 和 具有相同的均值(零)和 方差。 为方便展示,根据 值的大小,我们将每个点分别涂上了三种颜色之一,但 该颜色并不用于算法而仅用于图解。 PCA 算法将寻找一个低维空间来投影我们的数据。从下图中可以看出, 是 数据变化的主方向,而 是次方向。 也就是说,数据在 方向上的变化要比在 方向上大。为更形式化地找出方 向 和 ,我们首先计算出矩阵 ,如下所示: 假设 的均值为零,那么 就是 x 的协方差矩阵。(符号 ,读"Sigma",是 协方差矩阵的标准符号。虽然看起来与求和符号 比较像,但它们其实是 两个不同的概念。) 可以证明,数据变化的主方向 就是协方差矩阵 的主特征向量,而 是 次特征向量。 注:如果你对如何得到这个结果的具体数学推导过程感兴趣,可以参看 CS229 (机器学习)PCA 部分的课件(链接在本页底部)。但如果仅仅是想跟上本课, 可以不必如此。 你可以通过标准的数值线性代数运算软件求得特征向量(见实现说明).我们先 计算出协方差矩阵 的特征向量,按列排放,而组成矩阵 : 此处, 是主特征向量(对应最大的特征值), 是次特征向量。以此类推, 另记 为相应的特征值。 在本例中,向量 和 构成了一个新基,可以用来表示数据。 令 为训练样本,那么 就是样本点 在维度 上的投影的长度 (幅值)。同样的, 是 投影到 维度上的幅值。 旋转数据 至此,我们可以把 用 基表达为: (下标“rot”来源于单词“rotation”,意指这是原数据经过旋转(也可以说成映射) 后得到的结果) 对数据集中的每个样本 分别进行旋转: for every ,然后把 变换后的数据 显示在坐标图上,可得: 这就是把训练数据集旋转到 , 基后的结果。一般而言,运算 表示 旋转到基 ,, ..., 之上的训练数据。矩阵 有正交性,即满 足 ,所以若想将旋转后的向量 还原为原始数据 , 将其左乘矩阵 即可: , 验算一下: . 数据降维 数据的主方向就是旋转数据的第一维 。因此,若想把这数据降到一维, 可令: 更一般的,假如想把数据 降到 维表示 (令 ),只需 选取 的前 个成分,分别对应前 个数据变化的主方向。 PCA 的另外一种解释是: 是一个 维向量,其中前几个成分可能比较大 (例如,上例中大部分样本第一个成分 的取值相对较大), 而后面成分可能会比较小(例如,上例中大部分样本的 较 小)。 PCA 算法做的其实就是丢弃 中后面(取值较小)的成分,就是将这些成 分的值近似为零。具体的说,设 是 的近似表示,那么将 除了 前 个成分外,其余全赋值为零,就得到: 在本例中,可得 的点图如下(取 ): 然而,由于上面 的后 项均为零,没必要把这些零项保留下来。所以, 我们仅用前 个(非零)成分来定义 维向量 。 这也解释了我们为什么会以 为基来表示数据:要决定保留哪 些成分变得很简单,只需取前 个成分即可。这时也可以说,我们“保留了 前 个 PCA(主)成分”。 还原近似数据 现在,我们得到了原始数据 的低维“压缩”表征量 , 反过来, 如果给定 ,我们应如何还原原始数据 呢?查看以往章节以往章节可知,要 转换回来,只需 即可。进一步,我们把 看作将 的最 后 个元素被置 0 所得的近似表示,因此如果给定 ,可以通过 在其末尾添加 个 0 来得到对 的近似,最后,左乘 便可近 似还原出原数据 。具体来说,计算如下: 上面的等式基于先前对 的定义。在实现时,我们实际上并不先给 填 0 然 后再左乘 ,因为这意味着大量的乘 0 运算。我们可用 来与 的 前 列相乘,即上式中最右项,来达到同样的目的。将该算法应用于本例中的 数据集,可得如下关于重构数据 的点图: 由图可见,我们得到的是对原始数据集的一维近似重构。 在训练自动编码器或其它无监督特征学习算法时,算法运行时间将依赖于输入 数据的维数。若用 取代 作为输入数据,那么算法就可使用低维数据 进行训练,运行速度将显著加快。对于很多数据集来说,低维表征量 是原数 据集的极佳近似,因此在这些场合使用 PCA 是很合适的,它引入的近似误差的 很小,却可显著地提高你算法的运行速度。 选择主成分个数 我们该如何选择 ,即保留多少个 PCA 主成分?在上面这个简单的二维实验中, 保留第一个成分看起来是自然的选择。对于高维数据来说,做这个决定就没那 么简单:如果 过大,数据压缩率不高,在极限情况 时,等于是在使 用原始数据(只是旋转投射到了不同的基);相反地,如果 过小,那数据的 近似误差太太。 决定 值时,我们通常会考虑不同 值可保留的方差百分比。具体来说,如 果 ,那么我们得到的是对数据的完美近似,也就是保留了 100%的方差, 即原始数据的所有变化都被保留下来;相反,如果 ,那等于是使用零向 量来逼近输入数据,也就是只有 0%的方差被保留下来。 一般而言,设 表示 的特征值(按由大到小顺序排列),使 得 为对应于特征向量 的特征值。那么如果我们保留前 个成分,则保留 的方差百分比可计算为: 在上面简单的二维实验中, , 。因此,如果保 留 个主成分,等于我们保留了 ,即 91.3%的方差。 对保留方差的百分比进行更正式的定义已超出了本教程的范围,但很容易证明, 。因此,如果 ,则说明 也就基本上接近于 0, 所以用 0 来近似它并不会产生多大损失。这也解释了为什么要保留前面的主成 分(对应的 值较大)而不是末尾的那些。 这些前面的主成分 变化性 更大,取值也更大,如果将其设为 0 势必引入较大的近似误差。 以处理图像数据为例,一个惯常的经验法则是选择 以保留 99%的方差,换句 话说,我们选取满足以下条件的最小 值: 对其它应用,如不介意引入稍大的误差,有时也保留 90-98%的方差范围。若向 他人介绍 PCA 算法详情,告诉他们你选择的 保留了 95%的方差,比告诉他 们你保留了前 120 个(或任意某个数字)主成分更好理解。 对图像数据应用 PCA 算法 为使 PCA 算法能有效工作,通常我们希望所有的特征 都有相 似的取值范围(并且均值接近于 0)。如果你曾在其它应用中使用过 PCA 算法, 你可能知道有必要单独对每个特征做预处理,即通过估算每个特征 的均值 和方差,而后将其取值范围规整化为零均值和单位方差。但是,对于大部分图 像类型,我们却不需要进行这样的预处理。假定我们将在自然图像上训练算法, 此时特征 代表的是像素 的值。所谓“自然图像”,不严格的说,是指人或 动物在他们一生中所见的那种图像。 注:通常我们选取含草木等内容的户外场景图片,然后从中随机截取小图像块 (如 16x16 像素)来训练算法。在实践中我们发现,大多数特征学习算法对训 练图片的确切类型并不敏感,所以大多数用普通照相机拍摄的图片,只要不是 特别的模糊或带有非常奇怪的人工痕迹,都可以使用。 在自然图像上进行训练时,对每一个像素单独估计均值和方差意义不大,因为 (理论上)图像任一部分的统计性质都应该和其它部分相同,图像的这种特性 被称作平稳性(stationarity)。 具体而言,为使 PCA 算法正常工作,我们通常需要满足以下要求:(1)特征的均 值大致为 0;(2)不同特征的方差值彼此相似。对于自然图片,即使不进行方差 归一化操作,条件(2)也自然满足,故而我们不再进行任何方差归一化操作(对 音频数据,如声谱,或文本数据,如词袋向量,我们通常也不进行方差归一化)。 实际上,PCA 算法对输入数据具有缩放不变性,无论输入数据的值被如何放大 (或缩小),返回的特征向量都不改变。更正式的说:如果将每个特征向 量 都乘以某个正数(即所有特征量被放大或缩小相同的倍数),PCA 的输出 特征向量都将不会发生变化。 既然我们不做方差归一化,唯一还需进行的规整化操作就是均值规整化,其目 的是保证所有特征的均值都在 0 附近。根据应用,在大多数情况下,我们并不 关注所输入图像的整体明亮程度。比如在对象识别任务中,图像的整体明亮程 度并不会影响图像中存在的是什么物体。更为正式地说,我们对图像块的平均 亮度值不感兴趣,所以可以减去这个值来进行均值规整化。 具体的步骤是,如果 代表 16x16 的图像块的亮度(灰度)值 ( ),可用如下算法来对每幅图像进行零均值化操作: , for all 请注意:1)对每个输入图像块 都要单独执行上面两个步骤,2)这里 的 是指图像块 的平均亮度值。尤其需要注意的是,这和为每个像 素 单独估算均值是两个完全不同的概念。 如果你处理的图像并非自然图像(比如,手写文字,或者白背景正中摆放单独 物体),其他规整化操作就值得考虑了,而哪种做法最合适也取决于具体应用 场合。但对自然图像而言,对每幅图像进行上述的零均值规整化,是默认而合 理的处理。 参考文献 http://cs229.stanford.edu 中英文对照 Principal Components Analysis 主成份分析 whitening 白化 intensity 亮度 mean 平均值 variance 方差 covariance matrix 协方差矩阵 basis 基 magnitude 幅值 stationarity 平稳性 normalization 归一化 eigenvector 特征向量 eigenvalue 特征值 白化 Contents [hide] 1 介绍 2 2D 的例子 3 ZCA 白化 4 正则化 5 中英文对照 6 中文译者 介绍 我们已经了解了如何使用 PCA 降低数据维度。在一些算法中还需要一个与之相 关的预处理步骤,这个预处理过程称为白化(一些文献中也叫 sphering)。举 例来说,假设训练数据是图像,由于图像中相邻像素之间具有很强的相关性, 所以用于训练时输入是冗余的。白化的目的就是降低输入的冗余性;更正式的 说,我们希望通过白化过程使得学习算法的输入具有如下性质:(i)特征之间相 关性较低;(ii)所有特征具有相同的方差。 2D 的例子 下面我们先用前文的 2D 例子描述白化的主要思想,然后分别介绍如何将白化 与平滑和 PCA 相结合。 如何消除输入特征之间的相关性? 在前文计算 时实际上已经消 除了输入特征 之间的相关性。得到的新特征 的分布如下图所示: 这个数据的协方差矩阵如下: (注: 严格地讲, 这部分许多关于“协方差”的陈述仅当数据均值为 0 时成立。下文 的论述都隐式地假定这一条件成立。不过即使数据均值不为 0,下文的说法仍 然成立,所以你无需担心这个。) 协方差矩阵对角元素的值为 和 绝非偶然。并且非对角元素值为 0; 因此, 和 是不相关的, 满足我们对白化结果的第一个要求 (特征间相 关性降低)。 为了使每个输入特征具有单位方差,我们可以直接使用 作为缩放因子 来缩放每个特征 。具体地,我们定义白化后的数据 如 下: 绘制出 ,我们得到: 这些数据现在的协方差矩阵为单位矩阵 。我们说, 是数据经过 PCA 白化后的版本: 中不同的特征之间不相关并且具有单位方差。 白化与降维相结合。 如果你想要得到经过白化后的数据,并且比初始输入维数 更低,可以仅保留 中前 个成分。当我们把 PCA 白化和正则化结合 起来时(在稍后讨论), 中最后的少量成分将总是接近于 0,因而舍弃 这些成分不会带来很大的问题。 ZCA 白化 最后要说明的是,使数据的协方差矩阵变为单位矩阵 的方式并不唯 一。具体地,如果 是任意正交矩阵,即满 足 (说它正交不太严格, 可以是旋转或反射矩 阵), 那么 仍然具有单位协方差。在 ZCA 白化中, 令 。我们定义 ZCA 白化的结果为: 绘制 ,得到: 可以证明,对所有可能的 ,这种旋转使得 尽可能地接近原始输入 数据 。 当使用 ZCA 白化时(不同于 PCA 白化),我们通常保留数据的全部 个维度, 不尝试去降低它的维数。 正则化 实践中需要实现 PCA 白化或 ZCA 白化时,有时一些特征值 在数值上接近于 0,这样在缩放步骤时我们除以 将导致除以一个接近 0 的值;这可能使数 据上溢 (赋为大数值)或造成数值不稳定。因而在实践中,我们使用少量的正则 化实现这个缩放过程,即在取平方根和倒数之前给特征值加上一个很小的常 数 : 当 在区间 上时, 一般取值为 。 对图像来说, 这里加上 ,对输入图像也有一些平滑(或低通滤波)的作用。这样 处理还能消除在图像的像素信息获取过程中产生的噪声,改善学习到的特征(细 节超出了本文的范围)。 ZCA 白化是一种数据预处理方法,它将数据从 映射到 。 事实证 明这也是一种生物眼睛(视网膜)处理图像的粗糙模型。具体而言,当你的眼睛 感知图像时,由于一幅图像中相邻的部分在亮度上十分相关,大多数临近的“像 素”在眼中被感知为相近的值。因此,如果人眼需要分别传输每个像素值(通过 视觉神经)到大脑中,会非常不划算。取而代之的是,视网膜进行一个与 ZCA 中相似的去相关操作 (这是由视网膜上的 ON-型和 OFF-型光感受器细胞将光信 号转变为神经信号完成的)。由此得到对输入图像的更低冗余的表示,并将它传 输到大脑。 中英文对照 白化 whitening 冗余 redundant 方差 variance 平滑 smoothing 降维 dimensionality reduction 正则化 regularization 反射矩阵 reflection matrix 去相关 decorrelation 实现主成分分析和白化 在这一节里,我们将总结 PCA, PCA 白化和 ZCA 白化算法,并描述如何使用高 效的线性代数库来实现它们。 首先,我们需要确保数据的均值(近似)为零。对于自然图像,我们通过减去 每个图像块(patch)的均值(近似地)来达到这一目标。为此,我们计算每个图 像块的均值,并从每个图像块中减去它的均值。(译注:参见 PCA 一章中“对 图像数据应用 PCA 算法”一节)。Matlab 实现如下: avg = mean(x, 1); % 分别为每个图像块计算像素强度的均值。 x = x - repmat(avg, size(x, 1), 1); 下面,我们要计算 ,如果你在 Matlab 中实现(或 者在 C++, Java 等中实现,但可以使用高效的线性代数库),直接求和效率很低。 不过,我们可以这样一气呵成。 sigma = x * x' / size(x, 2); (自己推导一下看看)这里,我们假设 x 为一数据结构,其中每列表示一个训 练样本(所以 x 是一个 × 的矩阵)。 接下来,PCA 计算 Σ 的特征向量。你可以使用 Matlab 的 eig 函数来计算。但是 由于 Σ 是对称半正定的矩阵,用 svd 函数在数值计算上更加稳定。 具体来说,如果你使用 [U,S,V] = svd(sigma); 那矩阵 U 将包含 Sigma 的特征向量(一个特征向量一列,从主向量开始排序), 矩阵 S 对角线上的元素将包含对应的特征值(同样降序排列)。矩阵 等 于 的转置,可以忽略。 (注意 svd 函数实际上计算的是一个矩阵的奇异值和奇异向量,就对称半正定 矩阵的特殊情况来说,它们对应于特征值和特征向量,这里我们也只关心这一 特例。关于奇异向量和特征向量的详细讨论超出了本文范围。) 最后,我们可以这样计 算 和 : xRot = U' * x; % 数据旋转后的结果。 xTilde = U(:,1:k)' * x; % 数据降维后的结果,这里 k 希望保留的特征向量的数 目。 这以 的形式给出了数据的 PCA 表示。顺便说一下,如果 x 是一个包括 所有训练数据的 × 矩阵,这也是一种向量化的实现方式,上面的式子可以 让你一次对所有的训练样本计算出 xrot 和 。得到的 xrot 和 中,每列对应一 个训练样本。 为计算 PCA 白化后的数据 ,可以用 xPCAwhite = diag(1./sqrt(diag(S) + epsilon)) * U' * x; 因为 S 的对角线包括了特征值 ,这其实就是同时为所有样本 计 算 的简洁表达。 最后,你也可以这样计算 ZCA 白化后的数据 : xZCAwhite = U * diag(1./sqrt(diag(S) + epsilon)) * U' * x; 中英文对照 主成分分析 Principal Components Analysis (PCA) 白化 whitening 均值为零 zero-mean 均值 mean value 特征值 eigenvalue 特征向量 eigenvector 对称半正定矩阵 symmetric positive semi-definite matrix 数值计算上稳定 numerically reliable 降序排列 sorted in decreasing order 奇异值 singular value 奇异向量 singular vector 向量化实现 vectorized implementation 对角线 diagonal Softmax 回归 Softmax 回归 Contents [hide] 1 简介 2 代价函数 3 Softmax 回归模型参数化的特点 4 权重衰减 5 Softmax 回归与 Logistic 回归的关系 6 Softmax 回归 vs. k 个二元分类器 7 中英文对照 8 中文译者 简介 在本节中,我们介绍 Softmax 回归模型,该模型是 logistic 回归模型在多分类问 题上的推广,在多分类问题中,类标签 可以取两个以上的值。 Softmax 回归 模型对于诸如 MNIST 手写数字分类等问题是很有用的,该问题的目的是辨识 10 个不同的单个数字。Softmax 回归是有监督的,不过后面也会介绍它与深度 学习/无监督学习方法的结合。(译者注: MNIST 是一个手写数字识别库,由 NYU 的 Yann LeCun 等人维护。http://yann.lecun.com/exdb/mnist/ ) 回想一下在 logistic 回归中,我们的训练集由 个已标记的样本构成: ,其中输入特征 。(我们对符 号的约定如下:特征向量 的维度为 ,其中 对应截距项 。) 由于 logistic 回归是针对二分类问题的,因此类标记 。假设函数 (hypothesis function) 如下: 我们将训练模型参数 ,使其能够最小化代价函数 : 在 softmax 回归中,我们解决的是多分类问题(相对于 logistic 回归解决的二分 类问题),类标 可以取 个不同的值(而不是 2 个)。因此,对于训练 集 ,我们有 。(注意 此处的类别下标从 1 开始,而不是 0)。例如,在 MNIST 数字识别任务中,我 们有 个不同的类别。 对于给定的测试输入 ,我们想用假设函数针对每一个类别 j 估算出概率 值 。也就是说,我们想估计 的每一种分类结果出现的概率。因 此,我们的假设函数将要输出一个 维的向量(向量元素的和为 1)来表示 这 个估计的概率值。 具体地说,我们的假设函数 形式如下: 其中 是模型的参数。请注意 这一项对 概率分布进行归一化,使得所有概率之和为 1 。 为了方便起见,我们同样使用符号 来表示全部的模型参数。在实现 Softmax 回归时,将 用一个 的矩阵来表示会很方便,该矩阵是 将 按行罗列起来得到的,如下所示: 代价函数 现在我们来介绍 softmax 回归算法的代价函数。在下面的公式中, 是示性 函数,其取值规则为: 值为真的表达式 , 值为假的表达式 。举例来说,表达 式 的值为 1 , 的值为 0。我 们的代价函数为: 值得注意的是,上述公式是 logistic 回归代价函数的推广。logistic 回归代价函数 可以改为: 可以看到,Softmax 代价函数与 logistic 代价函数在形式上非常类似,只是在 Softmax 损失函数中对类标记的 个可能值进行了累加。注意在 Softmax 回归中 将 分类为类别 的概率为: . 对于 的最小化问题,目前还没有闭式解法。因此,我们使用迭代的优化 算法(例如梯度下降法,或 L-BFGS)。经过求导,我们得到梯度公式如下: 让我们来回顾一下符号 "" 的含义。 本身是一个向量,它的第 个元 素 是 对 的第 个分量的偏导数。 有了上面的偏导数公式以后,我们就可以将它代入到梯度下降法等算法中,来 最小化 。 例如,在梯度下降法的标准实现中,每一次迭代需要进行如下更 新: ()。 当实现 softmax 回归算法时, 我们通常会使用上述代价函数的一个改进版本。 具体来说,就是和权重衰减(weight decay)一起使用。我们接下来介绍使用它的 动机和细节。 Softmax 回归模型参数化的特点 Softmax 回归有一个不寻常的特点:它有一个“冗余”的参数集。为了便于阐述这 一特点,假设我们从参数向量 中减去了向量 ,这时,每一个 都变成 了 ()。此时假设函数变成了以下的式子: 换句话说,从 中减去 完全不影响假设函数的预测结果!这表明前面的 softmax 回归模型中存在冗余的参数。更正式一点来说, Softmax 模型被过度参 数化了。对于任意一个用于拟合数据的假设函数,可以求出多组参数值,这些 参数得到的是完全相同的假设函数 。 进一步而言,如果参数 是代价函数 的极小值点,那 么 同样也是它的极小值点,其中 可以为任意向量。 因此使 最小化的解不是唯一的。(有趣的是,由于 仍然是一个凸函数, 因此梯度下降时不会遇到局部最优解的问题。但是 Hessian 矩阵是奇异的/不可 逆的,这会直接导致采用牛顿法优化就遇到数值计算的问题) 注意,当 时,我们总是可以将 替换为 (即替换为全 零向量),并且这种变换不会影响假设函数。因此我们可以去掉参数向 量 (或者其他 中的任意一个)而不影响假设函数的表达能力。实际上, 与其优化全部的 个参数 (其中 ),我们可以 令 ,只优化剩余的 个参数,这样算法依然能够正常工 作。 在实际应用中,为了使算法实现更简单清楚,往往保留所有参数 , 而不任意地将某一参数设置为 0。但此时我们需要对代价函数做一个改动:加 入权重衰减。权重衰减可以解决 softmax 回归的参数冗余所带来的数值问题。 权重衰减 我们通过添加一个权重衰减项 来修改代价函数,这个衰减项会 惩罚过大的参数值,现在我们的代价函数变为: 有了这个权重衰减项以后 (),代价函数就变成了严格的凸函数,这样就可 以保证得到唯一的解了。 此时的 Hessian 矩阵变为可逆矩阵,并且因为 是凸 函数,梯度下降法和 L-BFGS 等算法可以保证收敛到全局最优解。 为了使用优化算法,我们需要求得这个新函数 的导数,如下: 通过最小化 ,我们就能实现一个可用的 softmax 回归模型。 Softmax 回归与 Logistic 回归的关系 当类别数 时,softmax 回归退化为 logistic 回归。这表明 softmax 回归是 logistic 回归的一般形式。具体地说,当 时,softmax 回归的假设函数为: 利用 softmax 回归参数冗余的特点,我们令 ,并且从两个参数向量中都 减去向量 ,得到: 因此,用 来表示 ,我们就会发现 softmax 回归器预测其中一个类别的概 率为 ,另一个类别概率的为 ,这与 logistic 回归是 一致的。 Softmax 回归 vs. k 个二元分类器 如果你在开发一个音乐分类的应用,需要对 k 种类型的音乐进行识别,那么是 选择使用 softmax 分类器呢,还是使用 logistic 回归算法建立 k 个独立的二元分 类器呢? 这一选择取决于你的类别之间是否互斥,例如,如果你有四个类别的音乐,分 别为:古典音乐、乡村音乐、摇滚乐和爵士乐,那么你可以假设每个训练样本 只会被打上一个标签(即:一首歌只能属于这四种音乐类型的其中一种),此 时你应该使用类别数 k = 4 的 softmax 回归。(如果在你的数据集中,有的歌曲 不属于以上四类的其中任何一类,那么你可以添加一个“其他类”,并将类别 数 k 设为 5。) 如果你的四个类别如下:人声音乐、舞曲、影视原声、流行歌曲,那么这些类 别之间并不是互斥的。例如:一首歌曲可以来源于影视原声,同时也包含人声 。 这种情况下,使用 4 个二分类的 logistic 回归分类器更为合适。这样,对于每个 新的音乐作品 ,我们的算法可以分别判断它是否属于各个类别。 现在我们来看一个计算视觉领域的例子,你的任务是将图像分到三个不同类别 中。(i) 假设这三个类别分别是:室内场景、户外城区场景、户外荒野场景。你 会使用 sofmax 回归还是 3 个 logistic 回归分类器呢? (ii) 现在假设这三个类别分 别是室内场景、黑白图片、包含人物的图片,你又会选择 softmax 回归还是多 个 logistic 回归分类器呢? 在第一个例子中,三个类别是互斥的,因此更适于选择 softmax 回归分类器 。 而在第二个例子中,建立三个独立的 logistic 回归分类器更加合适。 中英文对照 Softmax 回归 Softmax Regression 有监督学习 supervised learning 无监督学习 unsupervised learning 深度学习 deep learning logistic 回归 logistic regression 截距项 intercept term 二元分类 binary classification 类型标记 class labels 估值函数/估计值 hypothesis 代价函数 cost function 多元分类 multi-class classification 权重衰减 weight decay 自我学习与无监督特征学习 自我学习 Contents [hide] 1 综述 2 特征学习 3 数据预处理 4 无监督特征学习的术语 5 中英文对照 6 中文译者 综述 如果已经有一个足够强大的机器学习算法,为了获得更好的性能,最靠谱的方 法之一是给这个算法以更多的数据。机器学习界甚至有个说法:“有时候胜出者 并非有最好的算法,而是有更多的数据。” 人们总是可以尝试获取更多的已标注数据,但是这样做成本往往很高。例如研 究人员已经花了相当的精力在使用类似 AMT(Amazon Mechanical Turk) 这样的 工具上,以期获取更大的训练数据集。相比大量研究人员通过手工方式构建特 征,用众包的方式让多人手工标数据是一个进步,但是我们可以做得更好。具 体的说,如果算法能够从未标注数据中学习,那么我们就可以轻易地获取大量 无标注数据,并从中学习。自学习和无监督特征学习就是这种的算法。尽管一 个单一的未标注样本蕴含的信息比一个已标注的样本要少,但是如果能获取大 量无标注数据(比如从互联网上下载随机的、无标注的图像、音频剪辑或者是 文本),并且算法能够有效的利用它们,那么相比大规模的手工构建特征和标 数据,算法将会取得更好的性能。 在自学习和无监督特征学习问题上,可以给算法以大量的未标注数据,学习出 较好的特征描述。在尝试解决一个具体的分类问题时,可以基于这些学习出的 特征描述和任意的(可能比较少的)已标注数据,使用有监督学习方法完成分 类。 在一些拥有大量未标注数据和少量的已标注数据的场景中,上述思想可能是最 有效的。即使在只有已标注数据的情况下(这时我们通常忽略训练数据的类标 号进行特征学习),以上想法也能得到很好的结果。 特征学习 我们已经了解到如何使用一个自编码器(autoencoder)从无标注数据中学习特 征。具体来说,假定有一个无标注的训练数据集 (下 标 代表“不带类标”)。现在用它们训练一个稀疏自编码器(可能需要首先对 这些数据做白化或其它适当的预处理)。 利用训练得到的模型参数 ,给定任意的输入数据 ,可 以计算隐藏单元的激活量(activations) 。如前所述,相比原始输入 来说, 可能是一个更好的特征描述。下图的神经网络描述了特征(激活量 )的计 算。 这实际上就是之前得到的稀疏自编码器,在这里去掉了最后一层。 假定有大小为 的已标注训练 集 (下标 表示“带类标”), 我们可以为输入数据找到更好的特征描述。例如,可以将 输入到稀疏自编 码器,得到隐藏单元激活量 。接下来,可以直接使用 来代替原始数 据 (“替代表示”,Replacement Representation)。也可以合二为一,使用新 的向量 来代替原始数据 (“级联表示”,Concatenation Representation)。 经过变换后,训练集就变成 或 者是 (取决于使用 替换 还是将二者合并)。在实践中,将 和 合 并通常表现的更好。但是考虑到内存和计算的成本,也可以使用替换操作。 最终,可以训练出一个有监督学习算法(例如 svm, logistic regression 等),得 到一个判别函数对 值进行预测。预测过程如下:给定一个测试样本 , 重复之前的过程,将其送入稀疏自编码器,得到 。然后将 (或 者 )送入分类器中,得到预测值。 数据预处理 在特征学习阶段,我们从未标注训练集 中学习,这一 过程中可能计算了各种数据预处理参数。例如计算数据均值并且对数据做均值 标准化(mean normalization);或者对原始数据做主成分分析(PCA),然后 将原始数据表示为 (又或者使用 PCA 白化或 ZCA 白化)。这样的话,有必 要将这些参数保存起来,并且在后面的训练和测试阶段使用同样的参数,以保 证数据进入稀疏自编码神经网络之前经过了同样的变换。例如,如果对未标注 数据集进行 PCA 预处理,就必须将得到的矩阵 保存起来,并且应用到有标 注训练集和测试集上;而不能使用有标注训练集重新估计出一个不同的矩 阵 (也不能重新计算均值并做均值标准化),否则的话可能得到一个完全不 一致的数据预处理操作,导致进入自编码器的数据分布迥异于训练自编码器时 的数据分布。 无监督特征学习的术语 有两种常见的无监督特征学习方式,区别在于你有什么样的未标注数据。自学 习(self-taught learning) 是其中更为一般的、更强大的学习方式,它不要求未标 注数据 和已标注数据 来自同样的分布。另外一种带限制性的方式也被称 为半监督学习,它要求 和 服从同样的分布。下面通过例子解释二者的区 别。 假定有一个计算机视觉方面的任务,目标是区分汽车和摩托车图像;也即训练 样本里面要么是汽车的图像,要么是摩托车的图像。哪里可以获取大量的未标 注数据呢?最简单的方式可能是从互联网上下载一些随机的图像数据集,在这 些数据上训练出一个稀疏自编码器,从中得到有用的特征。这个例子里,未标 注数据完全来自于一个和已标注数据不同的分布(未标注数据集中,或许其中 一些图像包含汽车或者摩托车,但是不是所有的图像都如此)。这种情形被称 为自学习。 相反,如果有大量的未标注图像数据,要么是汽车图像,要么是摩托车图像, 仅仅是缺失了类标号(没有标注每张图片到底是汽车还是摩托车)。也可以用 这些未标注数据来学习特征。这种方式,即要求未标注样本和带标注样本服从 相同的分布,有时候被称为半监督学习。在实践中,常常无法找到满足这种要 求的未标注数据(到哪里找到一个每张图像不是汽车就是摩托车,只是丢失了 类标号的图像数据库?)因此,自学习在无标注数据集的特征学习中应用更广。 中英文对照 自我学习/自学习 self-taught learning 无监督特征学习 unsupervised feature learning 自编码器 autoencoder 白化 whitening 激活量 activation 稀疏自编码器 sparse autoencoder 半监督学习 semi-supervised learning Building Deep Networks for Classification 从自我学习到深层网络 在前一节中,我们利用自编码器来学习输入至 softmax 或 logistic 回归分类器的 特征。这些特征仅利用未标注数据学习获得。在本节中,我们描述如何利用已 标注数据进行微调,从而进一步优化这些特征。如果有大量已标注数据,通过 微调就可以显著提升分类器的性能。 在自我学习中,我们首先利用未标注数据训练一个稀疏自编码器。随后,给定 一个新样本 ,我们通过隐含层提取出特征 。上述过程图示如下: 我们感兴趣的是分类问题,目标是预测样本的类别标号 。我们拥有标注数据 集 ,包含 个标注样本。此前我们已经 说明,可以利用稀疏自编码器获得的特征 来替代原始特征。这样就可获得 训练数据集 。最终,我们训练出一个从特征 到类 标号 的 logistic 分类器。为说明这一过程,我们按照神经网络一节中的方式, 用下图描述 logistic 回归单元(橘黄色)。 考虑利用这个方法所学到的分类器(输入-输出映射)。它描述了一个把测试样 本 映射到预测值 的函数。将此前的两张图片结合起来,就得到该 函数的图形表示。也即,最终的分类器可以表示为: 该模型的参数通过两个步骤训练获得:在该网络的第一层,将输入 映射至隐 藏单元激活量 的权值 可以通过稀疏自编码器训练过程获得。在第二层, 将隐藏单元 映射至输出 的权值 可以通过 logistic 回归或 softmax 回归训 练获得。 这个最终分类器整体上显然是一个大的神经网络。因此,在训练获得模型最初 参数(利用自动编码器训练第一层,利用 logistic/softmax 回归训练第二层)之 后,我们可以进一步修正模型参数,进而降低训练误差。具体来说,我们可以 对参数进行微调,在现有参数的基础上采用梯度下降或者 L-BFGS 来降低已标 注样本集 上的训练误差。 使用微调时,初始的非监督特征学习步骤(也就是自动编码器和 logistic 分类器 训练)有时候被称为预训练。微调的作用在于,已标注数据集也可以用来修正 权值 ,这样可以对隐藏单元所提取的特征 做进一步调整。 到现在为止,我们描述上述过程时,都假设采用了“替代 (Replacement)”表示而 不是“级联 (Concatenation)”表示。在替代表示中,logistic 分类器所看到的训练 样本格式为 ;而在级联表示中,分类器所看到的训练样本格式 为 。对级联表示同样可以进行微调(在级联表示神经网络中,输 入值 也直接被输入至 logistic 分类器。对此前的神经网络示意图稍加更改, 即可获得其示意图。具体的说,第一层的输入节点除了与隐层联接之外,还将 越过隐层,与第三层输出节点直接相连)。但是对于微调来说,级联表示相对 于替代表示几乎没有优势。因此,如果需要开展微调,我们通常使用替代表示 的网络(但是如果不开展微调,级联表示的效果有时候会好得多)。 在什么时候应用微调?通常仅在有大量已标注训练数据的情况下使用。在这样 的情况下,微调能显著提升分类器性能。然而,如果有大量未标注数据集(用 于非监督特征学习/预训练),却只有相对较少的已标注训练集,微调的作用非 常有限。 中英文对照 自我学习 self-taught learning 深层网络 deep networks 微调 fine-tune 稀疏自编码器 sparse autoencoder 梯度下降 gradient descent 非监督特征学习 unsupervised feature learning 预训练 pre-training 深度网络概览 Contents [hide] 1 概述 2 深度网络的优势 3 训练深度网络的困难 o 3.1 数据获取问题 o 3.2 局部极值问题 o 3.3 梯度弥散问题 4 逐层贪婪训练方法 o 4.1 数据获取 o 4.2 更好的局部极值 5 中英文对照 6 中文译者 概述 在之前的章节中,你已经构建了一个包括输入层、隐藏层以及输出层的三层神 经网络。虽然该网络对于 MNIST 手写数字数据库非常有效,但是它还是一个非 常“浅”的网络。这里的“浅”指的是特征(隐藏层的激活值 )只使用一层计 算单元(隐藏层)来得到的。 在本节中,我们开始讨论深度神经网络,即含有多个隐藏层的神经网络。通过 引入深度网络,我们可以计算更多复杂的输入特征。因为每一个隐藏层可以对 上一层的输出进行非线性变换,因此深度神经网络拥有比“浅层”网络更加优异 的表达能力(例如可以学习到更加复杂的函数关系)。 值得注意的是当训练深度网络的时候,每一层隐层应该使用非线性的激活函 数 。这是因为多层的线性函数组合在一起本质上也只有线性函数的表达能 力(例如,将多个线性方程组合在一起仅仅产生另一个线性方程)。因此,在 激活函数是线性的情况下,相比于单隐藏层神经网络,包含多隐藏层的深度网 络并没有增加表达能力。 深度网络的优势 为什么我们要使用深度网络呢?使用深度网络最主要的优势在于,它能以更加 紧凑简洁的方式来表达比浅层网络大得多的函数集合。正式点说,我们可以找 到一些函数,这些函数可以用 层网络简洁地表达出来(这里的简洁是指隐层 单元的数目只需与输入单元数目呈多项式关系)。但是对于一个只有 层 的网络而言,除非它使用与输入单元数目呈指数关系的隐层单元数目,否则不 能简洁表达这些函数。 举一个简单的例子,比如我们打算构建一个布尔网络来计算 个输入比特的奇 偶校验码(或者进行异或运算)。假设网络中的每一个节点都可以进行逻辑“或” 运算(或者“与非”运算),亦或者逻辑“与”运算。如果我们拥有一个仅仅由一 个输入层、一个隐层以及一个输出层构成的网络,那么该奇偶校验函数所需要 的节点数目与输入层的规模 呈指数关系。但是,如果我们构建一个更深点的 网络,那么这个网络的规模就可做到仅仅是 的多项式函数。 当处理对象是图像时,我们能够使用深度网络学习到“部分-整体”的分解关系。 例如,第一层可以学习如何将图像中的像素组合在一起来检测边缘(正如我们 在前面的练习中做的那样)。第二层可以将边缘组合起来检测更长的轮廓或者 简单的“目标的部件”。在更深的层次上,可以将这些轮廓进一步组合起来以检 测更为复杂的特征。 最后要提的一点是,大脑皮层同样是分多层进行计算的。例如视觉图像在人脑 中是分多个阶段进行处理的,首先是进入大脑皮层的“V1”区,然后紧跟着进入 大脑皮层“V2”区,以此类推。 训练深度网络的困难 虽然几十年前人们就发现了深度网络在理论上的简洁性和较强的表达能力,但 是直到最近,研究者们也没有在训练深度网络方面取得多少进步。 问题原因在 于研究者们主要使用的学习算法是:首先随机初始化深度网络的权重,然后使 用有监督的目标函数在有标签的训练集 上进行训练。 例如通过使用梯度下降法来降低训练误差。然而,这种方法通常不是十分奏效。 这其中有如下几方面原因: 数据获取问题 使用上面提到的方法,我们需要依赖于有标签的数据才能进行训练。然而有标 签的数据通常是稀缺的,因此对于许多问题,我们很难获得足够多的样本来拟 合一个复杂模型的参数。例如,考虑到深度网络具有强大的表达能力,在不充 足的数据上进行训练将会导致过拟合。 局部极值问题 使用监督学习方法来对浅层网络(只有一个隐藏层)进行训练通常能够使参数 收敛到合理的范围内。但是当用这种方法来训练深度网络的时候,并不能取得 很好的效果。特别的,使用监督学习方法训练神经网络时,通常会涉及到求解 一个高度非凸的优化问题(例如最小化训练误差 ,其中参 数 是要优化的参数。对深度网络而言,这种非凸优化问题的搜索区域中充斥 着大量“坏”的局部极值,因而使用梯度下降法(或者像共轭梯度下降法,L- BFGS 等方法)效果并不好。 梯度弥散问题 梯度下降法(以及相关的 L-BFGS 算法等)在使用随机初始化权重的深度网络 上效果不好的技术原因是:梯度会变得非常小。具体而言,当使用反向传播方 法计算导数的时候,随着网络的深度的增加,反向传播的梯度(从输出层到网 络的最初几层)的幅度值会急剧地减小。结果就造成了整体的损失函数相对于 最初几层的权重的导数非常小。这样,当使用梯度下降法的时候,最初几层的 权重变化非常缓慢,以至于它们不能够从样本中进行有效的学习。这种问题通 常被称为“梯度的弥散”. 与梯度弥散问题紧密相关的问题是:当神经网络中的最后几层含有足够数量神 经元的时候,可能单独这几层就足以对有标签数据进行建模,而不用最初几层 的帮助。因此,对所有层都使用随机初始化的方法训练得到的整个网络的性能 将会与训练得到的浅层网络(仅由深度网络的最后几层组成的浅层网络)的性 能相似。 逐层贪婪训练方法 那么,我们应该如何训练深度网络呢?逐层贪婪训练方法是取得一定成功的一 种方法。我们会在后面的章节中详细阐述这种方法的细节。简单来说,逐层贪 婪算法的主要思路是每次只训练网络中的一层,即我们首先训练一个只含一个 隐藏层的网络,仅当这层网络训练结束之后才开始训练一个有两个隐藏层的网 络,以此类推。在每一步中,我们把已经训练好的前 层固定,然后增加 第 层(也就是将我们已经训练好的前 的输出作为输入)。每一层的训练 可以是有监督的(例如,将每一步的分类误差作为目标函数),但更通常使用 无监督方法(例如自动编码器,我们会在后边的章节中给出细节)。这些各层 单独训练所得到的权重被用来初始化最终(或者说全部)的深度网络的权重, 然后对整个网络进行“微调”(即把所有层放在一起来优化有标签训练集上的训 练误差)。 逐层贪婪的训练方法取得成功要归功于以下几方面: 数据获取 虽然获取有标签数据的代价是昂贵的,但获取大量的无标签数据是容易 的。自学习方法(self-taught learning)的潜力在于它能通过使用大量的无标签 数据来学习到更好的模型。具体而言,该方法使用无标签数据来学习得到所有 层(不包括用于预测标签的最终分类层) 的最佳初始权重。相比纯监督学 习方法,这种自学习方法能够利用多得多的数据,并且能够学习和发现数据中 存在的模式。因此该方法通常能够提高分类器的性能。 更好的局部极值 当用无标签数据训练完网络后,相比于随机初始化而言,各层初始权重 会位于参数空间中较好的位置上。然后我们可以从这些位置出发进一步微调权 重。从经验上来说,以这些位置为起点开始梯度下降更有可能收敛到比较好的 局部极值点,这是因为无标签数据已经提供了大量输入数据中包含的模式的先 验信息。 在下一节中,我们将会具体阐述如何进行逐层贪婪训练。 中英文对照 深度网络 Deep Networks 深度神经网络 deep neural networks 非线性变换 non-linear transformation 激活函数 activation function 简洁地表达 represent compactly “部分-整体”的分解 part-whole decompositions 目标的部件 parts of objects 高度非凸的优化问题 highly non-convex optimization problem 共轭梯度 conjugate gradient 梯度的弥散 diffusion of gradients 逐层贪婪训练方法 Greedy layer-wise training 自动编码器 autoencoder 微调 fine-tuned 自学习方法 self-taught learning 栈式自编码算法 Contents [hide] 1 概述 2 训练 3 具体实例 4 讨论 5 中英文对照 6 中文译者 概述 逐层贪婪训练法依次训练网络的每一层,进而预训练整个深度神经网络。在本 节中,我们将会学习如何将自编码器“栈化”到逐层贪婪训练法中,从而预训练 (或者说初始化)深度神经网络的权重。 栈式自编码神经网络是一个由多层稀疏自编码器组成的神经网络,其前一层自 编码器的输出作为其后一层自编码器的输入。对于一个 层栈式自编码神经网 络,我们沿用自编码器一章的各种符号,假定用 表示 第 个自编码器对应的 参数,那么该栈式自编码神经网络的 编码过程就是,按照从前向后的顺序执行每一层自编码器的编码步骤: 同理,栈式神经网络的解码过程就是,按照从后向前的顺序执行每一层自编码 器的解码步骤: 其中, 是最深层隐藏单元的激活值,其包含了我们感兴趣的信息,这个向 量也是对输入值的更高阶的表示。 通过将 作为 softmax 分类器的输入特征,可以将栈式自编码神经网络中学 到的特征用于分类问题。 训练 一种比较好的获取栈式自编码神经网络参数的方法是采用逐层贪婪训练法进行 训练。即先利用原始输入来训练网络的第一层,得到其参 数 ;然后网络第一层将原始输入转化成为由隐藏单元激 活值组成的向量(假设该向量为 A),接着把 A 作为第二层的输入,继续训练 得到第二层的参数 ;最后,对后面的各层同样采用的策 略,即将前层的输出作为下一层输入的方式依次训练。 对于上述训练方式,在训练每一层参数的时候,会固定其它各层参数保 持不变。所以,如果想得到更好的结果,在上述预训练过程完成之后,可以通 过反向传播算法同时调整所有层的参数以改善结果,这个过程一般被称作“微调 (fine-tuning)”。 实际上,使用逐层贪婪训练方法将参数训练到快要收敛时,应该使用微 调。反之,如果直接在随机化的初始权重上使用微调,那么会得到不好的结果, 因为参数会收敛到局部最优。 如果你只对以分类为目的的微调感兴趣,那么惯用的做法是丢掉栈式自 编码网络的“解码”层,直接把最后一个隐藏层的 作为特征输入到 softmax 分 类器进行分类,这样,分类器(softmax)的分类错误的梯度值就可以直接反向 传播给编码层了。 具体实例 让我们来看个具体的例子,假设你想要训练一个包含两个隐含层的栈式自编码 网络,用来进行 MNIST 手写数字分类(这将会是你的下一个练习)。 首先, 你需要用原始输入 训练第一个自编码器,它能够学习得到原始输入的一阶 特征表示 (如下图所示)。 接着,你需要把原始数据输入到上述训练好的稀疏自编码器中,对于每一个输 入 ,都可以得到它对应的一阶特征表示 。然后你再用这些一阶特征作为 另一个稀疏自编码器的输入,使用它们来学习二阶特征 。(如下图所示) 同样,再把一阶特征输入到刚训练好的第二层稀疏自编码器中,得到每 个 对应的二阶特征激活值 。接下来,你可以把这些二阶特征作为 softmax 分类器的输入,训练得到一个能将二阶特征映射到数字标签的模型。 如下图所示,最终,你可以将这三层结合起来构建一个包含两个隐藏层 和一个最终 softmax 分类器层的栈式自编码网络,这个网络能够如你所愿地对 MNIST 数字进行分类。 讨论 栈式自编码神经网络具有强大的表达能力及深度神经网络的所有优点。 更进一步,它通常能够获取到输入的“层次型分组”或者“部分-整体分解”结构。 为了弄清这一点,回顾一下,自编码器倾向于学习得到能更好地表示输入数据 的特征。因此,栈式自编码神经网络的第一层会学习得到原始输入的一阶特征 (比如图片里的边缘),第二层会学习得到二阶特征,该特征对应一阶特征里 包含的一些模式(比如在构成轮廓或者角点时,什么样的边缘会共现)。栈式 自编码神经网络的更高层还会学到更高阶的特征。 举个例子,如果网络的输入数据是图像,网络的第一层会学习如何去识别边, 第二层一般会学习如何去组合边,从而构成轮廓、角等。更高层会学习如何去 组合更形象且有意义的特征。例如,如果输入数据集包含人脸图像,更高层会 学习如何识别或组合眼睛、鼻子、嘴等人脸器官。 中英文对照 自编码器 Autoencoder 逐层贪婪训练法 Greedy layer-wise training 预训练 PreTrain 栈式自编码神经网络 Stacked autoencoder 微调 Fine-tuning 原始输入 Raw inputs 层次型分组 Hierarchical grouping 部分-整体分解 Part-whole decomposition 一阶特征 First-order features 二阶特征 Second-order features 更高阶特征 Higher-order features 激活值 Activation 微调多层自编码算法 Contents [hide] 1 介绍 2 一般策略 3 使用反向传播法进行微调 4 中英文对照 5 中文译者 介绍 微调是深度学习中的常用策略,可以大幅提升一个栈式自编码神经网络的性能 表现。从更高的视角来讲,微调将栈式自编码神经网络的所有层视为一个模型, 这样在每次迭代中,网络中所有的权重值都可以被优化。 一般策略 幸运的是,实施微调栈式自编码神经网络所需的工具都已齐备!为了在每次迭 代中计算所有层的梯度,我们需要使用稀疏自动编码一节中讨论的反向传播算 法。因为反向传播算法可以延伸应用到任意多层,所以事实上,该算法对任意 多层的栈式自编码神经网络都适用。 使用反向传播法进行微调 为方便读者,以下我们简要描述如何实施反向传播算法: 1. 进行一次前馈传递,对 层、 层直到输出层 ,使用前向传播步骤中定义 的公式计算各层上的激活值(激励响应)。 2. 对输出层( 层),令 (当使用 softmax 分类器时,softmax 层满足:,其中 为输入 数据对应的类别标签, 为条件概率向量。) 3. 对 令 4. 计算所需的偏导数: 注:我们可以认为输出层 softmax 分类器是附加上的一层,但是其求导过程需 要单独处理。具体地说,网络“最后一层”的特征会进入 softmax 分类器。所以, 第二步中的导数由 计算,其中 。 中英文对照 栈式自编码神经网络(可以考虑翻译为“多层自动编码机”或“多层自动编码神经 网络”) Stacked autoencoder 微调 Fine tuning 反向传播算法 Backpropagation Algorithm 前馈传递 feedforward pass 激活值 (可以考虑翻译为“激励响应”或“响应”) activation Linear Decoders with Autoencoders 线性解码器 Contents [hide] 1 稀疏自编码重述 2 线性解码器 3 中英文对照 4 中文译者 稀疏自编码重述 稀疏自编码器包含 3 层神经元,分别是输入层,隐含层以及输出层。 从前面 (神经网络)自编码器描述可知,位于神经网络中的神经元都采用相同的激励 函数。 在注解中,我们修改了自编码器定义,使得某些神经元采用不同的激励 函数。这样得到的模型更容易应用,而且模型对参数的变化也更为鲁棒。 回想一下,输出层神经元计算公式如下: 其中 a(3) 是输出。在自编码器中,a(3) 近似重构了输入 x = a(1)。 S 型激励函数输出范围是 [0,1],当 f(z(3)) 采用该激励函数时,就要对输入限制或 缩放,使其位于 [0,1]范围中。一些数据集,比如 MNIST,能方便将输出缩放到 [0,1] 中,但是很难满足对输入值的要求。比如, PCA 白化处理的输入并不满 足 [0,1] 范围要求,也不清楚是否有最好的办法可以将数据缩放到特定范围中。 线性解码器 设定 a(3) = z(3) 可以很简单的解决上述问题。从形式上来看,就是输出端使用恒 等函数 f(z) = z 作为激励函数,于是有 a(3) = f(z(3)) = z(3)。我们称该特殊的激励函 数为 线性激励函数 (称为恒等激励函数可能更好些)。 需要注意,神经网络中隐含层的神经元依然使用 S 型(或者 tanh)激励函数。 这样隐含单元的激励公式为 ,其中 是 S 型函数, x 是输 入,W(1) 和 b(1) 分别是隐单元的权重和偏差项。我们仅在输出层中使用线性激 励函数。 一个 S 型或 tanh 隐含层以及线性输出层构成的自编码器,我们称为线性解码器。 在这个线性解码器模型中,。因为输出 是隐单元 激励输出的线性函数,改变 W(2) ,可以使输出值 a(3) 大于 1 或者小于 0。这使 得我们可以用实值输入来训练稀疏自编码器,避免预先缩放样本到给定范围。 随着输出单元的激励函数的改变,这个输出单元梯度也相应变化。回顾之前每 一个输出单元误差项定义为: 其中 y = x 是所期望的输出, 是自编码器的输出, 是激励函数.因为在输 出层激励函数为 f(z) =z, 这样 f'(z) = 1,所以上述公式可以简化为 当然,若使用反向传播算法来计算隐含层的误差项时: 因为隐含层采用一个 S 型(或 tanh)的激励函数 f,在上述公式中, 依然是 S 型(或 tanh)函数的导数。 中英文对照 线性解码器 Linear Decoders 稀疏自编码 Sparse Autoencoder 输入层 input layer 隐含层 hidden layer 输出层 output layer 神经元 neuron 神经网络 neural network 自编码器 autoencoder 激励函数 activation function 鲁棒 robust S 型激励函数 sigmoid activation function tanh 激励函数 tanh function 线性激励函数 linear activation function 恒等激励函数 identity activation function 隐单元 hidden unit 权重 weight 偏差项 error term 反向传播算法 backpropagation Working with Large Images 卷积特征提取 Contents [hide] 1 概述 2 全联通网络 3 部分联通网络 4 卷积 5 中英文对照 6 中文译者 概述 前面的练习中,解决了一些有关低分辨率图像的问题,比如:小块图像,手写 数字小幅图像等。在这部分中,我们将把已知的方法扩展到实际应用中更加常 见的大图像数据集。 全联通网络 在稀疏自编码章节中,我们介绍了把输入层和隐含层进行“全连接”的设 计。从计算的角度来讲,在其他章节中曾经用过的相对较小的图像(如在稀疏 自编码的作业中用到过的 8x8 的小块图像,在 MNIST 数据集中用到过的 28x28 的小块图像),从整幅图像中计算特征是可行的。但是,如果是更大的图像 (如 96x96 的图像),要通过这种全联通网络的这种方法来学习整幅图像上的 特征,从计算角度而言,将变得非常耗时。你需要设计 10 的 4 次方(=10000) 个输入单元,假设你要学习 100 个特征,那么就有 10 的 6 次方个参数需要去学 习。与 28x28 的小块图像相比较, 96x96 的图像使用前向输送或者后向传导的 计算方式,计算过程也会慢 10 的 2 次方(=100)倍。 部分联通网络 解决这类问题的一种简单方法是对隐含单元和输入单元间的连接加以限制:每 个隐含单元仅仅只能连接输入单元的一部分。例如,每个隐含单元仅仅连接输 入图像的一小片相邻区域。(对于不同于图像输入的输入形式,也会有一些特 别的连接到单隐含层的输入信号“连接区域”选择方式。如音频作为一种信号输 入方式,一个隐含单元所需要连接的输入单元的子集,可能仅仅是一段音频输 入所对应的某个时间段上的信号。) 网络部分连通的思想,也是受启发于生物学里面的视觉系统结构。视觉皮层的 神经元就是局部接受信息的(即这些神经元只响应某些特定区域的刺激)。 卷积 自然图像有其固有特性,也就是说,图像的一部分的统计特性与其他部分是一 样的。这也意味着我们在这一部分学习的特征也能用在另一部分上,所以对于 这个图像上的所有位置,我们都能使用同样的学习特征。 更恰当的解释是,当从一个大尺寸图像中随机选取一小块,比如说 8x8 作为样 本,并且从这个小块样本中学习到了一些特征,这时我们可以把从这个 8x8 样 本中学习到的特征作为探测器,应用到这个图像的任意地方中去。特别是,我 们可以用从 8x8 样本中所学习到的特征跟原本的大尺寸图像作卷积,从而对这 个大尺寸图像上的任一位置获得一个不同特征的激活值。 下面给出一个具体的例子:假设你已经从一个 96x96 的图像中学习到了它的一 个 8x8 的样本所具有的特征,假设这是由有 100 个隐含单元的自编码完成的。 为了得到卷积特征,需要对 96x96 的图像的每个 8x8 的小块图像区域都进行卷 积运算。也就是说,抽取 8x8 的小块区域,并且从起始坐标开始依次标记为(1, 1),(1,2),...,一直到(89,89),然后对抽取的区域逐个运行训练过的 稀疏自编码来得到特征的激活值。在这个例子里,显然可以得到 100 个集合, 每个集合含有 89x89 个卷积特征。 假设给定了 的大尺寸图像,将其定义为 xlarge。首先通过从大尺寸图像中 抽取的 的小尺寸图像样本 xsmall 训练稀疏自编码,计算 f = σ(W(1)xsmall + b(1)) (σ 是一个 sigmoid 型函数)得到了 k 个特征, 其中 W(1) 和 b(1) 是可视层单元和 隐含单元之间的权重和偏差值。对于每一个 大小的小图像 xs,计算出对应 的值 fs = σ(W(1)xs + b(1)),对这些 fconvolved 值做卷积,就可以得 到 个卷积后的特征的矩阵。 在接下来的章节里,我们会更进一步描述如何把这些特征汇总到一起以得到一 些更利于分类的特征。 中英文对照 全联通网络 Full Connected Networks 稀疏编码 Sparse Autoencoder 前向输送 Feedforward 反向传播 Backpropagation 部分联通网络 Locally Connected Networks 连接区域 Contiguous Groups 视觉皮层 Visual Cortex 卷积 Convolution 固有特征 Stationary 池化 Pool 池化 Contents [hide] 1 池化: 概述 2 池化的不变性 3 形式化描述 4 中英文对照 5 中文译者 池化: 概述 在通过卷积获得了特征 (features) 之后,下一步我们希望利用这些特征去 做分类。理论上讲,人们可以用所有提取得到的特征去训练分类器,例如 softmax 分类器,但这样做面临计算量的挑战。例如:对于一个 96X96 像素的 图像,假设我们已经学习得到了 400 个定义在 8X8 输入上的特征,每一个特征 和图像卷积都会得到一个 (96 − 8 + 1) * (96 − 8 + 1) = 7921 维的卷积特征,由于 有 400 个特征,所以每个样例 (example) 都会得到一个 892 * 400 = 3,168,400 维 的卷积特征向量。学习一个拥有超过 3 百万特征输入的分类器十分不便,并且 容易出现过拟合 (over-fitting)。 为了解决这个问题,首先回忆一下,我们之所以决定使用卷积后的特征 是因为图像具有一种“静态性”的属性,这也就意味着在一个图像区域有用的特 征极有可能在另一个区域同样适用。因此,为了描述大的图像,一个很自然的 想法就是对不同位置的特征进行聚合统计,例如,人们可以计算图像一个区域 上的某个特定特征的平均值 (或最大值)。这些概要统计特征不仅具有低得多的 维度 (相比使用所有提取得到的特征),同时还会改善结果(不容易过拟合)。这种 聚合的操作就叫做池化 (pooling),有时也称为平均池化或者最大池化 (取决于计 算池化的方法)。 下图显示池化如何应用于一个图像的四块不重合区域。 池化的不变性 如果人们选择图像中的连续范围作为池化区域,并且只是池化相同(重复) 的隐藏单元产生的特征,那么,这些池化单元就具有平移不变性 (translation invariant)。这就意味着即使图像经历了一个小的平移之后,依然会产生相同的 (池化的) 特征。在很多任务中 (例如物体检测、声音识别),我们都更希望得到 具有平移不变性的特征,因为即使图像经过了平移,样例(图像)的标记仍然保 持不变。例如,如果你处理一个 MNIST 数据集的数字,把它向左侧或右侧平移, 那么不论最终的位置在哪里,你都会期望你的分类器仍然能够精确地将其分类 为相同的数字。 (*MNIST 是一个手写数字库识别库: http://yann.lecun.com/exdb/mnist/) 形式化描述 形式上,在获取到我们前面讨论过的卷积特征后,我们要确定池化区域 的大小(假定为 ),来池化我们的卷积特征。那么,我们把卷积特征划分到 数个大小为 的不相交区域上,然后用这些区域的平均(或最大)特征来获取 池化后的卷积特征。这些池化后的特征便可以用来做分类。 中英文对照 特征 features 样例 example 过拟合 over-fitting 平移不变性 translation invariant 池化 pooling 提取 extract 物体检测 object detection 数据预处理 Contents [hide] 1 概要 2 数据归一化 o 2.1 简单缩放 o 2.2 逐样本均值消减 o 2.3 特征标准化 3 PCA/ZCA 白化 o 3.1 基于重构的模型 o 3.2 基于正交化 ICA 的模型 4 大图像 5 标准流程 o 5.1 自然灰度图像 o 5.2 彩色图像 o 5.3 音频 (MFCC/频谱图) o 5.4 MNIST 手写数字 6 中英文对照 7 中文译者 概要 数据预处理在众多深度学习算法中都起着重要作用,实际情况中,将数 据做归一化和白化处理后,很多算法能够发挥最佳效果。然而除非对这些算法 有丰富的使用经验,否则预处理的精确参数并非显而易见。在本页中,我们希 望能够揭开预处理方法的神秘面纱,同时为预处理数据提供技巧(和标准流 程)。 提示:当我们开始处理数据时,首先要做的事是观察数据并获知其特性。 本部分将介绍一些通用的技术,在实际中应该针对具体数据选择合适的预处理 技术。例如一种标准的预处理方法是对每一个数据点都减去它的均值(也被称 为移除直流分量,局部均值消减,消减归一化),这一方法对诸如自然图像这 类数据是有效的,但对非平稳的数据则不然。 数据归一化 数据预处理中,标准的第一步是数据归一化。虽然这里有一系列可行的 方法,但是这一步通常是根据数据的具体情况而明确选择的。特征归一化常用 的方法包含如下几种: (1)简单缩放 (2)逐样本均值消减(也称为移除直流分量) (3)特征标准化(使数据集中所有特征都具有零均值和单位方差) 简单缩放 在简单缩放中,我们的目的是通过对数据的每一个维度的值进行重新调节(这 些维度可能是相互独立的),使得最终的数据向量落在[0,1]或[− 1,1]的区间内 (根据数据情况而定)。这对后续的处理十分重要,因为很多默认参数(如 PCA-白化中的 epsilon)都假定数据已被缩放到合理区间。 例子:在处理自然图像时,我们获得的像素值在 [0,255] 区间中,常用的处理是 将这些像素值除以 255,使它们缩放到 [0,1] 中. 逐样本均值消减 如果你的数据是平稳的(即数据每一个维度的统计都服从相同分布),那么你 可以考虑在每个样本上减去数据的统计平均值(逐样本计算)。 例子:对于图像,这种归一化可以移除图像的平均亮度值 (intensity)。很多情况 下我们对图像的照度并不感兴趣,而更多地关注其内容,这时对每个数据点移 除像素的均值是有意义的。注意:虽然该方法广泛地应用于图像,但在处理彩 色图像时需要格外小心,具体来说,是因为不同色彩通道中的像素并不都存在 平稳特性。 说明:为什么归一化 1. (1)基本上归一化思想是利用图像的不变矩寻找一组参数使其能够消除其他 变换函数对图像变换的影响。也就是转换成唯一的标准形式以抵抗仿射变换 (2)图像归一化使得图像可以抵抗几何变换的攻击,它能够找出图像中的那些 不变量,从而得知这些图像原本就是一样的或者一个系列的。 (3)因为我们这次的图片有好多都是一个系列的。例如可以通过归一化减小医 学图片由于光线不均匀造成的干扰。 2.matlab 里图像数据有时候必须是浮点型才能处理,而图像数据本身是 0-255 的 UNIT 型数据所以需要归一化,转换到 0-1 之间。 3.归一化是一种简化计算的方式,即将有量纲的表达式,经过变换,化为无量 纲的表达式,成为纯量。 目的是为了: (1).避免具有不同物理意义和量纲的输入变量不能平等使用 (2).bp 中常采用 sigmoid 函数作为转移函数,归一化能够防止净输入绝对值过大 引起的神经元输出饱和现象 (3).保证输出数据中数值小的不被吞食 人脸图像的归一化,目的是使不同成像条件(光照强度,方向,距离, 姿势等)下拍摄的同一个人的照片具有一致性。人脸归一化包括两个方面的内 容:一是几何归一化,二是灰度归一化。几何归一化也称为位置校准,它将有 助于矫正因成像距离和人脸姿势变化造成的尺寸差异和角度倾斜。它的目的在 于解决人脸尺度变化和人脸旋转问题。具体包括人脸尺度归一化,平面人脸旋 转矫正(歪头),深度人脸旋转矫正(扭脸)三个环节。严格的深度人脸旋转 矫正需要利用人脸的 3D 模型。灰度归一化用来对不同光强,光源方向下得到 的人脸图像进行补偿。以减弱单纯由于光照变化造成的图像信号的变化。 人脸图像的尺度归一化,包括图像的平移、旋转、缩放和标准切割等。人脸 图像的缩放,顾名思义,缩放即是将图像放大或者缩小。 特征标准化 特征标准化指的是(独立地)使得数据的每一个维度具有零均值和单位 方差。这是归一化中最常见的方法并被广泛地使用(例如,在使用支持向量机 (SVM)时,特征标准化常被建议用作预处理的一部分)。在实际应用中,特 征标准化的具体做法是:首先计算每一个维度上数据的均值(使用全体数据计 算),之后在每一个维度上都减去该均值。下一步便是在数据的每一维度上除 以该维度上数据的标准差。 例子:处理音频数据时,常用 Mel 倒频系数 MFCCs 来表征数据。然而 MFCC 特 征的第一个分量(表示直流分量)数值太大,常常会掩盖其他分量。这种情况 下,为了平衡各个分量的影响,通常对特征的每个分量独立地使用标准化处理。 PCA/ZCA 白化 在做完简单的归一化后,白化通常会被用来作为接下来的预处理步骤, 它会使我们的算法工作得更好。实际上许多深度学习算法都依赖于白化来获得 好的特征。 在进行 PCA/ZCA 白化时,首先使特征零均值化是很有必要的,这保证 了 。特别地,这一步需要在计算协方差矩阵前完成。(唯一例外的情 况是已经进行了逐样本均值消减,并且数据在各维度上或像素上是平稳的。) 接下来在 PCA/ZCA 白化中我们需要选择合适的 epsilon(回忆一下,这 是规则化项,对数据有低通滤波作用)。 选取合适的 epsilon 值对特征学习起 着很大作用,下面讨论在两种不同场合下如何选取 epsilon: 基于重构的模型 在基于重构的模型中(包括自编码器,稀疏编码,受限 Boltzman 机 (RBM),k-均值(K-Means)),经常倾向于选取合适的 epsilon 以使得白化达 到低通滤波的效果。(译注:通常认为数据中的高频分量是噪声,低通滤波的 作用就是尽可能抑制这些噪声,同时保留有用的信息。在 PCA 等方法中,假设 数据的信息主要分布在方差较高的方向,方差较低的方向是噪声(即高频分 量),因此后文中 epsilon 的选择与特征值有关)。一种检验 epsilon 是否合适 的方法是用该值对数据进行 ZCA 白化,然后对白化前后的数据进行可视化。如 果 epsilon 值过低,白化后的数据会显得噪声很大;相反,如果 epsilon 值过高, 白化后的数据与原始数据相比就过于模糊。一种直观上得到 epsilon 大小的方法 是以图形方式画出数据的特征值,如下图的例子所示,你可以看到一条"长尾", 它对应于数据中的高频噪声部分。你需要选取合适的 epsilon,使其能够在很大 程度上过滤掉这条"长尾",也就是说,选取的 epsilon 应大于大多数较小的、反 映数据中噪声的特征值。 在基于重构的模型中,损失函数有一项是用于惩罚那些与原始输入数据 差异较大的重构结果(译注:以自动编码机为例,要求输入数据经过编码和解 码之后还能尽可能的还原输入数据)。如果 epsilon 太小,白化后的数据中就会 包含很多噪声,而模型要拟合这些噪声,以达到很好的重构结果。因此,对于 基于重构的模型来说,对原始数据进行低通滤波就显得非常重要。 提示:如果数据已被缩放到合理范围(如[0,1]),可以从 epsilon = 0.01 或 epsilon = 0.1 开始调节 epsilon。 基于正交化 ICA 的模型 对基于正交化 ICA 的模型来说,保证输入数据尽可能地白化(即协方差 矩阵为单位矩阵)非常重要。这是因为:这类模型需要对学习到的特征做正交 化,以解除不同维度之间的相关性(详细内容请参考 ICA 一节)。因此在这种 情况下,epsilon 要足够小(比如 epsilon = 1e − 6)。 提示:我们也可以在 PCA 白化过程中同时降低数据的维度。这是一个很好的主 意,因为这样可以大大提升算法的速度(减少了运算量和参数数目)。确定要 保留的主成分数目有一个经验法则:即所保留的成分的总方差达到总样本方差 的 99% 以上。(详细内容请参考 PCA ) 注意: 在使用分类框架时,我们应该只基于练集上的数据计算 PCA/ZCA 白化矩 阵。需要保存以下两个参数留待测试集合使用: (a)用于零均值化数据的平均值向量; (b)白化矩阵。 测试集需要采用这两组保存的参数来进行相同的预处理。 大图像 对于大图像,采用基于 PCA/ZCA 的白化方法是不切实际的,因为协方 差矩阵太大。在这些情况下我们退而使用 1/f 白化方法(更多内容后续再讲)。 标准流程 在这一部分中,我们将介绍几种在一些数据集上有良好表现的预处理标准流程. 自然灰度图像 灰度图像具有平稳特性,我们通常在第一步对每个数据样本分别做均值 消减(即减去直流分量),然后采用 PCA/ZCA 白化处理,其中的 epsilon 要足 够大以达到低通滤波的效果。 彩色图像 对于彩色图像,色彩通道间并不存在平稳特性。因此我们通常首先对数 据进行特征缩放(使像素值位于 [0,1] 区间),然后使用足够大的 epsilon 来做 PCA/ZCA。注意在进行 PCA 变换前需要对特征进行分量均值归零化。 音频 (MFCC/频谱图) 对于音频数据 (MFCC 和频谱图),每一维度的取值范围(方差)不同。 例如 MFCC 的第一分量是直流分量,通常其幅度远大于其他分量,尤其当特征 中包含时域导数 (temporal derivatives) 时(这是音频处理中的常用方法)更是如 此。因此,对这类数据的预处理通常从简单的数据标准化开始(即使得数据的 每 一 维度 均值 为 零、方差 为 1),然后 进行 PCA/ZCA 白 化(使 用合 适 的 epsilon)。 MNIST 手写数字 MNIST 数据集的像素值在 [0,255] 区间中。我们首先将其缩放到 [0,1] 区间。实 际上,进行逐样本均值消去也有助于特征学习。 注:也可选择以对 MNIST 进行 PCA/ZCA 白化,但这在实践中不常用。 中英文对照 归一化 normalization 白化 whitening 直流分量 DC component 局部均值消减 local mean subtraction 消减归一化 sparse autoencoder 缩放 rescaling 逐样本均值消减 per-example mean subtraction 特征标准化 feature standardization 平稳 stationary Mel 倒频系数 MFCC 零均值化 zero-mean 低通滤波 low-pass filtering 基于重构的模型 reconstruction based models 自编码器 autoencoders 稀疏编码 sparse coding 受限 Boltzman 机 RBMs k-均值 k-Means 长尾 long tail 损失函数 loss function 正交化 orthogonalization 用反向传导思想求导 Contents [hide] 1 简介 2 示例 o 2.1 示例 1:稀疏编码中权重矩阵的目标函数 o 2.2 示例 2:稀疏编码中的平滑地形 L1 稀疏罚函数 o 2.3 示例 3:ICA 重建代价 3 中英文对照 4 中文译者 简介 在 反向传导算法 一节中,我们介绍了在稀疏自编码器中用反向传导算法来求梯 度的方法。事实证明,反向传导算法与矩阵运算相结合的方法,对于计算复杂 矩阵函数(从矩阵到实数的函数,或用符号表示为:从 )的梯度 是十分强大和直观的。 首先,我们回顾一下反向传导的思想,为了更适合我们的目的,将其稍作修改 呈现于下: 1. 对第 nl 层(最后一层)中的每一个输出单元 i ,令 其中 J(z) 是我们的“目标函数”(稍后解释)。 2. 对 , 对第 l 层中的每个节点 i , 令 3. 计算我们要的偏导数 符号扼要重述: . l 是神经网络的层数 . nl 第 l 层神经元的个数 . 是 l 层第 i 个节点到第 (l + 1) 层第 j 个节点的权重 . 是第 l 层第 i 个单元的输入 . 是第 l 层第 i 个节点的激励 . 是矩阵的 Hadamard 积或逐个元素乘积,对 矩阵 A 和 B ,它们的乘 积是 矩阵 ,即 . f(l) 是第 l 层中各单元的激励函数 假设我们有一个函数 F,F 以矩阵 X 为参数生成一个实数。我们希望用反向 传导思想计算 F 关于 X 的梯度,即 。大致思路是将函数 F 看成一个多层神 经网络,并使用反向传导思想求梯度。 为了实现这个想法,我们取目标函数为 J(z),当计算最后一层神经元的输出时, 会产生值 F(X)。对于中间层,我们将选择激励函数 f(l)。 稍后我们会看到,使用这种方法,我们可以很容易计算出对于输入 X 以及网络 中任意一个权重的导数。 示例 为了阐述如何使用反向传导思想计算关于输入的导数,我们要在示例 1, 示例 2 中用 稀疏编码 章节中的两个函数。在示例 3 中,我们使用 独立成分分 析 一节中的一个函数来说明使用此思想计算关于权重的偏导的方法,以及在这 种特殊情况下,如何处理相互捆绑或重复的权重。 示例 1:稀疏编码中权重矩阵的目标函数 回顾一下 稀疏编码 ,当给定特征矩阵 s 时,权重矩阵 A 的目标函数为: 我们希望求 F 对于 A 的梯度,即 。因为目标函数是两个含 A 的式子之和,所 以它的梯度是每个式子的梯度之和。第二项的梯度很容易求,因此我们只考虑第一项 的梯度。 第一项, ,可以看成一个用 s 做输入的神经网络的实例,通过四步进 行计算,文字以及图形描述如下: 1. 把 A 作为第一层到第二层的权重。 2. 将第二层的激励减 x ,第二层使用了单位激励函数。 3. 通过单位权重将结果不变地传到第三层。在第三层使用平方函数作 为激励函数。 4. 将第三层的所有激励相加。 该网络的权重和激励函数如下表所示: 层 权重 激励函数 f 1 A f(zi) = zi (单位函数) 2 I (单位向量) f(zi) = zi − xi 3 N/A 为了使 J(z(3)) = F(x) ,我们可令 。 一旦我们将 F 看成神经网络,梯度 就很容易求了——使用反向传导 得到: 层 激励函数的导数 f' Delta 该层输入 z 3 f'(zi) = 2zi f'(zi) = 2zi As − x 2 f'(zi) = 1 As 1 f'(zi) = 1 s 因此 示例 2:稀疏编码中的平滑地形 L1 稀疏罚函数 回顾 稀疏编码 一节中对 s 的平滑地形 L1 稀疏罚函数: 其中 V 是分 组矩阵, s 是特征矩阵, ε 是一个常数。 我们希望求得 。像上面那样,我们把这一项看做一个神经网络的 实例: 该网络的权重和激励函数如下表所示: 层 权重 激励函数 f 1 I 2 V f(zi) = zi 3 I f(zi) = zi + ε 4 N/A 为使 J(z(4)) = F(x) ,我们可令 。 一旦我们把 F 看做一个神经网络,梯度 变得很容易计算——使用反向传 导得到: 层 激励函数的导数 f' Delta 该层输入 z 4 (VssT + ε) 3 f'(zi) = 1 VssT 2 f'(zi) = 1 ssT 1 f'(zi) = 2zi s 因此 示例 3:ICA 重建代价 回顾 独立成分分析(ICA) 一节重建代价一项: ,其中 W 是权重矩 阵, x 是输入。 我们希望计算 ——对于权重矩阵的导数,而不是像前两例中对 于输入的导数。不过我们仍然用类似的方法处理,把该项看做一个神经网络的 实例: 该网络的权重和激励函数如下表所示: 层 权重 激励函数 f 1 W f(zi) = zi 2 WT f(zi) = zi 3 I f(zi) = zi − xi 4 N/A 为使 J(z(4)) = F(x) ,我们可令 。 既然我们可将 F 看做神经网络,我们就能计算出梯度 。然而,我们现在 面临的难题是 W 在网络中出现了两次。幸运的是,可以证明如果 W 在网络中 出现多次,那么对于 W 的梯度是对网络中每个 W 实例的梯度的简单相加(你 需要自己给出对这一事实的严格证明来说服自己)。知道这一点后,我们将首 先计算 delta: 层 激励函数的导数 f' Delta 该层输入 z 4 f'(zi) = 2zi f'(zi) = 2zi (WTWx − x) 3 f'(zi) = 1 WTWx 2 f'(zi) = 1 Wx 1 f'(zi) = 1 x 为计算对于 W 的梯度,首先计算对网络中每个 W 实例的梯度。 对于 WT : 对于 W : 最后进行求和,得到对于 W 的最终梯度,注意我们需要对 WT 梯度进行转置, 来得到关于 W 的梯度(原谅我在这里稍稍滥用了符号): 中英文对照 反向传导 backpropagation 稀疏编码 sparse coding 权重矩阵 weight matrix 目标函数 objective 平滑地形 L1 稀疏罚函数 Smoothed topographic L1 sparsity penalty 重建代价 reconstruction cost 稀疏自编码器 sparse autoencoder 梯度 gradient 神经网络 neural network 神经元 neuron 激励 activation 激励函数 activation function 独立成分分析 independent component analysis 单位激励函数 identity activation function 平方函数 square function 分组矩阵 grouping matrix 特征矩阵 feature matrix 稀疏编码 Contents [hide] 1 稀疏编码 2 概率解释 [基于 1996 年 Olshausen 与 Field 的理论] 3 学习算法 4 中英文对照 5 中文译者 稀疏编码 稀疏编码算法是一种无监督学习方法,它用来寻找一组“超完备”基向量 来更高效地表示样本数据。稀疏编码算法的目的就是找到一组基向量 ,使 得我们能将输入向量 表示为这些基向量的线性组合: 虽然形如主成分分析技术(PCA)能使我们方便地找到一组“完备”基向量, 但是这里我们想要做的是找到一组 “ 超 完 备 ” 基 向 量 来 表 示 输 入 向 量 (也就是说,k > n)。超完备基的好处是它们能更有效地找出隐含 在输入数据内部的结构与模式。然而,对于超完备基来说,系数 ai 不再由输入 向量 唯一确定。因此,在稀疏编码算法中,我们另加了一个评判标准“稀疏 性”来解决因超完备而导致的退化(degeneracy)问题。 这里,我们把“稀疏性”定义为:只有很少的几个非零元素或只有很少的几 个远大于零的元素。要求系数 ai 是稀疏的意思就是说:对于一组输入向量,我 们只想有尽可能少的几个系数远大于零。选择使用具有稀疏性的分量来表示我 们的输入数据是有原因的,因为绝大多数的感官数据,比如自然图像,可以被 表示成少量基本元素的叠加,在图像中这些基本元素可以是面或者线。同时, 比如与初级视觉皮层的类比过程也因此得到了提升。 我们把有 m 个输入向量的稀疏编码代价函数定义为: 此处 S(.)是一个稀疏代价函数,由它来对远大于零的 ai 进行“惩罚”。我 们可以把稀疏编码目标函式的第一项解释为一个重构项,这一项迫使稀疏编码 算法能为输入向量 提供一个高拟合度的线性表达式,而公式第二项即“稀疏惩 罚”项,它使 的表达式变得“稀疏”。常量 λ 是一个变换量,由它来控制这两项 式子的相对重要性。 虽然“稀疏性”的最直接测度标准是 "L0" 范式(),但这 是不可微的,而且通常很难进行优化。在实际中,稀疏代价函数 S(.)的普遍选 择是 L1 范式代价函数 及对数代价函数 。 此外,很有可能因为减小 ai 或增加 至很大的常量,使得稀疏惩罚变得非常小。 为防止此类事件发生,我们将限制 要小于某常量 C。包含了限制条件的稀 疏编码代价函数的完整形式如下: 概率解释 [基于 1996 年 Olshausen 与 Field 的理论] 到目前为止,我们所考虑的稀疏编码,是为了寻找到一个稀疏的、超完备基向 量集,来覆盖我们的输入数据空间。现在换一种方式,我们可以从概率的角度 出发,将稀疏编码算法当作一种“生成模型”。 我们将自然图像建模问题看成是一种线性叠加,叠加元素包括 k 个独立的源特 征 以及加性噪声 ν : 我们的目标是找到一组特征基向量 ,它使得图像的分布函数 尽可能 地近似于输入数据的经验分布函数 。 一 种 实 现 方 式 是 , 最 小 化 与 之间的 KL 散度,此 KL 散度表示如下: 因为无论我们如何选择 ,经验分布函数 都是常量,也就是说我们只需 要最大化对数似然函数 。 假设 ν 是具有方差 σ2 的高斯白噪音,则有下 式: 为了确定分布 ,我们需要指定先验分布 。假定我们的特征变量是 独立的,我们就可以将先验概率分解为: 此时,我们将“稀疏”假设加入进来——假设任何一幅图像都是由相对较少的一 些源特征组合起来的。因此,我们希望 ai 的概率分布在零值附近是凸起的,而 且峰值很高。一个方便的参数化先验分布就是: 这里 S(ai) 是决定先验分布的形状的函数。 当定义了 和 后,我们就可以写出在由 定义的模型之下的数 据 的概率分布: 那么,我们的问题就简化为寻找: 这里 < . > 表示的是输入数据的期望值。 不幸的是,通过对 的积分计算 通常是难以实现的。虽然如此,我 们注意到如果 的分布(对于相应的 )足够陡峭的话,我们就可以 用 的最大值来估算以上积分。估算方法如下: 跟之前一样,我们可以通过减小 ai 或增大 来增加概率的估算值(因 为 P(ai) 在零值附近陡升)。因此我们要对特征向量 加一个限制以防止这种 情况发生。 最后,我们可以定义一种线性生成模型的能量函数,从而将原先的代价函数重 新表述为: 其中 λ = 2σ2β ,并且关系不大的常量已被隐藏起来。因为最大化对数似然函数 等同于最小化能量函数,我们就可以将原先的优化问题重新表述为: 使用概率理论来分析,我们可以发现,选择 L1 惩罚和 惩罚作为 函数 S(.) ,分别对应于使用了拉普拉斯概率 和柯西先验 概率 。 学习算法 使用稀疏编码算法学习基向量集的方法,是由两个独立的优化过程组合 起来的。第一个是逐个使用训练样本 来优化系数 ai ,第二个是一次性处理多 个样本对基向量 进行优化。 如果使用 L1 范式作为稀疏惩罚函数,对 的学习过程就简化为求解 由 L1 范式正则化的最小二乘法问题,这个问题函数在域 内为凸,已经有很 多技术方法来解决这个问题(诸如 CVX 之类的凸优化软件可以用来解决 L1 正 则化的最小二乘法问题)。如果 S(.) 是可微的,比如是对数惩罚函数,则可以 采用基于梯度算法的方法,如共轭梯度法。 用 L2 范式约束来学习基向量,同样可以简化为一个带有二次约束的最小 二乘问题,其问题函数在域 内也为凸。标准的凸优化软件(如 CVX)或其 它迭代方法就可以用来求解 ,虽然已经有了更有效的方法,比如求解拉格朗 日对偶函数(Lagrange dual)。 根据前面的的描述,稀疏编码是有一个明显的局限性的,这就是即使已 经学习得到一组基向量,如果为了对新的数据样本进行“编码”,我们必须再次 执行优化过程来得到所需的系数。这个显著的“实时”消耗意味着,即使是在测 试中,实现稀疏编码也需要高昂的计算成本,尤其是与典型的前馈结构算法相比。 中英文对照 稀疏编码 Sparse Coding 无监督学习 unsupervised method 超完备基 over-complete bases 主成分分析 PCA 稀疏性 sparsity 退化 degeneracy 代价函数 cost function 重构项 reconstruction term 稀疏惩罚项 sparsity penalty 范式 norm 生成模型 generative model 线性叠加 linear superposition 加性噪声 additive noise 特征基向量 basis feature vectors 经验分布函数 the empirical distribution KL 散度 KL divergence 对数似然函数 the log-likelihood 高斯白噪音 Gaussian white noise 先验分布 the prior distribution 先验概率 prior probability 源特征 source features 能量函数 the energy function 正则化 regularized 最小二乘法 least squares 凸优化软件 convex optimization software 共轭梯度法 conjugate gradient methods 二次约束 quadratic constraints 拉格朗日对偶函数 the Lagrange dual 前馈结构算法 feedforward architectures 稀疏编码自编码表达 Contents [hide] 1 稀疏编码 2 拓扑稀疏编码 3 稀疏编码实践 o 3.1 将样本分批为“迷你块” o 3.2 良好的 s 初始值 o 3.3 可运行算法 4 中英文对照 5 中文译者 稀疏编码 在稀疏自编码算法中,我们试着学习得到一组权重参数 W(以及相应的 截距 b),通过这些参数可以使我们得到稀疏特征向量 σ(Wx+b),这些特征向量 对于重构输入样本非常有用。 稀疏编码可以看作是稀疏自编码方法的一个变形,该方法试图直接学习数据的 特征集。利用与此特征集相应的基向量,将学习得到的特征集从特征空间转换 到样本数据空间,这样我们就可以用学习得到的特征集重构样本数据。 确切地说,在稀疏编码算法中,有样本数据 x 供我们进行特征学习。特 别是,学习一个用于表示样本数据的稀疏特征集 s,和一个将特征集从特征空间 转换到样本数据空间的基向量 A,我们可以构建如下目标函数: ( 是 x 的 Lk 范数,等价于 。L2 范数即大家熟知的欧几里得范数, L1 范数是向量元素的绝对值之和) 上式前第一部分是利用基向量将特征集重构为样本数据所产生的误差, 第二部分为稀疏性惩罚项(sparsity penalty term),用于保证特征集的稀疏性。 但是,如目标函数所示,它的约束性并不强――按常数比例缩放 A 的同 时再按这个常数的倒数缩放 s,结果不会改变误差大小,却会减少稀疏代价 (表达式第二项)的值。因此,需要为 A 中每项 Aj 增加额外约束 。问 题变为: 遗憾的是,因为目标函数并不是一个凸函数,所以不能用梯度方法解决 这个优化问题。但是,在给定 A 的情况下,最小化 J(A,s)求解 s 是凸的。同理, 给定 s 最小化 J(A,s)求解 A 也是凸的。这表明,可以通过交替固定 s 和 A 分别求 解 A 和 s。实践表明,这一策略取得的效果非常好。 但是,以上表达式带来了另一个难题:不能用简单的梯度方法来实现约 束条件 。因此在实际问题中,此约束条件还不足以成为“权重衰变” ("weight decay")项以保证 A 的每一项值够小。这样我们就得到一个新的目标 函数: (注意上式中第三项, 等价于 ,是 A 各项的平方和) 这一目标函数带来了最后一个问题,即 L1 范数在 0 点处不可微影响了 梯度方法的应用。尽管可以通过其他非梯度下降方法避开这一问题,但是本文 通过使用近似值“平滑” L1 范数的方法解决此难题。使用 代替 , 对 L1 范数进行平滑,其中 ε 是“平滑参数”("smoothing parameter")或者“稀疏参数” ("sparsity parameter")(如果 ε 远大于 x,则 x+ε 的值由 ε 主导,其平方根近似 于 )。在下文提及拓扑稀疏编码时,“平滑”会派上用场。 因此,最终的目标函数是: ( 是 的简写) 该目标函数可以通过以下过程迭代优化: 1. 随机初始化 A 2. 重复以下步骤直至收敛: 1. 根据上一步给定的 A,求解能够最小化 J(A,s) 的 s 2. 根据上一步得到的 s,,求解能够最小化 J(A,s) 的 A 观察修改后的目标函数 J(A,s),给定 s 的条件下,目标函数可以简化 为 (因为 s 的 L1 范式不是 A 的函数,所以可以忽 略)。简化后的目标函数是一个关于 A 的简单二次项式,因此对 A 求导是很容 易的。这种求导的一种快捷方法是矩阵微积分( 相关链接部分列出了跟矩阵演 算有关的内容)。遗憾的是,在给定 A 的条件下,目标函数却不具备这样的求 导方法,因此目标函数的最小化步骤只能用梯度下降或其他类似的最优化方法。 理论上,通过上述迭代方法求解目标函数的最优化问题最终得到的特征 集(A 的基向量)与通过稀疏自编码学习得到的特征集是差不多的。但是实际 上,为了获得更好的算法收敛性需要使用一些小技巧,后面的 稀疏编码实践 稀 疏编码实践章节会详细介绍这些技巧。用梯度下降方法求解目标函数也略需技 巧,另外使用矩阵演算或 反向传播算法则有助于解决此类问题。 拓扑稀疏编码 通过稀疏编码,我们能够得到一组用于表示样本数据的特征集。不过,让我们 来找些灵感,我们希望学习得到一组有某种“秩序”的特征集。举个例子,视觉 特征,如前面所提到的,大脑皮层 V1 区神经元能够按特定的方向对边缘进行 检测,同时,这些神经元(在生理上)被组织成超柱(hypercolumns),在超 柱中,相邻神经元以相似的方向对边缘进行检测,一个神经元检测水平边缘, 其相邻神经元检测到的边缘就稍微偏离水平方向,沿着超柱,神经元就可以检 测到与水平方向相差更大的边缘了。 受该例子的启发,我们希望学习到的特征也具有这样“拓扑秩序”的性质。 这对于我们要学习的特征意味着什么呢?直观的讲,如果“相邻”的特征是“相似” 的,就意味着如果某个特征被激活,那么与之相邻的特征也将随之被激活。 具体而言,假设我们(随意地)将特征组织成一个方阵。我们就希望矩 阵中相邻的特征是相似的。实现这一点的方法是将相邻特征按经过平滑的 L1 范 式惩罚进行分组,如果按 3x3 方阵分组,则用 代替 , 其分组通常是重合的,因此从第 1 行第 1 列开始的 3x3 区域是一 个分组,从第 1 行第 2 列开始的 3x3 区域是另一个分组,以此类推。最终,这 样的分组会形成环绕,就好像这个矩阵是个环形曲面,所以每个特征都以同样 的次数进行了分组。 于是,将经过平滑的所有分组的 L1 惩罚值之和代替经过 平滑的 L1 惩罚值,得到新的目标函数如下: 实际上,“分组”可以通过“分组矩阵”V 完成,于是矩阵 V 的第 r 行标识了哪些特 征被分到第 r 组中,即如果第 r 组包含特征 c 则 Vr,c= 1。通过分组矩阵实现分组 使得梯度的计算更加直观,使用此分组矩阵,目标函数被重写为: (令 , 等价于 ,r c r c D ) 该目标函数能够使用之前部分提到的迭代方法进行求解。拓扑稀疏编码 得到的特征与稀疏编码得到的类似,只是拓扑稀疏编码得到的特征是以某种方 式有“秩序”排列的。 稀疏编码实践 如上所述,虽然稀疏编码背后的理论十分简单,但是要写出准确无误的 实现代码并能快速又恰到好处地收敛到最优值,则需要一定的技巧。 回顾一下之前提到的简单迭代算法: 1. 随机初始化 A 2. 重复以下步骤直至收敛到最优值: 1. 根据上一步给定的 A,求解能够最小 化 J(A,s)的 s 2. 根据上一步得到的 s,求解能够最小 化 J(A,s)的 A 这样信手拈来地执行这个算法,结果并不会令人满意,即使确实得到了某些结 果。以下是两种更快更优化的收敛技巧: 1. 将样本分批为“迷你块” 2. 良好的 s 初始值 将样本分批为“迷你块” 如果你一次性在大规模数据集(比如,有 10000 个 patch)上执行简单的 迭代算法,你会发现每次迭代都要花很长时间,也因此这算法要花好长时间才 能达到收敛结果。为了提高收敛速度,可以选择在迷你块上运行该算法。每次 迭代的时候,不是在所有的 10000 个 patchs 上执行该算法,而是使用迷你块, 即从 10000 个 patch 中随机选出 2000 个 patch,再在这个迷你块上执行这个算法。 这样就可以做到一石二鸟――第一,提高了每次迭代的速度,因为现在每次迭 代只在 2000 个 patch 上执行而不是 10000 个;第二,也是更重要的,它提高了 收敛的速度(原因见 TODO)。 良好的 s 初始值 另一个能获得更快速更优化收敛的重要技巧是:在给定 A 的条件下,根 据目标函数使用梯度下降(或其他方法)求解 s 之前找到良好的特征矩阵 s 的 初始值。实际上,除非在优化 A 的最优值前已找到一个最佳矩阵 s,不然每次 迭代过程中随机初始化 s 值会导致很差的收敛效果。下面给出一个初始化 s 的 较好方法: 1. 令 (x 是迷你块中 patches 的矩阵表 示) 2. s 中的每个特征(s 的每一列),除以其在 A 中对应基向量的范数。即,如果 sr,c 表示第 c 个样本的第 r 个特征,则 Ac 表示 A 中的第 c 个基向量,则令 无疑,这样的初始化有助于算法的改进,因为上述的第一步希望找到满足 的矩阵 s;第二步对 s 作规范化处理是为了保持较小的稀疏惩罚值。这 也表明,只采用上述步骤的某一步而不是两步对 s 做初始化处理将严重影响算 法性能(TODO:此链接将会对为什么这样的初始化能改进算法作出更详细的解 释) 可运行算法 有了以上两种技巧,稀疏编码算法修改如下: 1. 随机初始化 A 2. 重复以下步骤直至收敛 1. 随机选取一个有 2000 个 patches 的迷 你块 2. 如上所述,初始化 s 3. 根据上一步给定的 A,求解能够最小 化 J(A,s)的 s 4. 根据上一步得到的 s,求解能够最小 化 J(A,s)的 A 通过上述方法,可以相对快速的得到局部最优解。 中英文对照 稀疏编码 sparse coding 自编码 autoencoder 目标函数 objective function 稀疏代价 sparsity cost 反向传播 backpropagation 基于梯度的 gradient-based 非凸的 non-convex 权重衰变 weight decay 拓扑稀疏编码 topographic sparse coding 拓扑秩序 topographically ordered 平滑的一范数惩罚 smoothed L1 penalty 迷你块 mini-batches 收敛速度 the rate of convergence 梯度下降 gradient descent 局部最优解 local optima 独立成分分析 Contents [hide] 1 概述 2 标准正交 ICA 3 拓扑 ICA 4 中英文对照 5 中文译者 概述 试着回想一下,在介绍 稀疏编码算法中我们想为样本数据学习得到一个 超完备基(over-complete basis)。具体来说,这意味着用稀疏编码学习得到的 基向量之间不一定线性独立。尽管在某些情况下这已经满足需要,但有时我们 仍然希望得到的是一组线性独立基。独立成分分析算法(ICA)正实现了一组 线性独立基。而且,在 ICA 中,我们希望学习到的基不仅要线性独立,而且还 是一组标准正交基。(一组标准正交基 需要满足条件:(如 果 )或者 (如果 i = j)) 与稀疏编码算法类似,独立成分分析也有一个简单的数学形式。给定数 据 x,我们希望学习得到一组基向量――以列向量形式构成的矩阵 W,其满足 以下特点:首先,与稀疏编码一样,特征是稀疏的;其次,基是标准正交的 (注意,在稀疏编码中,矩阵 A 用于将特征 s 映射到原始数据,而在独立成分 分析中,矩阵 W 工作的方向相反,是将原始数据 x 映射到特征)。这样我们得 到以下目标函数: 由于 Wx 实际上是描述样本数据的特征,这个目标函数等价于在稀疏编 码中特征 s 的稀疏惩罚项。加入标准正交性约束后,独立成分分析相当于求解 如下优化问题: 与深度学习中的通常情况一样,这个问题没有简单的解析解,而且更糟 糕的是,由于标准正交性约束,使得用梯度下降方法来求解该问题变得更加困 难――每次梯度下降迭代之后,必须将新的基映射回正交基空间中(以此保证 正交性约束)。 实践中,在最优化目标函数的同时施加正交性约束(如下一节正交 ICA 中讲到的)是可行的,但是速度慢。在标准正交基是不可或缺的情况下,标准 正交 ICA 的使用会受到一些限制。(哪些情况见:TODO ) 标准正交 ICA 标准正交 ICA 的目标函数是: 通过观察可知,约束 WWT = I 隐含着另外两个约束: 第一,因为要学习到一组标准正交基,所以基向量的个数必须小于输入数据的 维度。具体来说,这意味着不能像通常在 稀疏编码中所做的那样来学习得到超 完备基(over-complete bases)。 第二,数据必须经过无正则 ZCA 白化(也即,ε 设为 0)。(为什么必须这样做? 见 TODO) 因此,在优化标准正交 ICA 目标函数之前,必须确保数据被白化过,并 且学习的是一组不完备基(under-complete basis)。 然后,为了优化目标函数,我们可以使用梯度下降法,在梯度下降的每 一步中增加投影步骤,以满足标准正交约束。过程如下: 重复以下步骤直到完成: 1. 2. 其中 U 是满足 WWT = I 的矩阵空间 在实际中,学习速率 α 是可变的,使用一个线搜索算法来加速梯度.投影步骤通过 设置 来完成,这实际上可以看成就是 ZCA 白化(TODO:解释为什么 这就象 ZCA 白化). 拓扑 ICA 与 稀疏编码算法类似,加上一个拓扑代价项,独立成分分析法可以修改成具有 拓扑性质的算法。 中英文对照 独立成分分析 Independent Component Analysis 稀疏编码算法 Sparse coding 超完备基 Over-complete basis 标准正交基 Orthonormal basis 稀疏惩罚项 Sparsity penalty 梯度下降法 Gradient descent 白化 Whitened 不完备基 Under-complete basis 线搜索算法 Line-search algorithm 拓扑代价项 Topographic cost term
还剩116页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 23 人已下载

下载pdf

pdf贡献者

岳麓丹枫

贡献于2014-09-29

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf