林轩田机器学习技法关于特征学习系列,其中涉及到 Neural Network <script type="math/tex" id="MathJax-Element-1">Neural\ Network</script>, Backpropagation Algorithm <script type="math/tex" id="MathJax-Element-2">Backpropagation\ Algorithm</script>, Deep Learning <script type="math/tex" id="MathJax-Element-3">Deep\ Learning</script>, Autoencoder <script type="math/tex" id="MathJax-Element-4">Autoencoder</script>,
PCA <script type="math/tex" id="MathJax-Element-5">PCA</script>, Radial Basis Function Network <script type="math/tex" id="MathJax-Element-6">Radial\ Basis\ Function\ Network</script>, K <script type="math/tex" id="MathJax-Element-7">K</script>-Means<script type="math/tex" id="MathJax-Element-8">Means</script>, Matrix Factorization <script type="math/tex" id="MathJax-Element-9">Matrix\ Factorization</script> 等。

上一篇的介绍中我们看到在 Neural network <script type="math/tex" id="MathJax-Element-10">Neural\ network</script>中有一层一层的神经元,它们的作用就是帮助我们识别出资料中的模式 pattern <script type="math/tex" id="MathJax-Element-11">pattern</script>,将这些模式当成是特征。通过 BP <script type="math/tex" id="MathJax-Element-12">BP</script>算法可以帮助我们计算梯度,这样就可以利用 GD <script type="math/tex" id="MathJax-Element-13">GD</script>类算法来更新每一个权重,最终得到神经网络中每一个神经元的权重 w(l)ij <script type="math/tex" id="MathJax-Element-14">w_{ij}^{(l)}</script>。所以神经网路的核心就是这些一层一层的神经元,还有神经元之间的连接权重,那么如何来决定神经网络的结构呢?这是神经网络中一个非常核心也非常困难的问题。

Deep Neural Network

Shallow neural network and deep neural network

在本篇中,我们使用一种非常粗略的方法按照神经网络中 hidden layer <script type="math/tex" id="MathJax-Element-15">hidden\ layer</script>的层数将其划分为两类: shallow neural network <script type="math/tex" id="MathJax-Element-16">shallow\ neural\ network</script>和 deep neural network <script type="math/tex" id="MathJax-Element-17">deep\ neural\ network</script>。对于 shallow neural network <script type="math/tex" id="MathJax-Element-18">shallow\ neural\ network</script>来说,由于隐藏层的个数比较少,所以 forward <script type="math/tex" id="MathJax-Element-19">forward</script>和 backward <script type="math/tex" id="MathJax-Element-20">backward</script>的计算都会比较有效率,有关结构的决定也会比较简单,并且有理论可以证明当有足够多的神经元和足够多的连接的时候,浅层的神经网络就可以拟合任意复杂的函数。对于 deep neural network <script type="math/tex" id="MathJax-Element-21">deep\ neural\ network</script>来说,在参数的训练和结构的决定方面相比于 shallow neural network <script type="math/tex" id="MathJax-Element-22">shallow\ neural\ network</script>来说就更有难度一些。既然是这样的,那么为什么还要使用 deep neural network <script type="math/tex" id="MathJax-Element-23">deep\ neural\ network</script>呢?其中的一个原因是,因为大家相信通过 deep neural network <script type="math/tex" id="MathJax-Element-24">deep\ neural\ network</script>我们可以得到比较有物理意义的特征。最近 deep learning <script type="math/tex" id="MathJax-Element-25">deep\ learning</script>在图像处理和语音识别方面的流行, 正式由于这样 deep <script type="math/tex" id="MathJax-Element-26">deep</script>的结构可以帮助我们得到隐藏在图像和声音中的有用的特征。

Meaningfulness of deep learning

下面通过一个例子来对 deep network <script type="math/tex" id="MathJax-Element-324">deep\ network</script>的工作做出简单的解释,我们现在想要做的是识别手写数字 1 <script type="math/tex" id="MathJax-Element-325">1</script> 和 5<script type="math/tex" id="MathJax-Element-326">5</script> 。


这里写图片描述

当我们想要辨识 1 <script type="math/tex" id="MathJax-Element-327">1</script> 和 5<script type="math/tex" id="MathJax-Element-328">5</script> 的时候,我们可能需要首先利用第一层神经元识别出其中一些很小如下图所示的笔画:


这里写图片描述

比如与 ϕ2 <script type="math/tex" id="MathJax-Element-329">\phi_2</script> 相连的神经元可能要识别出长的像“|”的东西,也就是说如果某一个输入其垂直方向上居中位置的像素值比较低(是黑色)的话,那么与 ϕ2 <script type="math/tex" id="MathJax-Element-330">\phi_2</script>相连的这个神经元就会被激活,或者说这样的输入会和 ϕ2 <script type="math/tex" id="MathJax-Element-331">\phi_2</script>“模式匹配”。
下一层会基于上一层提取的非常简单的特征再提取稍复杂一些的特征,下下一层又会在这些稍微复杂的特征的基础上再提取更为复杂的一些特征, <script type="math/tex" id="MathJax-Element-332">\cdots</script>,等到特征足够复杂的时候就可以根据这些特征轻易的来做识别的工作。
这样的每一层可能都可以代表不同的物理意义, 例如一张数字 1 <script type="math/tex" id="MathJax-Element-333">1</script> 的图片在预测时可能会激活与 ϕ1,ϕ2,ϕ3<script type="math/tex" id="MathJax-Element-334">\phi_1, \phi_2, \phi_3</script> 相连的神经元, 或者说在训练时与 ϕ1,ϕ2,ϕ3 <script type="math/tex" id="MathJax-Element-335">\phi_1, \phi_2, \phi_3</script> 相连的神经元会提取出三个特征:


这里写图片描述

所以识别 1 <script type="math/tex" id="MathJax-Element-336">1</script> 的神经元 z1<script type="math/tex" id="MathJax-Element-337">z_1</script> 在与 ϕ1,ϕ2,ϕ3 <script type="math/tex" id="MathJax-Element-338">\phi_1, \phi_2, \phi_3</script> 相连的神经元都激活的情况下会被激活。 可以想象如果层数越多的话,每一层需要做的事情就越简单,相比只有一层 hidden layer <script type="math/tex" id="MathJax-Element-339">hidden\ layer</script>的网络来说,可能会有更多的物理意义上的解释。

所以 deep neural network <script type="math/tex" id="MathJax-Element-340">deep\ neural\ network</script>对于原始特征是 raw feature <script type="math/tex" id="MathJax-Element-341">raw\ feature</script>的学习任务来说会比较有用, 例如对于图像来说,这些 raw feature <script type="math/tex" id="MathJax-Element-342">raw\ feature</script>是一个一个的 pixel <script type="math/tex" id="MathJax-Element-343">pixel</script>值,每一个 pixel <script type="math/tex" id="MathJax-Element-344">pixel</script>的值可能只有一丁点的物理含义,但是我们最终想要的是一个非常复杂的分类模型:区分 1 <script type="math/tex" id="MathJax-Element-345">1</script>和5<script type="math/tex" id="MathJax-Element-346">5</script>,这对于计算机来说是很难的。基于原始的特征这很难一步做到,而通过 deep neural network <script type="math/tex" id="MathJax-Element-347">deep\ neural\ network</script>这样在每一层做一些简单处理, 层数足够多的话就可以完成这个很复杂的分类任务。 类似于图像的还有音频这样的资料,同样也是 raw feature <script type="math/tex" id="MathJax-Element-348">raw\ feature</script>,要做识别是很困难的任务,但是同样可以通过这样一层一层的学习, 学习了足够层数之后就可以解决。总结下, 在图片和语音这样的领域,由于给出的资料都非常的原始, 通常没有什么好的办法可以做特征的提取和转换, 所以只能是通过 deep learning <script type="math/tex" id="MathJax-Element-349">deep\ learning</script>这样的架构自主的从数据中学习有利于进行识别的特征从而完成很复杂的任务。

Challenges and keys techniques for deep learning

这里概略的对深度学习中遇到的困难和解决的方法给出介绍。

  • 模型的架构很难决定
    • 结合对专业领域的了解, 例如用于图像处理的 CNN <script type="math/tex" id="MathJax-Element-53">CNN</script>。
  • 模型的复杂度很高
    • 当有足够多的数据时,这个问题通常是不需要太过于担心的。
    • regularization <script type="math/tex" id="MathJax-Element-54">regularization</script>
      • dropout <script type="math/tex" id="MathJax-Element-55">dropout</script>
      • denoising <script type="math/tex" id="MathJax-Element-56">denoising</script>
  • 有很多局部最优解,很难于最佳化
    • 由于初始权重的设置对最终的结果有很大的影响,所以通过谨慎的选择初始权重可以有效的避免陷入局部最优解,关于如何选择好的起始点这样的方法称为 pre <script type="math/tex" id="MathJax-Element-57">pre</script>- training <script type="math/tex" id="MathJax-Element-58">training</script>。
  • 计算复杂度很大
    • mini batch with GPU <script type="math/tex" id="MathJax-Element-59">mini\ batch\ with\ GPU </script>

其中各种各样不同的 regularization <script type="math/tex" id="MathJax-Element-60">regularization</script>和 initialization <script type="math/tex" id="MathJax-Element-61">initialization</script>的思路使得我们可以实现更深层的网络。

A two-step deep learning framework

介绍一个简单的深度学习的架构,如上面所谈论的, 网络最终的表现和初始的权重值设置有很大的关系,那么如何选定一个好的权重起始点呢?一个方法是,在正式训练模型之前分别选择好每一层的权重,具体做法是,先通过一定的方法选择好第一层的权重,然后固定第一层的权重,选择好第二层的权重, <script type="math/tex" id="MathJax-Element-62">\cdots</script>。这样的过程称之为 pre <script type="math/tex" id="MathJax-Element-63">pre</script>- train <script type="math/tex" id="MathJax-Element-64">train</script>,然后在 train <script type="math/tex" id="MathJax-Element-65">train</script>阶段使用 pre <script type="math/tex" id="MathJax-Element-66">pre</script>- train <script type="math/tex" id="MathJax-Element-67">train</script>得到的权重作为初始权重利用 bp <script type="math/tex" id="MathJax-Element-68">bp</script>算法进行训练对所有的权重进行微调。

Simple deep learning <script type="math/tex" id="MathJax-Element-69">Simple\ deep\ learning</script>
1.for l=1,2,,L, pre train{w(l)ij} assuming w1,,w(l1) fixed <script type="math/tex" id="MathJax-Element-70">1. for\ l = 1, 2, \cdots, L,\ pre\ train \{w_{ij}^{(l)}\}\ assuming\ w_{*}^{1}, \cdots, w_{*}^{(l-1)}\ fixed</script>
这里写图片描述

2.train with backprop on pre trained NNet to fine tune all {w(l)ij} <script type="math/tex" id="MathJax-Element-71">2. train\ with\ backprop\ on\ pre\ trained\ NNet\ to\ fine\ tune\ all\ \{w_{ij}^{(l)}\}</script>

下一节会在这个架构下讲解如何进行 pre <script type="math/tex" id="MathJax-Element-72">pre</script>- train <script type="math/tex" id="MathJax-Element-73">train</script>,即如何得到不错的初始权重值,并且介绍在这个过程中如何使用 regularization <script type="math/tex" id="MathJax-Element-74">regularization</script>来限制模型的复杂度。

Autoencoder

上一小节介绍了一个基本的深度学习的架构,这一小节介绍如何进行 pre <script type="math/tex" id="MathJax-Element-368">pre</script>- train <script type="math/tex" id="MathJax-Element-369">train</script>,也就是如何进行初始权重的决定。
在神经网络和深度学习中,权重可以理解为代表了做特征转换或者抽取的方式,或者是如何将特征换成另一种不同的表现形式。在得到了不同的特征的表现形式之后,再决定要如何学习。但是,假设当我们使用一定的方法得到了第一层的初始权重,进而得到在这些权重作用下经过转换的特征之后,我们是不清楚这些特征在后面的隐藏层中是怎么被使用的。既然这样的话, 那么我们认为好的权重就是那些能够保存原始资料特征的权重, 直观上说也就是在经过这样的权重将资料转换之后不会得到面目全非的特征,而是原来的资料能告诉我们的信息在新的资料中也可以得到类似的结果, 只是更加简练或者是抽象了而已。

例如在上一小节中我们提到的 1 <script type="math/tex" id="MathJax-Element-370">1</script>和5<script type="math/tex" id="MathJax-Element-371">5</script>的识别,第一个 hidden layer <script type="math/tex" id="MathJax-Element-372">hidden\ layer</script>将原始的像素特征转换为 6 <script type="math/tex" id="MathJax-Element-373">6</script> 个笔画的特征, 可以很直观的看出我们是能够通过这6<script type="math/tex" id="MathJax-Element-374">6</script>个笔画的组合得到原始的信息的,例如当权重取 (1,1,1,0,0,0) <script type="math/tex" id="MathJax-Element-375">(1, 1, 1, 0, 0, 0)</script>的时候可以组合得到 1 <script type="math/tex" id="MathJax-Element-376">1</script>;权重取(0,0,1,1,1,1)<script type="math/tex" id="MathJax-Element-377">(0, 0, 1, 1, 1, 1)</script>的时候可以组合得到 5 <script type="math/tex" id="MathJax-Element-378">5</script>。

也就是说在deep learning<script type="math/tex" id="MathJax-Element-379">deep\ learning</script>的 pre training <script type="math/tex" id="MathJax-Element-380">pre\ training</script>的时候,我们希望得到的初始的权重是 information preserving <script type="math/tex" id="MathJax-Element-381">information\ preserving</script>的,即在该权重下经过转换得到的特征保留了原始特征的信息,这样的愿景可以通过如下的浅层神经网络实现,


这里写图片描述

这个神经网络的结构为: dd~d <script type="math/tex" id="MathJax-Element-382">d \longrightarrow \tilde{d} \longrightarrow d</script>, 其特别之处在于,输出层神经元的个数等于输入层神经元的个数,并且我们期望输出等于输入: gi(x)xi <script type="math/tex" id="MathJax-Element-383">g_i(x) \approx x_i</script>, 这样的神经网络被称为 autoencoder <script type="math/tex" id="MathJax-Element-384">autoencoder</script>,其目的是将原始的特征编码为 d~ <script type="math/tex" id="MathJax-Element-385">\tilde{d}</script>维的新的特征, 然后解码为与原始特征相似的输出。

usefulness

通过这样的方式可能可以得到隐藏在数据中的潜藏结构 hidden structures <script type="math/tex" id="MathJax-Element-93">hidden\ structures</script>。这样就可以利用这些 hidden structures <script type="math/tex" id="MathJax-Element-94">hidden\ structures</script>做特征转换,其中得到的 w(1)ij <script type="math/tex" id="MathJax-Element-95">w_{ij}^{(1)}</script> 可以认为是一个很好的权重的起始点, 同时可以得到原始数据的 informative <script type="math/tex" id="MathJax-Element-96">informative</script>(无损)的特征表示。

  • learning informative representation of data <script type="math/tex" id="MathJax-Element-97">learning\ informative\ representation\ of\ data</script>

在无监督学习中, autoencoder <script type="math/tex" id="MathJax-Element-98">autoencoder</script>可以用来做异常点检测 outlier detection <script type="math/tex" id="MathJax-Element-99">outlier\ detection</script>,因为在异常点上编码器的表现会差,而合群的点由于数据量多编码器的表现会好。所以我们可以认为 autoencoder <script type="math/tex" id="MathJax-Element-100">autoencoder</script>能够筛选典型的资料。

  • learning typical representation of data <script type="math/tex" id="MathJax-Element-101">learning\ typical\ representation\ of\ data</script>

所以 autoencoder <script type="math/tex" id="MathJax-Element-102">autoencoder</script>看似在学习一个简单的 identity function g(x)=x <script type="math/tex" id="MathJax-Element-103">identity\ function\ g(x) = x</script>,实则我们想要的是中间隐藏层所得到的原始数据的具有代表性的 (typical) <script type="math/tex" id="MathJax-Element-104">(typical)</script>或者说是无损的 (informative) <script type="math/tex" id="MathJax-Element-105">(informative)</script>的数据表示方法 (representation of data) <script type="math/tex" id="MathJax-Element-106">(representation\ of\ data)</script>。这样得到了大部分资料的表现方式之后,可以做更有用的事情。

Basic Autoencoder

一个基本的编码器就是一个结构为 dd~d <script type="math/tex" id="MathJax-Element-107">d - \tilde{d} - d</script>的浅层神经网络, 通常其 error function <script type="math/tex" id="MathJax-Element-108">error\ function</script>为:

i=1d(gi(x)xi)2
<script type="math/tex; mode=display" id="MathJax-Element-109">\sum_{i = 1}^{d}(g_i(x) - x_i)^2</script>
可以利用 backproporgation <script type="math/tex" id="MathJax-Element-110">backproporgation</script>算法进行最佳化。并且一般我们关心 d~<d <script type="math/tex" id="MathJax-Element-111">\tilde{d} < d</script>的情形, 这样就做到了 特征降维。训练的资料是 {(x1,y1=x1),(x2,y2=x2),,(xN,yN=xN)} <script type="math/tex" id="MathJax-Element-112">\{(x_1, y_1 = x_1), (x_2, y_2 = x_2), \cdots, (x_N, y_N = x_N)\}</script>,可以看到由于并不需要 label <script type="math/tex" id="MathJax-Element-113">label</script> 值的参与,所以通常会被归为 无监督学习方法。很多时候在这样的神经网络中会限制编码的权重 w(1)ij <script type="math/tex" id="MathJax-Element-114">w_{ij}^{(1)}</script>和解码的权重 w(2)ji <script type="math/tex" id="MathJax-Element-115">w_{ji}^{(2)}</script>相同。

Pre-Training with Autoencoders

这样 autoencoder <script type="math/tex" id="MathJax-Element-116">autoencoder</script>通常用于 deep learning <script type="math/tex" id="MathJax-Element-117">deep\ learning</script>的 pre training <script type="math/tex" id="MathJax-Element-118">pre\ training</script>。或者说 deep learning <script type="math/tex" id="MathJax-Element-119">deep\ learning</script>中 pre training <script type="math/tex" id="MathJax-Element-120">pre\ training</script>的一个合理的方式是 autoencoders <script type="math/tex" id="MathJax-Element-121">autoencoders</script>

Deep learning with autoencoders <script type="math/tex" id="MathJax-Element-122">Deep\ learning\ with\ autoencoders</script>

  • 1.for l=1,2,,L, pre train{w(l)ij} assuming w1,,w(l1) fixed <script type="math/tex" id="MathJax-Element-123">1. for\ l = 1, 2, \cdots, L,\ pre\ train \{w_{ij}^{(l)}\}\ assuming\ w_{*}^{1}, \cdots, w_{*}^{(l-1)}\ fixed</script>
    这里写图片描述
    by training basic autoencoders on {x(l1)n} with d~=dl <script type="math/tex" id="MathJax-Element-124">by\ training\ basic\ autoencoders\ on\ \{x_{n}^{(l-1)}\}\ with\ \tilde{d} = d^{l}</script>
  • 2.train with backprop on pre trained NNet to fine tune all {w(l)ij} <script type="math/tex" id="MathJax-Element-125">2. train\ with\ backprop\ on\ pre\ trained\ NNet\ to\ fine\ tune\ all\ \{w_{ij}^{(l)}\}</script>

具体的过程是:当要决定神经网络中第一层的初始权重值时,利用神经网络的输入来训练一个 autoencoder <script type="math/tex" id="MathJax-Element-126">autoencoder</script>,其中 autoencoder <script type="math/tex" id="MathJax-Element-127">autoencoder</script>中间层的神经元的个数为神经网络第一层 hidden layer <script type="math/tex" id="MathJax-Element-128">hidden\ layer</script>中神经元的个数。当 autoencoder <script type="math/tex" id="MathJax-Element-129">autoencoder</script>训练完毕之后,固定神经网络中第一层的权重,并计算第一个 hidden layer <script type="math/tex" id="MathJax-Element-130">hidden\ layer</script>的输出,利用该输出作为第二个 autoencoder <script type="math/tex" id="MathJax-Element-131">autoencoder</script>的输入,用于训练第二层的初始权重, <script type="math/tex" id="MathJax-Element-132">\cdots</script>。

Denoising Autoencoder

上一小节使用 autoencoders <script type="math/tex" id="MathJax-Element-398">autoencoders</script>解决了 deep learning <script type="math/tex" id="MathJax-Element-399">deep\ learning</script>中 pre training <script type="math/tex" id="MathJax-Element-400">pre\ training</script>的问题,这一小节简单介绍下 autoencoder <script type="math/tex" id="MathJax-Element-401">autoencoder</script>中用于控制模型复杂度的一种 regularization <script type="math/tex" id="MathJax-Element-402">regularization</script>的方法。


这里写图片描述

上图是上一篇中给出的神经网络的示意图,之前也提到因为有这么多的神经元和连接(权重),所以这样的模型很容易过拟合。由于模型的复杂度很高,所以我们需要正则化 regularization <script type="math/tex" id="MathJax-Element-403">regularization</script>,一些常见的方法有:

  • structural decisions <script type="math/tex" id="MathJax-Element-404">structural\ decisions</script>:例如在 CNN <script type="math/tex" id="MathJax-Element-405">CNN</script>中不使用全连接。
  • 使用正则化项: weight decay <script type="math/tex" id="MathJax-Element-406">weight\ decay</script>, weight elimination <script type="math/tex" id="MathJax-Element-407">weight\ elimination</script>。
  • early stopping <script type="math/tex" id="MathJax-Element-408">early\ stopping</script>:提前停止 bp <script type="math/tex" id="MathJax-Element-409">bp</script> 算法可能会得到更好的结果。

Dealing with noise

接下来介绍一个在 deep learning <script type="math/tex" id="MathJax-Element-445">deep\ learning</script>和 autoencoder <script type="math/tex" id="MathJax-Element-446">autoencoder</script>中都非常有用的 regularization <script type="math/tex" id="MathJax-Element-447">regularization</script>的方式。在此之前先来简单的回顾下 overfitting <script type="math/tex" id="MathJax-Element-448">overfitting</script>的成因是什么,


这里写图片描述

上图中横轴表示样本的数量,纵轴表示噪声。颜色越红表示 overfitting <script type="math/tex" id="MathJax-Element-449">overfitting</script>越严重,可以看到当资料量越少,噪声越多的时候,越容易 overfitting <script type="math/tex" id="MathJax-Element-450">overfitting</script>。

当模型复杂度和资料量已经确定的时候, 可以看到 noise <script type="math/tex" id="MathJax-Element-451">noise</script>是影响 overfitting <script type="math/tex" id="MathJax-Element-452">overfitting</script>的一个很重要的原因。为了避免 overfitting <script type="math/tex" id="MathJax-Element-453">overfitting</script>一个直接的做法是进行数据处理: data cleaning/pruning <script type="math/tex" id="MathJax-Element-454">data\ cleaning/pruning</script>,但是这通常是艰难的工作,我们提出一个特别的方法,既然没有办法将 noise <script type="math/tex" id="MathJax-Element-455">noise</script>或者是有 noise <script type="math/tex" id="MathJax-Element-456">noise</script>的资料清除掉,那么不然就把 noise <script type="math/tex" id="MathJax-Element-457">noise</script>加入到原来的资料当中。为什么可以这么做呢?

使用 autoencoder <script type="math/tex" id="MathJax-Element-458">autoencoder</script>为例来解释,一个好的编码器能够做的是: g(x)x <script type="math/tex" id="MathJax-Element-459">g(x) \approx x</script>,即对某个输入经过编码解码之后得到的输出和输入要差不多。我们想要一个更好的编码器,这个编码器可以做到:当输入是有噪声的 x <script type="math/tex" id="MathJax-Element-460">x</script> ,记为 x~<script type="math/tex" id="MathJax-Element-461">\tilde{x}</script>, 自动编码器依然能够输出 x <script type="math/tex" id="MathJax-Element-462">x</script> , 即 g(x~)x<script type="math/tex" id="MathJax-Element-463">g(\tilde{x}) \approx x</script>。例如当我们输入一张写的很不规范的数字 1 <script type="math/tex" id="MathJax-Element-464">1</script> 的图片,或者譬如写 1<script type="math/tex" id="MathJax-Element-465">1</script> 的纸是脏的,等等存在噪声的输入的时候, 我们希望这个很 robust <script type="math/tex" id="MathJax-Element-466">robust</script>的 autoencoder <script type="math/tex" id="MathJax-Element-467">autoencoder</script>依然可以通过编码解码之后输出一个正常的 1 <script type="math/tex" id="MathJax-Element-468">1</script>的图片, 而不是一个像原来那样被污染的,或者是更差的结果。

现在我们想要编码器不仅仅有编码的能力, 还要有能够去噪声的能力,我们将这样的编码器称之为denoising autoencoder<script type="math/tex" id="MathJax-Element-469">denoising\ autoencoder</script>,这样的编码器可以通过如下的方式得到:

denoising autoencoder <script type="math/tex" id="MathJax-Element-470">denoising\ autoencoder</script>
run basic autoencoder with data {(x1~,y1=x1),(x2~,y2=x2),,(xN~,yN=xN)},where xn~=xn+artificial noise <script type="math/tex" id="MathJax-Element-471">run\ basic\ autoencoder\ with\ data\ \{(\tilde{x_1}, y_1 = x_1), (\tilde{x_2}, y_2 = x_2), \cdots, (\tilde{x_N}, y_N = x_N)\}, where\ \tilde{x_n} = x_n + artificial\ noise</script>

即我们要求编码器的输出依然等于输入,但是编码器的输入不再是干净的资料,而是加了噪声的变脏的输入。通过这样的方式得到的 deep learning <script type="math/tex" id="MathJax-Element-472">deep\ learning</script>初始权重,不仅仅能够把干净的资料编码为干净的资料,还可以把脏的资料编码为干净的资料。可以想到的这样的方法的一个应用就是为照片去除噪声。

所以如果某个网络有去噪声的功能,那么该网络就能避免 noise <script type="math/tex" id="MathJax-Element-473">noise</script>的影响,再结合我们之前讨论的 noise <script type="math/tex" id="MathJax-Element-474">noise</script>对 overfitting <script type="math/tex" id="MathJax-Element-475">overfitting</script>的“重要贡献”,这样就能到达像 regularization <script type="math/tex" id="MathJax-Element-476">regularization</script>那样避免 overfitting <script type="math/tex" id="MathJax-Element-477">overfitting</script>的效果。而这样一个有去噪声功能的网络怎么得到呢?总结来说就是通过喂给编码器有噪声的资料并要求其拟合无噪声的结果从而得到一个可以去除噪声的(初始)权重。

添加 artificial noise <script type="math/tex" id="MathJax-Element-478">artificial\ noise</script>不仅仅可以用于 autoencoder <script type="math/tex" id="MathJax-Element-479">autoencoder</script>而且可以用于其他的机器学习和深度学习的方法中。

Principal Component Analysis(PCA)

上一小节介绍了利用神经网络构建 autoencoder <script type="math/tex" id="MathJax-Element-500">autoencoder</script>,由于该模型中有 tanh <script type="math/tex" id="MathJax-Element-501">tanh</script>函数的存在, 所以该模型是一个非线性的模型。这一节介绍 autoencoder <script type="math/tex" id="MathJax-Element-502">autoencoder</script>的线性版本,线性模型有一些好处,例如比较有效率, 不容易过拟合, 模型的复杂度低等。之所以没有先介绍线性的,再介绍非线性的(这样是比较正常的思路)是因为在深度学习的框架下非线性的 autoencoder <script type="math/tex" id="MathJax-Element-503">autoencoder</script>更加适合。如果现在我们想用线性的来对资料做些处理(降维),那么应该如何做呢?


这里写图片描述

考虑 output layer <script type="math/tex" id="MathJax-Element-504">output\ layer</script>中第 k <script type="math/tex" id="MathJax-Element-505">k</script> 个神经元的输出, 将如下非线性的autoencoder<script type="math/tex" id="MathJax-Element-506">autoencoder</script>:

hk(x)=j=0d~w(2)jk tanh(i=1dw(1)ijxi)
<script type="math/tex; mode=display" id="MathJax-Element-507">h_k(x) = \sum_{j = 0}^{\tilde{d}}w_{jk}^{(2)}\ tanh\bigg(\sum_{i=1}^{d}w_{ij}^{(1)}x_i\bigg)</script>
变为线性的 autoencoder <script type="math/tex" id="MathJax-Element-508">autoencoder</script>,即去掉非线性的函数 tanh <script type="math/tex" id="MathJax-Element-509">tanh</script>, 得到如下的表达方式:
hk(x)=j=0d~w(2)jk (i=1dw(1)ijxi)(1)
<script type="math/tex; mode=display" id="MathJax-Element-510">h_k(x) = \sum_{j = 0}^{\tilde{d}}w_{jk}^{(2)}\ \bigg(\sum_{i=1}^{d}w_{ij}^{(1)}x_i\bigg)\tag1</script>

在这里我们考虑 w(1)ij=w(2)ji <script type="math/tex" id="MathJax-Element-511">w_{ij}^{(1)} = w_{ji}^{(2)}</script> 这种特殊情况(可以认为这样的限制是在做 regularization <script type="math/tex" id="MathJax-Element-512">regularization</script>,或者是为了简单)。那么 (1) <script type="math/tex" id="MathJax-Element-513">(1)</script>式可以写为:

hk(x)=j=0d~wkj (i=1dwijxi)(2)
<script type="math/tex; mode=display" id="MathJax-Element-514">h_k(x) = \sum_{j = 0}^{\tilde{d}}w_{kj}\ \bigg(\sum_{i=1}^{d}w_{ij}x_i\bigg)\tag2</script>
因为我们主要是为了对数据进行降维,所以这里考虑的情况是 d~<d <script type="math/tex" id="MathJax-Element-515">\tilde{d} < d</script>。
W=[wij]d×d~ <script type="math/tex" id="MathJax-Element-516">W = [w_{ij}]_{d \times \tilde{d}}</script>, 那么可以得到 (2) <script type="math/tex" id="MathJax-Element-517">(2)</script>的向量形式:
h(x)=WWTx
<script type="math/tex; mode=display" id="MathJax-Element-518">h(x) = WW^Tx</script>

其中:

W=w11 w12  w1d~w21 w22  w2d~w31 w32  w3d~wd1 wd2  wdd~
<script type="math/tex; mode=display" id="MathJax-Element-519">\begin{equation} W = \begin{bmatrix} w_{11} \ w_{12} \ \cdots\ w_{1\tilde{d}} \\ w_{21} \ w_{22} \ \cdots\ w_{2\tilde{d}} \\ w_{31} \ w_{32} \ \cdots\ w_{3\tilde{d}} \\ \cdots \\ w_{d1} \ w_{d2} \ \cdots\ w_{d\tilde{d}} \\ \end{bmatrix} \end{equation}</script>

Linear autoencoder error function

我们的目的依然是为了让编码器的输出和输入尽可能的相似,因此定义如下的 error function <script type="math/tex" id="MathJax-Element-200">error\ function</script>:

Ein(h)=Ein(W)=1Nn=1NxnWWTxn2(3)
<script type="math/tex; mode=display" id="MathJax-Element-201">E_{in}(h) = E_{in}(W) = \frac1N\sum_{n=1}^{N}\|x_n - WW^Tx_n\|^2\tag3</script>

现在我们的目标就是要寻找最佳的 W <script type="math/tex" id="MathJax-Element-202">W</script>来使得Ein(W)<script type="math/tex" id="MathJax-Element-203">E_{in}(W)</script>最小, 因为是 square error <script type="math/tex" id="MathJax-Element-204">square\ error</script>,所以我们接下来推导其解析解。

因为 WWT <script type="math/tex" id="MathJax-Element-205">WW^T</script>是一个半正定的矩阵,经过 eigen value decompose <script type="math/tex" id="MathJax-Element-206">eigen\ value\ decompose</script>可以得到 WWT=VΓVT <script type="math/tex" id="MathJax-Element-207">WW^T = V\Gamma V^T</script>, 其中:

  • VVT=VTV=Id <script type="math/tex" id="MathJax-Element-208">VV^T = V^TV = I_{d}</script>, V <script type="math/tex" id="MathJax-Element-209">V</script>是维度为d×d<script type="math/tex" id="MathJax-Element-210">d\times d</script>的单位正交阵 orthogonal <script type="math/tex" id="MathJax-Element-211">orthogonal</script>。
  • Γ <script type="math/tex" id="MathJax-Element-212">\Gamma</script> 是一个对角线矩阵,其对角线上的元素为 WWT <script type="math/tex" id="MathJax-Element-213">WW^T</script>的特征值,根据 rank(ab)min{rank(a),rank(b)} <script type="math/tex" id="MathJax-Element-214">rank(ab) \le min\{rank(a), rank(b)\}</script>,可知 rank(Γ)d~ <script type="math/tex" id="MathJax-Element-215">rank(\Gamma) \le \tilde{d}</script>

所以 (3) <script type="math/tex" id="MathJax-Element-216">(3)</script>式中的 WWTxn <script type="math/tex" id="MathJax-Element-217">WW^Tx_n</script>可以变为 VΓVTxn <script type="math/tex" id="MathJax-Element-218">V\Gamma V^Tx_n</script>, 这里首先来简单看一下 VΓVTxn <script type="math/tex" id="MathJax-Element-219">V\Gamma V^Tx_n</script>的物理意思是什么?

  • VT(xn) <script type="math/tex" id="MathJax-Element-220">V^T(x_n)</script>: (d×d)×(d×1) <script type="math/tex" id="MathJax-Element-221">(d\times d)\times(d\times 1)</script>, 表示对 xn <script type="math/tex" id="MathJax-Element-222">x_n</script>在基 VT <script type="math/tex" id="MathJax-Element-223">V^T</script>下进行旋转或者是镜像变换,向量的长度没有变化,只是坐标系统改变了
  • Γ() <script type="math/tex" id="MathJax-Element-224">\Gamma(\bigcirc)</script>: (d×d)×(d×1) <script type="math/tex" id="MathJax-Element-225">(d\times d)\times(d\times 1)</script> Γ <script type="math/tex" id="MathJax-Element-226">\Gamma</script>矩阵的对角线上最多只有 d~ <script type="math/tex" id="MathJax-Element-227">\tilde{d}</script>个非零元,表明有多于 dd~ <script type="math/tex" id="MathJax-Element-228">d - \tilde{d}</script>个零元,该操作将 d×1 <script type="math/tex" id="MathJax-Element-229">\bigcirc_{d\times1}</script>相应位置上的元素变为 0 <script type="math/tex" id="MathJax-Element-230">0</script>,其他的位置上的元素进行了缩放
  • V()<script type="math/tex" id="MathJax-Element-231">V(\otimes)</script>: (d×d)×(d×1) <script type="math/tex" id="MathJax-Element-232">(d\times d)\times(d\times 1)</script>,和第一步的操作互逆,即将向量换回原始的坐标系。

直观上讲可以看到 (3) <script type="math/tex" id="MathJax-Element-233">(3)</script>式的过程其实就是将原始的特征 xn <script type="math/tex" id="MathJax-Element-234">x_n</script>进行旋转,将某些维度置为 0 <script type="math/tex" id="MathJax-Element-235">0</script>,其他维度进行缩放,然后再反向旋转回原始坐标下,然后和原来的特征xn<script type="math/tex" id="MathJax-Element-236">x_n</script>求取 square error <script type="math/tex" id="MathJax-Element-237">square\ error</script>。

通过这样的操作我们就将 W <script type="math/tex" id="MathJax-Element-238">W</script>的最佳化问题转换为Γ,V<script type="math/tex" id="MathJax-Element-239">\Gamma, V</script>的最佳化问题,如果可以求到最佳的 Γ,V <script type="math/tex" id="MathJax-Element-240">\Gamma, V</script>,就可以得到最佳的 W <script type="math/tex" id="MathJax-Element-241">W</script>。

首先求解 Γ<script type="math/tex" id="MathJax-Element-242">\Gamma</script> 的最佳化问题:

minVminΓ1Nn=1NVIVTxnxnVΓVTxnWWTxn2
<script type="math/tex; mode=display" id="MathJax-Element-243">\mathop{min}\limits_{V}\mathop{min}\limits_{\Gamma}\frac1N\sum_{n=1}^{N}\| \underbrace{VIV^Tx_n}_{x_n} - \underbrace{V\Gamma V^Tx_n}_{WW^Tx_n}\|^2</script>

这个时候 V <script type="math/tex" id="MathJax-Element-244">V</script>可以看成是一个常数不做考虑, 去掉一些对结果不影响的项,目前的最佳化问题其实是:

minΓV(IΓ)VTxn2(4)
<script type="math/tex; mode=display" id="MathJax-Element-245">\mathop{min}\limits_{\Gamma}\sum\|V(I - \Gamma)V^Tx_n\|^2\tag4</script>

想要最小化 (4) <script type="math/tex" id="MathJax-Element-246">(4)</script>我们就要想办法从 (IΓ) <script type="math/tex" id="MathJax-Element-247">(I - \Gamma)</script>中得到更多的 0 <script type="math/tex" id="MathJax-Element-248">0</script>。所以最理想的 Γ<script type="math/tex" id="MathJax-Element-249">\Gamma</script> 应该是一个对角矩阵,并且对角线上的元素为 1 <script type="math/tex" id="MathJax-Element-250">1</script>,但是由于rank(Γ)d~<script type="math/tex" id="MathJax-Element-251">rank(\Gamma) \le \tilde{d}</script>, 不失一般性所以最佳的 Γ <script type="math/tex" id="MathJax-Element-252">\Gamma</script>的行使如下:

Γopt=[Id~000]
<script type="math/tex; mode=display" id="MathJax-Element-253">\begin{equation} \Gamma_{opt} = \begin{bmatrix} I_{\tilde{d}} && 0 \\ 0 && 0 \\ \end{bmatrix} \end{equation}</script>

现在通过分析我们得到了最佳的 Γ <script type="math/tex" id="MathJax-Element-254">\Gamma</script>的形式,接下来分析在这样的最佳的 Γ <script type="math/tex" id="MathJax-Element-255">\Gamma</script>下,如何求解最佳的 V <script type="math/tex" id="MathJax-Element-256">V</script> ,正如前面所分析的,(4)<script type="math/tex" id="MathJax-Element-257">(4)</script>式中的第一个 V <script type="math/tex" id="MathJax-Element-258">V</script>所对应的操作是进行旋转,不影响向量的长度,所以在这里可以把式子中的V<script type="math/tex" id="MathJax-Element-259">V</script>去掉,并且需要注意的是, 此时 Γ <script type="math/tex" id="MathJax-Element-260">\Gamma</script> 的形式已经确定, 所以最佳化的问题变为:

minVn=1N[000Idd~]1ΓoptVTxn2
<script type="math/tex; mode=display" id="MathJax-Element-261">\begin{equation} \mathop{min}\limits_{V}\sum_{n=1}^{N} \bigg|\bigg| \underbrace{ \begin{bmatrix} 0 && 0 \\ 0 && I_{d-\tilde{d}} \\ \end{bmatrix} }_{1 - \Gamma_{opt}} V^Tx_n \bigg|\bigg|^2 \end{equation}</script>

转换为最大化问题:

maxVn=1N[Id~000]VTxn2(5)
<script type="math/tex; mode=display" id="MathJax-Element-578">\begin{equation} \mathop{max}\limits_{V}\sum_{n=1}^{N} \bigg|\bigg| \begin{bmatrix} I_{\tilde{d}} && 0 \\ 0 && 0 \\ \end{bmatrix} V^Tx_n \bigg|\bigg|^2 \tag5 \end{equation}</script>

d~=1 <script type="math/tex" id="MathJax-Element-579">\tilde{d} = 1</script>的时候,那么其实就只有 VT <script type="math/tex" id="MathJax-Element-580">V^T</script>中的第一行 vT <script type="math/tex" id="MathJax-Element-581">v^T</script>起作用, (5) <script type="math/tex" id="MathJax-Element-582">(5)</script>式子变为

maxvn=1NvTxnxTxvs.t.vTv=1(6)
<script type="math/tex; mode=display" id="MathJax-Element-583">max_v\sum_{n=1}^{N}v^Tx_nx_x^Tv\quad s.t.v^Tv = 1\tag6</script>
等式约束的最优化问题可以得到如下的拉格朗日函数:
L(v,λ)=n=1NvTxnxTxv+λ(vTv1)
<script type="math/tex; mode=display" id="MathJax-Element-584">L(v, \lambda) =\sum_{n=1}^{N}v^Tx_nx_x^Tv + \lambda(v^Tv - 1) </script>
对变量 v <script type="math/tex" id="MathJax-Element-585">v</script> 求偏导数可得:
Lv=n=1NxnxTnv+λv
<script type="math/tex; mode=display" id="MathJax-Element-586">\frac{\partial L}{\partial v}=\sum_{n=1}^{N}x_nx_n^Tv+\lambda v</script>
所以最佳的 v <script type="math/tex" id="MathJax-Element-587">v</script> 需要满足的条件是:
n=1NxnxTnv=λv
<script type="math/tex; mode=display" id="MathJax-Element-588">\sum_{n=1}^{N}x_nx_n^Tv = \lambda v</script>
到这里我们发现 v <script type="math/tex" id="MathJax-Element-589">v</script> 是特征值 λ<script type="math/tex" id="MathJax-Element-590">\lambda</script> 所对应的特征向量,如果想要 (6) <script type="math/tex" id="MathJax-Element-591">(6)</script>式中的 target function <script type="math/tex" id="MathJax-Element-592">target\ function</script>最大, 那么 λ <script type="math/tex" id="MathJax-Element-593">\lambda</script>就要是 XTX <script type="math/tex" id="MathJax-Element-594">X^TX</script>最大的特征值,这时 λ <script type="math/tex" id="MathJax-Element-595">\lambda</script> 所对应的特征向量 v <script type="math/tex" id="MathJax-Element-596">v</script> 就是上述最优化问题(6)<script type="math/tex" id="MathJax-Element-597">(6)</script>的最优解 vopt <script type="math/tex" id="MathJax-Element-598">v_{opt}</script>,这样就求得了矩阵 V <script type="math/tex" id="MathJax-Element-599">V</script>中的第一行。

对于一般的d~<script type="math/tex" id="MathJax-Element-600">\tilde{d}</script> {vj}d~j=1 <script type="math/tex" id="MathJax-Element-601">\{{v_j}\}_{j = 1}^{\tilde{d}}</script>是矩阵 XTX <script type="math/tex" id="MathJax-Element-602">X^TX</script>的最大的 d~ <script type="math/tex" id="MathJax-Element-603">\tilde{d}</script>个特征值所对应的特征向量。

可以得到最佳的 w <script type="math/tex" id="MathJax-Element-604">w</script>是:{wj}=top eigenvectors<script type="math/tex" id="MathJax-Element-605">\{w_j\} = top\ eigenvectors</script>

PCA <script type="math/tex" id="MathJax-Element-606">PCA</script>更详细好懂的讲解见:http://blog.codinglabs.org/articles/pca-tutorial.html

小结

本篇简单的介绍了 deep learning <script type="math/tex" id="MathJax-Element-291">deep\ learning</script>, 可以将其看做是 nerual network <script type="math/tex" id="MathJax-Element-292">nerual\ network</script>的延伸。主要介绍了其中涉及到的两个问题,一个是 autoencoder <script type="math/tex" id="MathJax-Element-293">autoencoder</script>,用于预训练网络的初始权重,或者可以认为该方法是在找数据最好的表现方式;一个是 denoising autoencoder <script type="math/tex" id="MathJax-Element-294">denoising\ autoencoder</script>,用于得到更加 robust <script type="math/tex" id="MathJax-Element-295">robust</script>的模型。最后介绍了非线性的 autoencoder <script type="math/tex" id="MathJax-Element-296">autoencoder</script>如果退化为为线性的,那么就得到了著名的降维方法 PCA <script type="math/tex" id="MathJax-Element-297">PCA</script>。

Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐