《深度学习》/《Deep Learning》——深度学习圣经的读书笔记

学习方法

  1. 对着书看一遍,把理解的内容写成笔记
  2. 看完一章后,看着笔记和书,把内容复习一下,把需要画线的地方画好并理解
  3. 逐层深入:这本书讲解基础概念讲得不生动,但是高层次上有很多不错的高瞻远瞩的见解,所以先看网文理解到基本的网络(如RNN-LSTM),然后看书深化理解

*. Jumping <script type="math/tex" id="MathJax-Element-1">Jumping</script> Read <script type="math/tex" id="MathJax-Element-2">Read</script>:读某一章很痛苦的时候,先读后面一章,然后返回来读

熟悉语音,VAE,tf,python,和深度学习的最佳方法——跟进大佬用tf写的语音转换代码,比如VAE那份,跑起来并改善

证明技法

泰勒级数逼近后,可以带入想要的参数常量P155
做简化,初始化为0,等

证明A方法=B方法:
在写出利用了A/B的代价函数/权重特征值/Hessian,然后联立对比

概论

  • 当有5k样本的时候,就可以达到可接受的性能
  • 当有10M个样本的时候,一般就可以超过人类的表现

矩阵

基础

  • 注意向量的子集的表示方法, x1 <script type="math/tex" id="MathJax-Element-3">x_{-1}</script>表示是 x <script type="math/tex" id="MathJax-Element-4">x</script>中除去 x1 <script type="math/tex" id="MathJax-Element-5">x_{1}</script>的子集,如果令集合 S={1,3,6} <script type="math/tex" id="MathJax-Element-6">S=\{1,3,6\}</script>,那么集合 xS <script type="math/tex" id="MathJax-Element-7">x_{-S}</script>表示除去 x1 <script type="math/tex" id="MathJax-Element-8">x_{1}</script>, x3 <script type="math/tex" id="MathJax-Element-9">x_{3}</script>, x6 <script type="math/tex" id="MathJax-Element-10">x_{6}</script>
  • 转置是沿着对主对角线的翻转,主对角线是左上角开始的

乘法

矩阵乘法不可教(交换)

单位矩阵和逆矩阵

线性方程组可以求解,而这个解要用到矩阵的逆操作

A1A=In
<script type="math/tex; mode=display" id="MathJax-Element-11"> A^{-1} A = I_n </script>
有了这个逆操作很简单就可以求取满秩的线性方程

逆矩阵存在的条件:线性相关

  • X向量的线性组合即生成子空间包含了b,所以要求A的维度大于b的维度,冗余即为线性相关,可以表示为其他向量的特征组合
  • 必须方阵,线性无关的时候称为奇异

线性相关

对一组向量a1,a2,…an,如果有 :

k1a1+k2a2+...=0
<script type="math/tex; mode=display" id="MathJax-Element-184"> k1a1+k2a2+...=0 </script>
则这组向量是线性相关的

对于任意的b使得

Ax=b
<script type="math/tex; mode=display" id="MathJax-Element-185"> Ax=b </script>
成立,那么当b的维度为m时,A需要恰好m个相互线性无关的列向量(当大于m个的时候,肯定会有一些向量没办法跟其他的保持线性无关,就会变成不止一个b)

逆矩阵有左乘和右乘,分别是:

A1A=I
<script type="math/tex; mode=display" id="MathJax-Element-186"> A^{-1}A=I </script>

AA1=I
<script type="math/tex; mode=display" id="MathJax-Element-187"> AA^{-1}=I </script>
对于方阵有左乘等价于右乘

秩 Rank

如果上面n个向量能选出最多的r个使得构成线性无关的子集,并且任意加一个都会变成线性相关的,那么r就是矩阵的秩

这个向量组称为最大线性无关向量组

衡量向量的大小:范数(norm)

几何角度来看,x的范数,就是原点O到点x的距离
最常用的是p范数:

||x||p=(|xi|p)1p
<script type="math/tex; mode=display" id="MathJax-Element-14"> ||x||_p = ( \sum |xi|^p )^{1\over p} </script>
单位范数即满足
||x||p=1
<script type="math/tex; mode=display" id="MathJax-Element-15"> ||x||_p=1 </script>
的点在平面上组成的线

  • 0范数:衡量x中0的数量(不用上式定义)
  • 1范数:令p=1,得元素绝对值之和,单位范数是方形
  • 2范数:p=2,欧几里得范数,大小表示原点到当前点的距离

不同p值的单位范数:
image

矩阵的范数:

  • 1-范数:

    ||A||1=maxji=1m|ai,j|
    <script type="math/tex; mode=display" id="MathJax-Element-16"> ||A||_1 = \max_j\sum_{i=1}^m|a_{i,j}| </script>
    列和范数,即所有矩阵列向量绝对值之和的最大值

  • 2-范数:

    ||A||2=λ1
    <script type="math/tex; mode=display" id="MathJax-Element-17"> ||A||_2 = \sqrt{\lambda_1} </script>
    lambda为A^TA的最大特征值
    谱范数,即A’A矩阵的最大特征值的开平方

  • ∞-范数:

    ||A||=maxij=1N|ai,j|
    <script type="math/tex; mode=display" id="MathJax-Element-18"> ||A||_\infty = \max_i\sum_{j=1}^N|a_{i,j}| </script>
    行和范数,即所有矩阵行向量绝对值之和的最大值

  • F-范数:

    ||A||F=i=1mj=1n|ai,j|212
    <script type="math/tex; mode=display" id="MathJax-Element-19"> ||A||_F=\left(\sum_{i=1}^m\sum_{j=1}^n|a_{i,j}|^2\right)^{\frac{1}{2}} </script>
    Frobenius范数,即矩阵元素绝对值的平方和再开平方,类似于向量的L2范数,很多深度学习被归结于F范数的最优化问题,比如PCA和Autoencoder

  • 核范数:

    ||A||=i=1nλi
    <script type="math/tex; mode=display" id="MathJax-Element-20"> ||A||_* = \sum_{i=1}^{n}\lambda_i </script>
    其中 λi <script type="math/tex" id="MathJax-Element-21">\lambda_i</script>是A的奇异值。
    即奇异值之和。

特殊的矩阵:

  • 对角只在主对角线上含有非零元素
    • 进行乘法的时候只需要把非零元素跟对应行相乘即可
    • 机器学习中,如果把一些矩阵限定为对角阵,可以降低计算代价
    • 对于非方形的矩阵,要变成对角阵,需要在缩放后在后面补零或者删除一些部分
      A=AT
      <script type="math/tex; mode=display" id="MathJax-Element-22"> A=A^T </script>
  • 对称表示对称元素相等。如,距离度量矩阵
    Ai,j=Aj,i
    <script type="math/tex; mode=display" id="MathJax-Element-23"> A_{i,j}=A_{j,i} </script>
  • 正交矩阵求逆代价小,是行向量和列向量分别标准正交*
    ATA=AAT=I
    <script type="math/tex; mode=display" id="MathJax-Element-24"> A^T A=AA^T =I </script>

    A1=AT
    <script type="math/tex; mode=display" id="MathJax-Element-25"> A^{-1}=A^T </script>

*标准正交:两个向量都是单位向量(范数=1的向量),而且正交(夹角为90°)

  • 所有特征>0称为正定,非负的半正定

方阵的特征值分解

就像把一个数变成不同的素数的乘积一样,矩阵也可以分解成不同的组成成分:
例如,可以把矩阵A中提取出特征向量v和特征值λ:(没有分解它)

Av=λv
<script type="math/tex; mode=display" id="MathJax-Element-26"> Av= \lambda v </script>
则实数λ称为A的特征值,v称为特征向量
- 此时,v与Av共线,λ指出了v跟Av的方向和长度关系
- 因此v可以直接取单位向量。

要还原A,就需要借助A的全部单位特征向量v和全部特征值λ,把A的所有的线性无关是单位特征v组合在一起形成特征矩阵:

V={v(1),...,v(n)}
<script type="math/tex; mode=display" id="MathJax-Element-27"> V=\{v^{(1)},...,v^{(n)}\} </script>
又把所有的特征值λ组成向量:
λ=[λ1,...,λn]T
<script type="math/tex; mode=display" id="MathJax-Element-28"> \lambda=[\lambda_1,...,\lambda_n]^T </script>
然后就会有:
A=Vdiag(λ)V1
<script type="math/tex; mode=display" id="MathJax-Element-29"> A=Vdiag(\lambda)V^{-1} </script>
于是完成了方阵的特征值分解

任意矩阵的特征值分解

对于不是方阵的任意矩阵,也照样可以进行分解。其中,实对称矩阵是一定能分解成实特征向量和实特征值的:

A=QΛQT
<script type="math/tex; mode=display" id="MathJax-Element-30"> A=Q \Lambda Q^T </script>
其中,Q是A的特征向量组成的正交矩阵, Λ <script type="math/tex" id="MathJax-Element-31">\Lambda</script>是特征值组成的对角阵。
Q是特征向量的组合,表示了组成原来的向量A的基向量的组织方式, Λ <script type="math/tex" id="MathJax-Element-32">\Lambda</script>是这些基向量各自向自己的方向延伸多少倍就可以还原A
因为这样的组织不唯一,为了唯一,一般把 Λ <script type="math/tex" id="MathJax-Element-33">\Lambda</script>降序排列。
由这样的分解可以看出矩阵有的许多性质:
- 奇异:奇异矩阵一定要有0特征值
- 正定:所有特征>0,其保证了如果 xTAx=0 <script type="math/tex" id="MathJax-Element-34">x^TAx=0</script>,那么 x=0 <script type="math/tex" id="MathJax-Element-35">x=0</script>
- 半正定:所有特征≥0,其保证了 xTAx0 <script type="math/tex" id="MathJax-Element-36">x^TAx\ge0</script>

奇异值分解SVD

还有一种分解矩阵的方式,就是分解成奇异向量和奇异值,这样的分解不单止可以让每一个实数矩阵可以进行分解,而且,用处更多.

分解成三个矩阵的乘积:

A=UDVT
<script type="math/tex; mode=display" id="MathJax-Element-37"> A=UDV^T </script>
分解成三个矩阵的乘积,分别是:U左奇异向量,D奇异值的对角阵,V右奇异向量。

  • 这样分解可以拓展矩阵求逆到非方矩阵上,其中,D矩阵也不一定是方阵。
  • 经常不用很多特征值就可以表达全部信息,可以用前r大的来表示。
  • 因为其求取AAT和ATA获得,这些都是对称矩阵所以一定有奇异值

没办法计算逆的时候,可以求伪逆

逆经常用来求取线性方程的解,但是对于非满秩的矩阵却没法求取逆,所以可以求取Moore-Penrose伪逆,A的伪逆用 A+ <script type="math/tex" id="MathJax-Element-38">A^+</script>表示。

如果用伪逆得到了一个解 x=A+y <script type="math/tex" id="MathJax-Element-39">x=A^+y</script>,那么这个解的L2范数会是所有可行解中最小的一个(也就是说,跟真正正解的欧几里得距离最小的那一个)

trace迹:对角元素的和

用来表达一些矩阵运算,例如,它表达了计算F-范数的一种方式。
- 转置不变
- 服从“交换率”

Tr(AB)=Tr(BA)
<script type="math/tex; mode=display" id="MathJax-Element-40"> Tr(AB)=Tr(BA) </script>
- trace跟F范数和奇异值有紧密的联系

行列式

  • det(A)
  • 把一个方阵转换到实数,等于特征的乘积
  • 用来衡量矩阵经过乘法后比原来扩大还是缩小了多少

利用线性代数的样例——PCA

  1. 将样本均值变为0
  2. 将样本方差变为1【这两步使得样本趋向于满足2范数=1,向量的大小并不是那么重要,可以缩放,但是变成单位矩阵才能为计算提供更多信息】
  3. 计算协方差矩阵XXT
  4. 对上面进行特征分解
  5. 求前k大的特征值

  6. 假设用矩阵D作为解码器

  7. 假设有最优编码c*,令编码后的c跟c*的 L2 <script type="math/tex" id="MathJax-Element-41">L^2</script>范数距离最小,得到形式也很简单的编码函数:
    f(x)=DTx
    <script type="math/tex; mode=display" id="MathJax-Element-42"> f(x)=D^Tx </script>
    以及重构后的x的表达式:
    r(x)=DDTx
    <script type="math/tex; mode=display" id="MathJax-Element-43"> r(x)=DD^Tx </script>
  8. 进一步地,令编解码后的 r(x) <script type="math/tex" id="MathJax-Element-44">r(x)</script>跟x的F-范数距离最小
  9. 令问题简单化,使用一维向量d表示D
  10. 解得最优d为最大的特征值对应的特征向量(第一列特征向量)
  11. 后面特征向量以此类推

概率论

基本定义

  • 概率质量函数PMF:
    P(x)
    <script type="math/tex; mode=display" id="MathJax-Element-45"> P(x) </script>
  • 分布函数:
    F(x)=P(Xx)
    <script type="math/tex; mode=display" id="MathJax-Element-46"> F(x)=P(X\leq x) </script>
    表示P函数在曲线下,左半块的面积
  • 概率密度函数PDF:
    G(x;a,b)=P(aXb)=F(a)F(b)
    <script type="math/tex; mode=display" id="MathJax-Element-47"> G(x;a,b)=P(a\leq X\leq b)=F(a)-F(b) </script>
    其中,符号“ ; <script type="math/tex" id="MathJax-Element-48">;</script>”表示“以…为参数”。并不会要求p(x)≤1
  • 联合密度函数:二维的F(x)
    F(x,y)
    <script type="math/tex; mode=display" id="MathJax-Element-49"> F(x,y) </script>
  • 边缘概率:
    如果已经知道了一组变量的联合分布,要求其中一个子集的概率分布,比如要求x,y的联合分布中x的边缘概率,那就把每一个x下所有的y的概率值累加作为这个x的概率,写在纸的边缘,就是x的边缘概率

对于连续型变量,就是对y求积分

p(x)=p(x,y)dy
<script type="math/tex; mode=display" id="MathJax-Element-50"> p(x)=\int p(x,y)dy </script>

条件概率

  • 贝叶斯公式,只在P>0时有定义(可计算)
  • 条件概率的链式法则:可以使用链式法则变成每一次都只有一个元素做前提的情况

相互独立和条件独立

  • 相互独立:如果一个概率分布可以写成两个因子x和y的乘积,那么就是相互独立,写做 xy <script type="math/tex" id="MathJax-Element-51">x\bot y</script>
  • 条件独立:如果一个条件概率分布x和y在条件z下可以写成乘积的形式,那么就是条件独立的,写做 xy|z <script type="math/tex" id="MathJax-Element-52">x\bot y|z</script>

期望和方差

  • 期望E:

当x由P产生,f作用于x时候,f(x)的平均值。也就是f(x)在每一个x上乘以权重p(x)后的权值,全部积起来的积分

ExP[f(x)]=p(x)f(x)dx
<script type="math/tex; mode=display" id="MathJax-Element-206"> \mathbb{E}_{x\sim P}[f(x)]=\int p(x)f(x)dx </script>
- 方差Var:

衡量的是根据概率分布进行采样的时候,x的函数值会有多大差异

Var(f(x))=E[(f(x)E[f(x)])2]
<script type="math/tex; mode=display" id="MathJax-Element-207"> Var(f(x))=\mathbb{E}[(f(x)-\mathbb{E}[f(x)])^2] </script>
- 协方差Cov:

  • 描述多维随机变量之间的相关性,看他们是不是跟y=x和y=-x两根线的相关程度
  • 协方差绝对值越大越相关
  • 提供相关系数的实数值,相关系数是一种只反映相关程度不反应尺度大小的衡量标准,其进行了归一化
  • X=Y时就是方差,即矩阵x跟自己的协方差矩阵的对角元素是方差
  • 0协方差表示没有线性相关性,但是不排除没有独立性,独立性还排除了非线性相关性,比如依赖
    Cov(X,Y)=E(XY)E(X)E(Y)
    <script type="math/tex; mode=display" id="MathJax-Element-208"> Cov(X,Y)=E(XY)-E(X)E(Y) </script>

常用概率分布:

  • 均匀分布U,即 xU(a,b) <script type="math/tex" id="MathJax-Element-55">x\sim U(a,b)</script>
  • B伯努利=0-1分布,单个二值随机变量
  • M范畴分布=多项式分布,多个离散二值随机变量的任意分布
  • 高斯分布=正态分布:

    • 实数的分布,中心极限定理建模了复杂系统符合正态的噪声
    • 在所有具有同样的方差的分布中,N是对分布保留了最大的不确定性的分布,是对模型加入了最少先验知识的分布
    • 为了方便计算,令 β=1σ2 <script type="math/tex" id="MathJax-Element-56">\beta = {{1} \over {\sigma^2}}</script>,称为精度
  • 指数和Laplace分布:指数分布在x=0处有边界点,Laplace允许任意位置有边界点
  • Dirac分布:概率分布上所有的质量都在一个点上,无限窄又在0处接近1
  • 经验分布:把概率密度 1m <script type="math/tex" id="MathJax-Element-57">1 \over m</script>赋给m个点,使得在每个点处,等分布,而且呈现Dirac分布(不扩散到其他值处)
  • 混合分布:比如有一分布,其值取决于每一个值上有一个对应的分布,比如GMM,是任何平滑密度函数的万能近似器

先验概率和后验概率

  • 先验概率:观测到x之前已经知道的关于c的信息,与x无关,记作 P(c=i) <script type="math/tex" id="MathJax-Element-58">P(c=i)</script>
  • 后验概率:观测到x之后才计算的关于c的信息,记作 P(c|x) <script type="math/tex" id="MathJax-Element-59">P(c|x)</script>

深度学习中常见的跟概率分布有关的函数

  • Logistic Sigmoid:
    • 通常用来生成B分布中的参数Φ,因为从B分布可推出Φ符合此函数
  • Softplus:
    • 用来生成正态分布的参数β和σ
    • 名字来源于它是ReLU(又叫“正部函数”)的“软化”形式
    • 方便求导

信息论:

量化信息的准则

  • 非常可能发生的事件信息量很少甚至接近0
  • 比较不可能发生的信息量应该更高
  • 独立事件发生n次,带来的信息量应该是一次事件的n倍(线性可加性)
  • 信息量的底一般是e
  • 令0log0=0

几种熵(信息量):
- 自信息:单个事件的信息量

I(x)=logP(x)
<script type="math/tex; mode=display" id="MathJax-Element-216"> I(x)=-logP(x) </script>
- 香农熵:整个概率分布中的不确定性总量
- 对自信息求期望可得
- 分布越随机,香农熵越大
- 又称为 微分熵
H(x)=ExP[I(x)]=ExP[logP(x)]
<script type="math/tex; mode=display" id="MathJax-Element-217"> H(x)=\mathbb{E}_{x\sim P}[I(x)]=-\mathbb{E}_{x\sim P}[logP(x)] </script>
- 相对熵:KL散度,描述两个变量分布的差异
- 对两个分布的自信息作差,求期望可得
- 描述的东西是:如果设计了一种针对Q能让消息长度最小的编码,用这套编码编码P的话,需要增加的额外的信息量
- 是非负的,描述两个分布的差异,经常用来衡量“从属性”
DKL(P||Q)=ExP[logP(x)logQ(x)]
<script type="math/tex; mode=display" id="MathJax-Element-218"> D_{KL}(P||Q)=\mathbb{E}_{x\sim P}[logP(x)-logQ(x)] </script>
- 交叉熵:描述两个分布的差异
- 对Q最小化交叉熵等价于最小化散度
H(P,Q)=H(P)+DKL(P||Q)=ExPlogQ(x)
<script type="math/tex; mode=display" id="MathJax-Element-219"> H(P,Q)=H(P)+D_{KL}(P||Q)=-\mathbb{E}_{x\sim P}logQ(x) </script>
- 信息熵是描述信息量多少的一个量。信息熵是跟所有可能性有关系的。每个可能事件的发生都有个概率。信息熵就是平均而言发生一个事件我们得到的信息量大小。所以数学上, 信息熵其实是信息量的期望。其表达式如下:
H(x)=xUP(x)logP(x)
<script type="math/tex; mode=display" id="MathJax-Element-220"> H(x)=-\sum_{x\in U}P(x)\log P(x) </script>
- 条件熵:H(Y|X):描述在X下随机变量Y的不确定性
H(Y|X)=xUP(y|x)logP(y|x)
<script type="math/tex; mode=display" id="MathJax-Element-221"> H(Y|X)=-\sum_{x\in U}P(y|x)\log P(y|x) </script>
- 互信息:即信息增益,描述两个随机变量的相关程度
I(X,Y)=H(Y)H(Y|X)
<script type="math/tex; mode=display" id="MathJax-Element-222"> I(X,Y)=H(Y)-H(Y|X) </script>

结构化概率模型:

为了降低描述一个具有多个相互关联的变量的复杂的联合分布的成本。

用几个条件概率函数可以链式组成,来描述一个大的概率分布,减轻计算压力。

p(a,b,c)=p(a)p(b|a)p(c|b)
<script type="math/tex; mode=display" id="MathJax-Element-66"> p(a,b,c)=p(a)p(b|a)p(c|b) </script>
进一步地,可以用图来描述这种关系

  • 有向:用条件概率来表示条件概率分布

    p(a,b,c)=p(a)p(b|a)p(c|a,b)
    <script type="math/tex; mode=display" id="MathJax-Element-67"> p(a,b,c)=p(a)p(b|a)p(c|a,b) </script>
    上式中,a和b,c形成一条有向的

  • 无向:用概率因子的乘积来表示联合概率分布

    • 有相连的边的节点,是一组函数,这样一组函数组成 Ci <script type="math/tex" id="MathJax-Element-68">Ci</script>,每个团带有一个因子函数 ϕ(i)Ci <script type="math/tex" id="MathJax-Element-69">\phi^{(i)}Ci</script>把这些函数结合起来
    • 真正的联合概率跟这些的因子的乘积成比例,又为了保证整个联合概率的积分为1,会进行除以一个归一化常数 Z <script type="math/tex" id="MathJax-Element-70">Z</script>进行归一化
      p(a,b,c,d)=1Zϕ(1)(a,b,c)ϕ(2)(c,d)
      <script type="math/tex; mode=display" id="MathJax-Element-71"> p(a,b,c,d)={1\over Z} \phi^{(1)}(a,b,c)\phi^{(2)}(c,d) </script>
      上式中,a和b,c相互影响(等边三角形),a和d只能通过c相互影响

数值计算:

基础数学工具确定好之后,解决一些让计算机进行计算的时候可能会出现的实际问题
- 下溢出:接近0的数被四舍五入变成0
- 上溢出:大量级的数变成inf

解决方案:用softmax进行数值的稳定

  • ill-condition:输入的轻微扰动,加上计算的时候的四舍五入,就使得输出巨大变化,比如矩阵求逆有时候会很敏感

梯度优化

  • 一般用x*表示让优化目标f(x)的最小的x值,比如:
    x=argmin(f(x))
    <script type="math/tex; mode=display" id="MathJax-Element-72"> x^*=argmin (f(x)) </script>
  • 为了让所谓“最小化”有意义,一般来说优化目标或者Loss都会是一个标量

Jacobin和Hessian

高维矩阵对所有参数的一阶微分组成的矩阵就是Jacobin矩阵,二阶为Hessian矩阵,记作H

  • 用于计算二阶导数

    一般Hessian矩阵都是x跟y可以交换也就是处处对称的,所以可以分解成一组实特征值和一组特征向量的正交基。对于某一个方向d,其二阶导数等于 dTHd <script type="math/tex" id="MathJax-Element-73">d^THd</script>,如此一来:

    1. 当d刚好是H的一个特征向量,那么二阶导数就是这个特征向量对应的特征值
    2. 当不是特征向量,那么二阶导数就是所有特征值的加权平均了
  • 用于指导优化过程

    可以通过二阶导数预期一个梯度下降有多好,其中,在某个点x做二阶泰勒级数展开,其中的梯度就可以用Jacobin和Hessian矩阵表示,实践中,泰勒级数在更新率 ϵ <script type="math/tex" id="MathJax-Element-74">\epsilon</script>很大的时候可能会失去意义,所以应当计算得到启发式的大小合适的更新率,跟H和g有关的。

  • 用于进行“是否局部最优”测试

    可以用二阶导数对”是否局部最优点“进行测试,有一些鞍点上H矩阵还是会有非0的值,证明在这些方面上还没有达到最优。

  • 结合牛顿法加快搜索

    用一个二阶泰勒展开近似f(x),一步跳到最小点
    用一阶导数的称为一阶优化算法,用Hessian的称为二阶优化算法

设计优化算法的条件

深度学习只对一些函数设计优化算法,设计的时候经常要求这些函数满足某些条件,比如:
- 大多数情况都假设满足Lipschitz连续:

优化算法导致的微小变化将使得输出产生微小变化
- 非常成功的优化算法都要求满足凸优化条件:
- 只对凸函数适用,凸函数向下凹,即H矩阵处处半正定的函数,这些函数没有鞍点
- 虽然整个目标目标空间是非凸的,但是因为凸函数能使用Hessian矩阵的二阶优化算法,所以深度学习中很多子函数是凸函数

约束下的优化

在可能值下进行优化,比如,加条件 ||x||1 <script type="math/tex" id="MathJax-Element-75">||x||\leq1</script>

KKT方法:一种针对约束优化的通用解决方案

满足KKT条件的时候,就可以把一系列的约束函数转化为广义拉格朗日优化,可以把一系列的约束移动到对应的min,max优化目标上

  1. 比如有一系列的等式约束 g(i) <script type="math/tex" id="MathJax-Element-76">g^{(i)}</script>和一系列的不等式约束 h(i)0 <script type="math/tex" id="MathJax-Element-77">h^{(i)}\leq0</script>,那么就可以写出拉格朗日式:
    L(x,λ,α)=f(x)+Σλig(i)(x)+Σαih(i)(x)
    <script type="math/tex; mode=display" id="MathJax-Element-78"> L(x,\lambda,\alpha)=f(x)+\Sigma \lambda_i g^{(i)}(x)+\Sigma \alpha_i h^{(i)}(x) </script>
    于是就可以转化为最优化问题:
    min(x)max(λ)max(α,α0)L(x,λ,α)
    <script type="math/tex; mode=display" id="MathJax-Element-79"> min(x) max(\lambda) max(\alpha ,\alpha \geq 0) L(x,\lambda,\alpha) </script>
    等价于
    minf(x)
    <script type="math/tex; mode=display" id="MathJax-Element-80"> minf(x) </script>
  2. 在这个函数中,如果最优解 f(x) <script type="math/tex" id="MathJax-Element-81">f(x^*)</script>的值也是约束问题的解,表示这个解在可行域空间上没有碰到约束组成的边界,那么这个约束的KKT乘子(λ或者α)就可以设为0。否则,约束问题的最优解 x <script type="math/tex" id="MathJax-Element-82">x^*</script>就会就会碰到某个约束带来的边界,也就是说会有某个约束 h(i)=0 <script type="math/tex" id="MathJax-Element-83">h^{(i)}=0</script>
  3. 为了解出这个解,然后就可以对这个拉格朗日式关于x的微分变成0
  4. 然后就可以解出 L(x,λ,α) <script type="math/tex" id="MathJax-Element-84">L(x,\lambda,\alpha)</script>关于λ和α的关系式
  5. 可以用梯度下降或者解析方法求出λ和α的值

其中,满足一点是最优点的充分不必要条件,是KKT条件,它说一个点是最优点,但是不一定是唯一的最优点

例子:LWLR线性最小二乘法

机器学习:

任务Task:

  • 分类
  • 输入有缺失的情况下分类,通过学习所有相关变量的概率分布
  • 回归
  • 转录:转换
  • 机器翻译

设计机器学习任务

  1. 定义任务T
  2. 定义性能度量P(选择误差…MSE训练误差是要除以样本量的)
  3. 最小化误差

有监督学习和无监督学习

  • 有监督学习估计后验概率 p(y|x) <script type="math/tex" id="MathJax-Element-85">p(y|x)</script>
  • 无监督学习学习样本分布 p(x,y) <script type="math/tex" id="MathJax-Element-86">p(x,y)</script>

测试集,训练集

训练集和测试集应遵循独立同分布假设,独立表示每个数据集中的样本是相互独立的,同分布表示两个数据集应该采样自同样的分布,这个共享的同样的分布称为数据生成分布

容量,欠拟合,过拟合

  • 欠拟合:在训练集上不够低
  • 过拟合:训练和测试间差距太大

通过调整模型容量可以控制模型在欠拟合和过拟合之间的平衡,控制模型的容量方法很多,包括:
- 控制模型的假设空间,比如对数据分布进行5次多项式的假设,就比2次多项式的假设空间大
- 选择学习算法,实际上就是限制了一套函数族,所限制的理论容量称为表示容量,但是实际上因为算法实现的不完美,可能只能达到学习算法的有效容量
- 控制特征的维度

VC维

用VC维可以衡量模型的复杂性

统计学习指出,训练误差和泛化误差的差异上界随着模型容量增长,随着样本数量争夺而下降

但是深度学习的VC维度难以计算,因为:
- 边界太松
- 因为模型容量受制于优化算法

参数模型和非参数模型

  • 参数模型的参数量是确定的,在更多样本的情况下,测试误差会逼近贝叶斯误差(从先验分布推算出的最优误差)。但是模型容量不足以描绘模型的时候,训练误差会增大,尽管测试误差仍然会下降逼近一个贝叶斯误差稍微大的误差
  • 非参数没有参数量的限制,如KNN回归,使用样本而不是参数来记住模型,在更多样本的情况下,会逼近可能的最优泛化误差

NFL指出没有一个算法能在任何分布上最好

正则化

为了控制模型容量,可以通过增加假设空间的函数数量,或者增加假设空间的函数类型数。

由此一来,就要对假设空间的子空间进行选择

一般地,可以通过正则化进行假设空间的选择,以提供“偏好这个假设空间”的先验偏好,给偏好的假设空间一个加权,并在后面优化的时候,如果不被选择的优化空间明显好于这个偏好的,就接受不被偏好那个,从而保持“有可能接受”其他的不同假设空间

没有最优的算法,也没有最优的正则化形式,普遍的认知是对大多数任务,都应当有一款通用的正则化方法

为了调整超参数——验证集

经常,在训练的时候要调整超参数,但是超参数又不能直接从训练集中获取(可能会过拟合)所以需要另外一个集合公平地评价各组超参数的性能,于是要二八分割训练集以获得验证集。

验证和测试的方式

有两种方案:

1. 经典验证(用于数据量大的时候)

  • 训练集——用于训练
  • 验证集——用于作为超参数调整的基准,搜索超参数
  • 测试集——最后只用一次,用于输出算法的最终性能

2. 交叉验证(用于数据量小的情况)

  • 进行K-fold分割,获得训练集和测试集
  • 在训练集上训练,在测试集上测试
  • 以所有测试集合性能的平均作为整个数据集上性能的无偏估计
  • 用以上无偏估计作为验证,调整超参数

一些统计工具

点估计:要知道,参数是总体的,并不能真正可见,所以需要根据某一个函数,对数据集的某个参数进行估计,对 θ <script type="math/tex" id="MathJax-Element-87">\theta</script>的点估计结果一般记为 θ^ <script type="math/tex" id="MathJax-Element-88">\hat{\theta}</script>

偏差

bias(θ^m)=E(θ^m)θ
<script type="math/tex; mode=display" id="MathJax-Element-89"> bias(\hat \theta_m)=\mathbb{E}(\hat \theta_m)-\theta </script>
- 当bias=0,那么称为 无偏
- 当 limm+bias=0 <script type="math/tex" id="MathJax-Element-90">\lim_{m\rightarrow+\infty}bias=0</script>,称为 渐近无偏
- 有的时候一个估计是无偏的,但是不一定是最好的,我们有时候会采用有偏估计

方差和标准差

估计量的方差定义为:
Var(\hat \theta)

Var(θ^)
<script type="math/tex; mode=display" id="MathJax-Element-91"> Var(\hat \theta) </script>
- 当从样本中独立重采样的时候,我们也希望方差尽可能地小
- 但是标准差的估计量的定义并不是方差估计量的根号
- 样本方差的平方根跟方差无偏估计的平方根都低估了真实的标准差,相对而言,方差无偏估计的平方根会好一些
- 我们常用均值的标准差来给出测试结果的误差(根据3σ原则),这种情况下,一般说算法A比算法B好,表示在95%置信区间上,A的上界比B的下界小

权衡偏差和方差

我们希望偏差和方差都比较小,但是实际上几乎都做不到,一种方法是交叉验证,另一种是计算均方误差MSE:

MSE=E[(θ^mθ)2]
<script type="math/tex; mode=display" id="MathJax-Element-231"> MSE=\mathbb{E}[(\hat \theta_m - \theta)^2] </script>
=Bias(θ^m)2+Var(θ^m)
<script type="math/tex; mode=display" id="MathJax-Element-232"> =Bias(\hat \theta_m)^2+Var(\hat \theta_m) </script>
MSE度量了估计和真实参数θ之间平方误差的总体期望偏差,最低的MSE会落在偏差和方差的交点附近

一致性

在数据增加的时候,估计量的变化趋势,当一个估计量有一致性的时候,随着数据的增加会偏差会减少,趋向于真实的参数(而不是bias趋向于0)
*但是渐进无偏不一定代表有一致性(渐进无偏是一个对bias大小的定义,一致性是对估计的真实性的定义)

最大似然估计MLE

最常用的估计方法是最大似然估计

最大似然估计的估计量θ等于模型在生成数据 xi <script type="math/tex" id="MathJax-Element-233">x_i</script>时候的概率 pmodel(xi;θ) <script type="math/tex" id="MathJax-Element-234">p_{model}(x_i;\theta)</script>的乘积:

θML=argmaxpmodel(x;θ)
<script type="math/tex; mode=display" id="MathJax-Element-235"> \theta_{ML}=argmaxp_{model}(x;\theta) </script>
=argmaxi=1mpmodel(x(i);θ)
<script type="math/tex; mode=display" id="MathJax-Element-236"> =argmax\prod_{i=1}^{m}p_{model}(x^{(i)};\theta) </script>
- 等价于最小化训练集上的经验分布和模型分布上的交叉熵,也就是让模型上建模的分布(模型分布)拟合训练集上已有的数据分布(经验分布)
- 一般地,任何一个由负对数使然组成的损失定义的都是在上述两个分布上的交叉熵

MLE和MSE的关系

image

MLE的性质

在满足一定条件的情况下,MLE具有一致性:
- 真实分布p_{data} pdata <script type="math/tex" id="MathJax-Element-94">p_{data}</script>必须在模型族p_{model}(;\theta) pmodel(;θ) <script type="math/tex" id="MathJax-Element-95">p_{model}(;\theta)</script>。否则没有估计能还原
- 真实p_{data} pdata <script type="math/tex" id="MathJax-Element-96">p_{data}</script>必须刚好对应一个θ值,否则恢复后不知道应该采用哪一个θ值

而且就收敛速率来说是最好的渐进估计:
- Cramer-Rao下界证明了:不存在均方误差大于MLE的一致估计

贝叶斯统计

贝叶斯认为样本是可观测的,真实的θ是不能观测的,所以给出先验的假设,并通过观测样本修正假设,修正的过程就是条件概率相乘的过程:

p(θ|x(1),...x(m))=p(x(1),...x(m)|θ)p(θ)p(x(1),...x(m))
<script type="math/tex; mode=display" id="MathJax-Element-240"> p(\theta | x^{(1)},...x^{(m)})={p(x^{(1)},...x^{(m)}|\theta)p(\theta) \over p(x^{(1)},...x^{(m)})} </script>
因此对 p(x(m+1)|x(1),...x(m)) <script type="math/tex" id="MathJax-Element-241">p(x^{(m+1)}|x^{(1)},...x^{(m)})</script>的预测为:
p(x(m+1)|x(1),...x(m))=p(x(m+1)|θ)p(θ|x(1),...x(m))dθ
<script type="math/tex; mode=display" id="MathJax-Element-242"> p(x^{(m+1)}|x^{(1)},...x^{(m)})=\int p(x^{(m+1)} |\theta)p(\theta | x^{(1)},...x^{(m)})d\theta </script>
贝叶斯跟频率派的两点不同:
- 频率派评估方差以度量不确定性,贝叶斯通过积分
- 贝叶斯引进了贝叶斯先验分布使得模型参数向偏好的方向偏移

在数据有限的时候贝叶斯经常更好,但数据量大的时候会有较大计算代价

最大后验估计MAP

大多数情况下,计算贝叶斯后验是棘手的,所以应该对频率派和贝叶斯的方法结合,让点估计估计可行的近似解,先验进行选择:

θMAP=argmaxp(θ|x)=argmaxlogp(x|θ)+logp(θ)
<script type="math/tex; mode=display" id="MathJax-Element-100"> \theta_{MAP}=argmaxp(\theta |x)=argmax logp(x|\theta)+logp(\theta) </script>
前一项是标准的对数似然点估计,后一项是先验分布

进行这样的推断可以使用来自先验的信息降低方差,但是也引入了偏差,很多正则化都是通过MAP进行引入的。

统计附加知识

α小于等于P的时候:接受,小时候接受

常见监督学习算法

概率监督学习

对于线性回归,我们会对用一个均值描述其正态分布。

但是对于二元分类任务,输出是一个概率,这个均值就必须在(0,1)区间内。

所以可以使用Logistic Sigmoid函数把实数样本值压缩到这个区间内,然后在这个区间内执行线性分类。

此时,这个区间内表示的 p(y|x) <script type="math/tex" id="MathJax-Element-101">p(y|x)</script>就变成对应样本的概率:

p(y=1|x;θ)=σ(θTx)
<script type="math/tex; mode=display" id="MathJax-Element-102"> p(y=1|x;\theta)=\sigma (\theta^Tx) </script>
这样就可以对这个区间内概率均值进行正态分布初始化

LR于是就对log-odds进行线性回归预测

SVM与核方法

SVM输出的不是概率,而是类别标签
SVM通过定义一些经过设计的核函数,从而高效地在高维空间计算内积,打个比方,有一个这样的核函数:

k(a,b)=min(a,b)
<script type="math/tex; mode=display" id="MathJax-Element-103"> k(a,b)=min(a,b) </script>
这个核函数其实对应于高维空间中的某个内积,但是实现和计算起来却很简单,更复杂和常用的核函数包括RBF核。

高斯核实际上近似与一种模板匹配,假设训练样本(x1,y1),高斯核会把x1作为y1的模板。当来了一个待测试样本x2,高斯核会计算x1跟x2之间的欧几里得距离,如果距离很近,那么高斯核响应(核的输出)就会很大,那么样本x2属于标签y1的对应权重就会变大。

许多线性模型都可以用核方法加强算法优化

其他监督学习方法

KNN

作为一种非参数学习方法,具有极大的模型容量。
- 在样本无限多的时候能取得较高的精度,收敛于贝叶斯误差。
- 但是,计算成本很高
- 训练集小的时候泛化能力很差(因为把所有特征看成等权重的)

DCT

如果学习任意大小的决策树,那么可以被视为非参数算法

无监督学习算法

无监督学习的最经典的任务就是获得数据的“最佳”表示
- 低维表示
- 稀疏表示
- 独立表示

聚类问题有一个重要问题,就是我们不知道聚类的效果在真实世界中对应着什么,比如,我们希望对所有的小汽车进行聚类,却聚类出了所有红色的东西——我们只能知道他们是不同的

所以我们应该希望能对数据的聚类结果进行分布式表示(用一个向量存储每个样本的聚类标签),这样可以让每一个属性聚类到这个聚类标签的一个维度上,从而我们可以通过观察这些属性的组合来选择我们想要的标签。

PCA

PCA将输入x通过矩阵W投影到其最大方差的方向跟坐标轴对齐的方向,学习数据的正交线性变换,消除输入数据维度的相关性,从而消除数据中未知的变化因素
- 可以通过SVD实现,取SVD的右奇异向量可以把X进行正交化的线性变换

k-means

可以看成是一种k长度的one-hot编码,使得数据编码成k长度的向量

随机梯度下降

因为总的损失是每个样本的损失的期望,所以以mini-batch进行更新可以收敛到总体的ε。

在SGD之前,都是通过核函数构建计算矩阵完成的,开销很大。

深度学习受关注一方面是因为在学术界,在中等数据集上获得很好的泛化性能。在工业界,也因为SGD带来了可以扩展的,在大型数据集上训练非线性模型的方式。

深度学习算法的组成

深度学习算法根据以下4项组成:
- 特定的数据集
- 代价函数(经常含有一项进行统计估计的成分,很多时候还会有正则化)
- 优化过程(对于线性的优化过程,有闭式解,对于非线性的,可能需要用梯度下降等方法)
- 模型(算法选定的模型空间称为模型,也就是说,对数据可能的分布的假设(比如正态))

令深度学习发展的挑战

真正的挑战是:传统机器学习在类人工智能上泛化能力不足(语音识别,图像识别),而实际上这个困难有三个方面:

维度灾难

维度很大的时候,每一个维度上的特征数量可能很稀疏,对于一个需要被预测的样本,可能其某一维是在很稀疏的地方的,任何训练样本都不很接近或者甚至那个维度上没有训练样本,那么怎样给出一个合理的值?

局部不变性和平滑正则化

很多机器学习算法通过先验信念进行泛化,几乎所有的算法都基于“平滑先验”,也就是,在小区域内不会产生很大的变化,或者一个样本的输出跟它的邻居是相似的。包括核机器也是这样。

只要在需要学习的真实函数中的峰值和谷值处有足够的样本,那么平滑性假设能工作的很好。

一种方法就是做样本扩增,通过额外引入对数据假设增加样本量,可以描绘大量的区间。

深度学习的假设则是:数据由因素或者特征组合产生,而这些因素来自于一个层次结构的多个层级。这样的假设比较温和。

流形学习

流形是很多机器学习算法内部的重要理念。
对于在高维空间中的流型,要刻画整个流型其实是困难的,但是流型假设认为整个高维空间中大多数是无意义的点,有意义的概率质量是高度集中的,于是只要刻画高度集中的部分就可以。

一般涉及到图像,文本或者语音的任务时,流型假设近似是对的。有两个证据:
- 关于概率密度集中性:观察现实生活中的图像语音等,有意义的概率分布是高度集中的。
- 关于流型的连续性:我们大多数能想象到这些变换的形式,包括光照如何影响图像等。

*这个概念的意义深刻,启发我们为什么深度学习经常用于语音图像文本,而不是其他,也启发我们如何扩展到其他任务,如何想象你要描绘的流型,为你的流型收集什么样的数据,生成什么样的数据以描绘流型的邻域,为什么模型在一些样本上工作得不好,是不是把那一块认为是概率密度无意义的部分等。

因为流型假设,深度学习天生就适于扩展到那些我们人类很容易想象这些流型的邻域的任务上,我们能想象,于是能建模(比如LSTM中引入长短程依赖,CNN中做卷积),能针对性地收集合适的数据,甚至适合人类直接观察结果以进行调优。
反之,深度学习做不到的东西,同理。

要开发新的学习范式,可能要往这个方向,考虑怎样才能设计让人能调试的假设,超越受制于人类感官的流型假设,奔向更高维的空间去。
AutoML和Alpha可能就是宝贵的尝试,直接让机器进行可能空间的搜索,直接淘汰最限制模型搜索的人工步骤,直奔更有超越性的,人类想象不到的空间中去。

深度网络:现代实践

深度网络基础

线性模型经常无法处理特征间有相互影响关系的问题,所以可以采用一个函数族把特征映射到线性空间,然后再做线性分类。

深度网络优化的优点就是,只要由模型设计者选定函数族,学习算法自动能进行函数族内函数的具体选择和调试

一般为了实现非线性映射,经常用ReLU做映射函数族,其保留了许多线性的特征有利于优化,又有非线性的部分。

MLP为什么能解决异或:

单层感知机因为只有输出层有激活函数,能力有限,多层感知机能通过隐藏层,进行“预激活”(输入的激活函数)和“激活”(输出的激活函数),把数据变成线性可分,也就是说使得分界面不单只是sigmoid分界,而是任意形状的曲面,从而解决线性不可分问题

梯度的学习

因为非线性会让大多数我们感兴趣的模型变得非凸,所以经常用迭代方法优化

代价函数

用极大似然是一种最佳的代价函数,即使任务并不需要拟合整个任务的 p(y|x) <script type="math/tex" id="MathJax-Element-104">p(y|x)</script>,但是很多激活函数带来的指数影响会造成梯度消失,极大似然的负对数特性恰好能抵消掉这些梯度消失,所以一般都用极大似然。

输出单元

1. 用于拟合高斯输出分布的线性单元

线性单元不会饱和,所以适合用于使用梯度优化方法。

但是,因为要学习高斯分布的协方差矩阵必须要把协方差矩阵限定为一个正定矩阵,实际上线性单元很难学习协方差矩阵

2. 用于拟合B分布的sigmoid单元

B分布需要学习的是 p(y=1|x) <script type="math/tex" id="MathJax-Element-105">p(y=1|x)</script>,输出是(0,1),梯度不足,所以需要进行优化。

一般使用sigmoid函数进行logit概率的输出,为了抵消sigmoid’函数的饱和问题,采用负对数的极大似然损失函数进行抵消。

3. 用于拟合M分布的softmax单元

用于进行多分类的适合经常用softmax单元,它近似于等于一个argmax函数,但是是soft的,连续可微的,其要求每一个 y^i <script type="math/tex" id="MathJax-Element-106">\hat y_i</script>元素的取值都在[0,1]中,而且所有的输出的和等于1。

最大化对数似然的时候,针对输入zi,输出如下:
logsoftmax(z)_i=z_i-log\Sigma exp(z_j)

logsoftmax(z)i=zilogΣexp(zj)
<script type="math/tex; mode=display" id="MathJax-Element-107"> logsoftmax(z)_i=z_i-log\Sigma exp(z_j) </script>
因此,正确的zi的梯度被保留(而且是线性的),同时其他所有的错误的zj被降低,特别是惩罚最活跃的不正确预测。

反之,因为无法抵消饱和区的影响,对于softmax来说,MSE就是一个很差的损失函数。

其他输出单元的设计

输出单元的设计基本上是考虑其在所需损失函数上的梯度是否容易饱和来设计的,比如,在需要学习高斯分布的协方差的时候,就需要用精度β来替代\sigma σ <script type="math/tex" id="MathJax-Element-108">\sigma</script>,从而避免容易导致梯度饱和的除法和平方运算。

而要进行多峰回归的情况下,就需要输出多个高斯的输出,也就是混合高斯模型。

但是因为除法(除以方差)的数值不稳定性,基于梯度的方法对混合高斯模型可能是不稳定的,观察输出梯度的变化可以看得出来,这个时候就需要进行梯度截断等优化。

隐藏单元的设计

局部加权线性回归LWR:

只要给平方损失函数的每一维损失增加一个系数μ,一般是指数函数的形式
于是就可以对每一维调整权重单独进行拟合,这个权重使用指数函数,远离分界面的点就可以使得这个值很小,接近0,让离x远的点的效果减少

损失函数

增益率:因为信息增益倾向于取值较多的性质,当取值很多的时候会生成很多的子树以提高纯度,所以用信息量增益率提高
Gini:CART会用Gini最小的特征(纯度最高)的来划分当前数据集

聚类算法

无监督聚类:不是为了直接提取标签,只是用于提取特征和规律,对后续的处理进行帮助,比如T-SNE
闵可夫斯基距离:d(x,y)=(Σ(xi-yi)p)1/p\
p=1时,曼哈顿距离,p=2时,欧几里得距离
无序,非连续数据常用VDM距离表示,如果混杂的时候,可以用闵氏和VDM的和

谱聚类:
根据图进行距离,核心逻辑:如果相似度很低,那么在同一个簇的概率就会很小。
先对Laplace矩阵进行降维,然后对降维后的执行K-means

最优化:

BGD:最速下降法
SGD:损失函数会出现较大的波动
MGBD:Mini-Batch GD,结合BGD和SGD,使得速度更快,一般都用这个
NAG:Nesterov的改进的Momentum,每一次还带有二阶导数信息
AdaGrad:如何避免鞍点
1.迭代时间越长,步长越小,不会因为学习率太大而走过头,一下子飞出太阳系
2.不同参数使用不同学习率,接近0的导数很小,不容易有鞍点,于是步长很大
3.特别适用于稀疏数据

共轭梯度:

共轭梯度法(Conjugate Gradient)是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。 在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。

牛顿法和拟牛顿法:

牛顿法直接用二阶导数,要计算Hessian矩阵,一般用拟牛顿法通过模拟Hessian矩阵改进,直接计算第k次迭代的模拟Hessian矩阵Hk。
在满足拟牛顿条件的情况下可以使用,举例几种拟牛顿:
DFP:核心是求解Hessian矩阵的逆来近似
BGFS:核心是求解Hessian矩阵的模拟矩阵,利用S-M公式进行迭代
L-BGFS:BGFS的内存消耗很大,算法不再保存完整的矩阵,而是保留Hessian在计算中使用的行向量s和列向量k,而且还只保留前m个,丢弃比较早生成的向量(旧的梯度),而且计算的时候也不用计算H,直接计算s和k

激活函数:

设计激活函数的准则

  • 非线性的激活函数能处理复杂的非线性问题(扭曲分界面),线性的等于没有隐藏层
  • 能把重点的神经元进行激活和抑制

几种激活函数

Relu及其扩展

  • ReLu:
    单侧抑制,稀疏性,简单,梯度大而且一致
    但是直接把神经元置为0后,一票否决了相当于没有了这个神经元,让后期很脆弱,初始化的时候经常让偏置b等于一个小的正值允许导数通过
  • Leaky-ReLu:
    给负数加一个小的斜率
  • maxout:在输入和输出中间插入k个maxout节点,每个的输入用ReLU等线性函数,然后每个的输出取当前节点输入的最大值。

maxout相当于用k个分段线性函数组合拟合一个曲线,其中,取最大值的操作实际上执行了“分段”这件事,其中k个maxout单元在学习权重的过程中,拟合了对应位置的线性函数,整个maxout的组合就拟合了任意的激活函数。

而具有许多maxout单元产生了一定的冗余,从而减弱了灾难遗忘效应(神经元忘记了自己过去的任务)

sigmoid系列

  • sigmoid:

会把数据压缩到中间的区域,使得特征集中,但是处理后的输出是一个非负值,使得对任意参数W的求导都大于0,让梯度不一定能稳定收敛

另外,sigmoid在大多数情况下梯度都会饱和,除非有合适的负对数代价函数进行抵消

  • tanh:
    几乎都比sigmoid更好,带来0均值,解决了sigmoid让梯度总是大于0的问题,但是导数小于1,所以还是会梯度消失

RNN,AE,概率模型等不能采用分段线性单元,于是只能采用sigmoid系列

其他激活函数

  • 根本没有激活函数

某一些层完全是线性的,这样有效地减少了参数的数量
- softmax

以softmax作为激活函数相当于一种开关,通常只适用于需要明确地操作内存的情况
- RBF
- softplus
- hard tanh

架构设计

主要是设计宽度和深度

万能近似原理

万能近似原理指出一个大的(2^n 2n <script type="math/tex" id="MathJax-Element-109">2^n</script>大小)MLP,哪怕是单层的,只要激活函数是非线性的,就一定能学到任意一个函数。

虽然有一些结论指出ReLU能学到的函数是深度的指数级,但是实际上不一定有这样的函数,但是总的来说深度可以看成是步骤的连续,每一个步骤中有很多操作,一种隐含是假设就是这些操作的复合能表示任意复杂的函数。

总之,更宽的层提供更多的特征,而更深的层提供更多的操作步骤,是米和电饭锅的关系。

因此,更深的模型性能更好不是因为其参数更多(操作更多),而是因为操作的流水线更长,一般来说,当米足够的时候(由于流型假设,应该也不会太多),电饭锅的改进能提供更好的泛化能力,这是一种有用的先验。

BP算法

BP算法实际上只是一种计算导数的方法:不单止用于MLP,也可以用于其他模型;不单止用于梯度参数的计算,也可以用于其他参数。

输入输出层,隐藏层和参数的梯度通用公式见紫皮书P228

基本算法流程:

  1. 根据输出层的梯度,用上述公式求出输出层梯度
  2. 对每次迭代,把输出梯度带入到每一层次迭代中,每次求前一层的参数的梯度
  3. 用梯度下降法更新梯度

计算图模型

用这样来表达计算操作

X-->|relu|W

BP的简化

为了减少对每一次计算都计算子表达式的开销,对以下图:

graphLRw>|f|xx>|f|yy>|f|z
<script type="math/tex; mode=display" id="MathJax-Element-245"> graph LR w-->|f|x x-->|f|y y-->|f|z </script>
有以下两种计算导数的方案:
zw
<script type="math/tex; mode=display" id="MathJax-Element-246"> {\partial z \over \partial w} </script>
=f(y)f(x)f(w)
<script type="math/tex; mode=display" id="MathJax-Element-247"> = f'(y)f'(x)f'(w) </script>
=f(f(f(w))f(f(w)))f(w)
<script type="math/tex; mode=display" id="MathJax-Element-248"> = f'(f(f(w))f'(f(w)))f'(w) </script>
上面的方案是反向传播算法提供的方案,下面是它的改进,其中,只需要计算一次 f(w) <script type="math/tex" id="MathJax-Element-249">f(w)</script>,用更多的运行时间减少了储存的开销。

反向传播算法访问了每一条边一次,以避免了重复子表达式的指数爆炸

MLP中的BP

每一层求出所需要的子梯度,如果上一层已经出现了这个子梯度,下一层只需要直接乘以它就可以,通过把求导分解,可以并行地计算整个网络上的所有梯度。

深度学习以外的微分

BP保证了正向传播和反向传播的复杂度是同一个数量级,但是要进一步降低开销,完全简化计算图,却是NP完全问题,所以像Theano和Tensoflow这样的库,其实都是在基于已知的一些匹配模式去尝试简化的。

为了提高计算效率,一种BP的逆向思维方法出现了——前向模式累加。考虑以下矩阵乘法:

ABCD
<script type="math/tex; mode=display" id="MathJax-Element-112"> ABCD </script>
如果D是一个输出,一维向量,当然是从右边开始乘比较快,反之像TTS这样的需要有很大维度的输出,输入却很少维度的模型,就需要用前向求微分。

进一步地,要计算二阶微分Hessian矩阵基本上都是吃不消的,所以一般计算Hessian向量积取代之。

深度学习的进步

1985年,《并行式分布式处理》出版后,其中的认知学习的观点强调神经元之间的连接作为学习过程,被冠以“连接主义”的名称。
近年来深度学习的进步基本上受益于两个方面:
1. 较大的数据集降低了统计泛化对神经网络的挑战——降低了统计偏差,和样本方差
2. 更大的计算机和更好的软件基础
3. 少量算法上的改进,包括:
1. 选用交叉熵代替MSE
2. ReLU被证明能提高性能
3. 最近,前馈模型重新被捡起来了

深度学习的难点:

欠拟合——梯度消失:
因为导数都小于1,所以BP的时候,梯度逐步递减,越靠近输出收敛越快,但是前面的几乎不收敛
解决:ReLU,maxout,
BN:ZCA标准化使得服从正态分布,然后重参数化使得新的输出值有任意均值和方差,此均值和方差通过训练获得,避免sigmoid函数中0均值单位方差把sigmoid两边的摧毁
深度残差网络ResNet,直接把输入加干扰后给到后面,使得原来的权重层的输出变成一个跟原来的输入的残差


深度学习的正则化

多数情况下正则化会对估计进行正则化,针对大方差的情况,通过偏差的增加换取方差的减少,理想的正则化应该是两者间的平衡。

(当泛化能力不足的时候,通过查看训练中各个epoch方差的变化,或者训练时方差的变化,我们可以设置合理的正则化系数)

实践中,其实大多数的深度学习模型拟合的都不是真正的数据生成模型,所以基本上都要用稍微过度复杂的模型拟合,一般来说,最好的模型总是:用一个适度复杂的方枘,细分面够多的那种,拟合一个宇宙的圆凿。
跟显卡渲染多边形一样,需要一个适当正则化(模型复杂度不能随便生长,要向适当的地方:计算量低,求导方便等)的大型模型。

参数范数惩罚

通常,我们只对权重惩罚而不惩罚偏置,因为相对于“关联两个变量”的权重而言,拟合偏置的数据少得多。
而且,正则化偏置可能会造成严重的过拟合。

L2 <script type="math/tex" id="MathJax-Element-113">L^2</script>范数

一般地,我们让权重以圆形接近原点,虽然可以随意接近任意一点,但是在不清楚应该接近哪个点的时候,接近原点有意义(1.稀疏化;2.最少先验假设)
为了形象地理解L2范数带来的正则化效应,我们可以分析加入权重衰减后学习规则的变化,会在每步更新权重之前,先对权重进行缩放 1ϵα <script type="math/tex" id="MathJax-Element-114">1-\epsilon \alpha</script>倍,这是单个步骤的变化。

对于整个训练步骤,参数衰减的影响:

w <script type="math/tex" id="MathJax-Element-286">w^*</script>为未正则化的最优权重, H <script type="math/tex" id="MathJax-Element-287">H</script>为J在 w <script type="math/tex" id="MathJax-Element-288">w^*</script>处计算的Hessian矩阵,则当J取得最小时:

wJ^(w)=H(ww)=0
<script type="math/tex; mode=display" id="MathJax-Element-289"> \nabla _w \hat J(w)=H(w-w^*)=0 </script>
加入权重衰减后,假设最优点为 w1 <script type="math/tex" id="MathJax-Element-290">w1^*</script>:
αw1+H(w1w)=0
<script type="math/tex; mode=display" id="MathJax-Element-291"> \alpha w1^*+H(w1^*-w^*)=0 </script>
st.
<script type="math/tex; mode=display" id="MathJax-Element-292"> st. </script>
w1=(H+αI)1Hw
<script type="math/tex; mode=display" id="MathJax-Element-293"> w1^*=(H+\alpha I)^{-1}Hw^* </script>
let:H=QΛQT,st.
<script type="math/tex; mode=display" id="MathJax-Element-294"> let:H=Q\Lambda Q^T,st. </script>
w1=Q(Λ+αI)1ΛQTw
<script type="math/tex; mode=display" id="MathJax-Element-295"> w1^*=Q(\Lambda +\alpha I)^{-1}\Lambda Q^T w^* </script>

因此,当α接近0的时候, w1 <script type="math/tex" id="MathJax-Element-296">w1^*</script>接近 w <script type="math/tex" id="MathJax-Element-297">w^*</script>。
当α不那么小的时候,就会对H中的特征向量对应的 w <script type="math/tex" id="MathJax-Element-298">w^*</script>进行缩放,具体缩放倍数是 λiλi+α <script type="math/tex" id="MathJax-Element-299">\lambda_i \over \lambda_i + \alpha</script>。也就是说,在H的特征值比较大的方向,正则化的影响比较小,反之,则几乎把 w <script type="math/tex" id="MathJax-Element-300">w^*</script>缩小到0。
因为H是Hessian矩阵,所以特征值比较大的方向实际上就是梯度比较大的方向,也就是说,会保留梯度大的方向,而把其他梯度小的方向衰减到0,对特征有高斯先验假设
image

对于线性回归的情况

令正规方程的解从:

w=(XTX)1XTy
<script type="math/tex; mode=display" id="MathJax-Element-125"> w=(X^TX)^{-1}X^Ty </script>
变成:
w=(XTX+αI)1XTy
<script type="math/tex; mode=display" id="MathJax-Element-126"> w=(X^TX+\alpha I)^{-1}X^Ty </script>
因为 XTX <script type="math/tex" id="MathJax-Element-127">X^TX</script>是对角阵,其对角元素是每个特征的方差,全部一起加了α后,方差大的那些就没那么明显了,对应的权重就降低了

L1 <script type="math/tex" id="MathJax-Element-128">L^1</script>正则化

相对来说,它会使得解析解变成:

wi=sign(wi)max{|wi|αHi,i,0}
<script type="math/tex; mode=display" id="MathJax-Element-129"> w_i=sign({w_i}^*)max\{|{w_i}^*|-{\alpha \over H_{i,i}},0\} </script>
也就是说
|wi|αHi,i <script type="math/tex" id="MathJax-Element-130">|{w_i}^*|\leq{\alpha \over H_{i,i}}</script>时, wi=0 <script type="math/tex" id="MathJax-Element-131">w_i=0</script>
|wi|αHi,i <script type="math/tex" id="MathJax-Element-132">|{w_i}^*|{\alpha \over H_{i,i}}</script>时, wi=wiαHi,i <script type="math/tex" id="MathJax-Element-133">{w_i}^*=w_i-{\alpha \over H_{i,i}}</script>

L1 <script type="math/tex" id="MathJax-Element-134">L^1</script>正则化通过足够大的α将部分贡献小的特征的权重置零,,对特征有各项同性的Laplace分布先验假设

一般的范数惩罚方法

通过把范数惩罚看成广义Lagrange函数,令之小于某个常数k,进行KKT方法的最优化,可以构造广义Lagrange函数:

L(θ,α;X,y)=J(θ;X,y)+α(Ω(θ)k)
<script type="math/tex; mode=display" id="MathJax-Element-135"> L(\theta,\alpha;X,y)=J(\theta;X,y)+\alpha (\Omega(\theta)-k) </script>
固定 α <script type="math/tex" id="MathJax-Element-136">\alpha ^*</script>,使得变成只跟 θ <script type="math/tex" id="MathJax-Element-137">\theta</script>有关:
θ=argminL(θ,α)=argminJ(θ;X,y)+αΩ(θ)
<script type="math/tex; mode=display" id="MathJax-Element-138"> \theta ^*=argminL(\theta,\alpha ^*)=argminJ(\theta;X,y)+\alpha ^*\Omega(\theta) </script>
在这情况下,就是通过α来对约束区域进行扩大和收缩。

但是有的情况下,我们不是通过惩罚隐式地限制权重,而是通过直接进行限制,直接计算J(θ)的下降步,然后通过θ投影到满足 Ω(θ) <script type="math/tex" id="MathJax-Element-139">\Omega (\theta)</script> > k,在已经知道k的先验值的情况下,这样做有3个好处:
1. 不用花时间寻找最佳的α,寻找k比寻找α更简单
2. 惩罚可能使得目标非凸从而陷入局部最小,使得训练的网络出现输入和输出权重都很小的死亡单元
3. 防止大梯度带来大权重,大权重又带来大梯度的正反馈循环,显式约束只是增加了一个最大界,不约束最大界内的行为,防止权重无限制的增加,增加稳定性

Hinton建议约束神经网络参数矩阵每列的范数而不是整个矩阵的F-范数以防止每一列有很大的权重,实践中,经常通过上述重投影的显式约束方法实现。

正则化和欠约束问题

正则化的的条件:
矩阵 XTX <script type="math/tex" id="MathJax-Element-140">X^TX</script>非奇异(当例子较少,数据在一些方向上没有方差的时候就会变成奇异的)

正则化在欠约束问题上的作用:
对于相关矩阵不可逆的时候,问题没有闭式解。正则化还可以用来给没有闭式解的问题提供收敛保证,可以作用于梯度的斜率,防止因为基于SGD之类的优化算法持续增加w的大小。

数据集增强作为正则化

  • 数据集增强在分类任务中效果很好,原因是我们大概能知道真实的分布的样子,而对于不知道真实分布的情况,我们不知道增加的噪声是否与真实的分布完全独立。
  • 有一些我们知道有用但是很难实行的操作也是有用的
  • 神经网络对噪声不是很健壮,但是增强这种健壮性就可以用噪声,Dropout也可以理解成加了噪声
  • 对比两个算法的时候,应该确保这两个算法用了相同的增强方案。

噪声鲁棒性

  • 一般来说,某些时候小的,施加于权重的噪声相当于范数惩罚,比如对于MSE回归而言。
  • 但是一般而言,注入噪声特别是对隐含层施加噪声比范数更强大
  • 输出目标与噪声:输出目标一般地都不会完全正确的标签,所以对于有ε概率出错的标签,可以用标签平滑的技术,从1和0变成 1ϵ <script type="math/tex" id="MathJax-Element-141">1-\epsilon</script>和 ϵ(k1) <script type="math/tex" id="MathJax-Element-142">\epsilon \over (k-1)</script>,防止模型追求确切概率而永远不会收敛

early stopping

提前停止具有正则化效果,但是可能会消耗验证集数据,可以进行两种改进:
1. 再次初始化模型,然后用全部数据再次训练,但是不知道最好在哪里
2. 保留第一轮获得的参数,然后全部数据继续训练,直到训练误差低于提前终止时候的值,但是不一定会更好

为何具有正则化效果:
其实是因为提前终止在某个地方阻止了w前往训练集的最优w*,在线性MSE模型上,其具有L2正则化效果

提前终止能自动确定正则化的最佳步,而权重衰减需要多次改变α进行试验

参数绑定和参数共享

我们可以让某些网络间或者子网络的子部分,让他们参数相同。
(比较传统的做法是施加范数使其接近已知的最佳点w*,以L2范数为例, Ω(w(A),w(B))=||w(A)w(A)||22 <script type="math/tex" id="MathJax-Element-143">\Omega(w^{(A)},w^{(B)})=||w^{(A)}-w^{(A)}||_2^2</script>)

比如让检测猫咪的网络,当猫咪平移了1像素,对应权重(相应)应该相同

稀疏表达

通过惩罚激活的单元,使得模型正则化,其中包括:
- L1(惩罚项, Ω(w)=Σi|hi| <script type="math/tex" id="MathJax-Element-144">\Omega(w)=\Sigma _i |h_i|</script>)
- t先验惩罚
- KL散度惩罚
- OMP-k正交匹配跟踪

含有隐藏单元的本质上都能变得稀疏

Bagging

Dropout

实际使用方法:
- 利用小批量小步长的学习算法
- 获得一个mini-batch
- 随机生成并应用一个控制使用那些单元的0-1向量μ
- 隐藏层0.5,输入层被选中大概在0.8,但是实际上一般不加Dropout
- 对于0.5的Dropout,开始推断前把权重除以2

参数共享使得在可用的内存下表现指数数量的模型变得可能,每一个子网络获得的训练样本确实是有放回采样的一个子集。

估计dropout的性能

1. 权重推断规则

Bagging的性能可以使用各个子模型生成的 1kpi(y|x) <script type="math/tex" id="MathJax-Element-145">{1 \over k}p_i(y|x)</script>进行估计,而Dropout有指数级模型所以计算不方便解决在这个问题的办法,被证明可以用标准归一化后的几何分布描述集成学习的性能 Pensemble <script type="math/tex" id="MathJax-Element-146">P_{ensemble}</script>
归一化的几何分布又可以化为,直接训练,后做预测的时候给每一个权重除以dropout率,这样的模型产生的分布,这种称为权重推断规则。

2. 蒙特卡罗近似采样

也可以直接采样大量子网络进行几何平均,虽然很多时候蒙特卡罗采样比不上权重推断规则,但是有时候蒙特卡罗采样会更好(小样本的时候)

Dropout的优点:
- 比其他开销小的正则化方法更有效
- 可以跟其他结合
- 计算量小
- 几乎在所有可以随机梯度下降的网络上都能用

Dropout的缺点:
- 减少了模型容量,不得不增大模型规模
- 只有很少样本的时候,还不如无监督预学习

Dropout的要点:
- 对于线性模型,等同于L2,但是对于深度模型而言,Dropout和权重衰减是不等同的。
- 随机性不是成功的必要条件,仅仅是一种近似所有子模型的一种方法
- 而且有随机性也不一定能达到dropout效果,它更多来自于Bagging了所有充分训练的子模型
- 大部分原因来自于掩码噪声,相当于对输入内容进行了自适应的破坏(相当于随机破坏了一部分高层特征)
- 另一重要的原因是噪声是乘性的,能使得噪声能肯定地破坏一些特征
- Dropout实现了参数共享的Bagging
- Dropout使得单个单元必须表现良好
- BatchNorm会加入加性和乘性特征,有的时候就不用Dropout了

对抗训练

对抗训练就是给模型一个小的加性噪声,就可以影响模型的分类结果
对抗训练是因为深度模型有些部分过度线性了,而线性模型其实有一个分界阈值,在这个阈值附近会丧失局部平稳性,可以通过这个训练数据附近的局部恒定进行处理

对抗样本带来两个用途:
- 进一步通过解决对抗扰动降低错误率
- 进行半监督学习(根据无标签样本的预测标签,给邻域内打标签,驱动模型学习流型局部稳定的模型,并假设不同类的流型彼此分离)

基于流型距离的方法

我们都希望分类函数在流型表面的切线上保持不变,而在法线方向上快速改变,一种基于这个思路对K-means的改进就是把点对之间的距离以流型距离表示,而在神经网络上,正切传播则通过给分类函数额外增加正则化惩罚使得f在类别的切线方向导数较小。
这等同于在小邻域上做了数据增强,不需要额外的训练数据和成本,但是只能处理小的邻域,而且很难在ReLU这种非线性分类上使用(导数难以更改)。

这些切线方向经常是手工指定的,包括图像平移,旋转等,而一种自动学习这种流型切线的方法叫做流型正切分类器,因此,AE可以自动学习流型的切向量,

半监督学习

用无监督学习给样本进行聚类,然后用监督学习进行分类,通过把无监督学习作为加入先验的步骤,更好地控制纯生成模型跟监督模型之间的权衡

多任务学习

在能解释数据变化的因素中,如果能解释这两个关联的任务的底层因素是共通的,那么共用底层作为训练会有很好的效果和泛化能力。


优化方法

机器学习中的优化经常不是直接指向最优解,而是制定一个性能度量P,进而优化性能度量P,间接地优化目标函数
其优化算法也不一样,最优化一般是直接优化到导数很小的地方,但是机器学习中的的时候优化到导数还是很大的时候就停止了(early stopping)

训练集上的代价函数可以写为:

J(θ)=E(x,y)P^dataL(f(x;θ),y)
<script type="math/tex; mode=display" id="MathJax-Element-147"> J(\theta)=\mathbb{E}_{{(x,y)} \sim \hat P_{data}}L(f(x;\theta),y) </script>

经验风险和结构风险

大多数情况下,我们不知道总体分布的 P <script type="math/tex" id="MathJax-Element-148">P</script>,因此用训练集上的经验分布 Pdata <script type="math/tex" id="MathJax-Element-149">P_{data}</script>替代真实分布风险,求平均意义下的期望损失函数,称为经验风险。

E(x,y)P^dataL(f(x;θ),y)=1mΣL(f(x(i);θ),y(i))
<script type="math/tex; mode=display" id="MathJax-Element-150"> \mathbb{E}_{{(x,y)} \sim \hat P_{data}}L(f(x;\theta),y)={1 \over m}\Sigma L(f(x^{(i)};\theta ),y^{(i)}) </script>
最小化这种损失函数的过程叫经验风险最小化
经验风险最小化很容易导致过拟合,所以要加入正则项,就会变成“结构风险”
实际上很多损失不能求导,所以实际上很少直接使用经验风险最小化

代理损失函数

因为很多时候经验风险是不可解的,所以会采用代理损失函数,某些情况下,代理设置比原函数学到的更多。

例如,log-loss经常作为哦0-1损失函数的替代,而且还允许计算条件概率。在0-1损失已经下降到0之后,对应的log-loss还可以进一步下降拉开类别之间的距离,学习更多的信息。

批量优化算法

机器学习中使用的目标函数经常不需要全部样本一起计算,可以分解为训练样本上损失的求和。

使用小批量的原因:
1. 对估计精确度的回报是小于线性的
而且,在小批量的数据上计算估计值(比如mini-batch上的Loss),经常可以在计算量少得多的情况下,获得一个比较好的估计,只要知道了大概的估计值,就可以收敛得更快。

  1. 另一个小批量估计的原因是训练集的冗余,实际上大多数样本对梯度的贡献都会很相似,以至于全部都计算一次求平均跟用mini-batch求平均差不多。

确定合适的批量大小:
1. 在最大限度利用架构性能的情况下(用GPU时,batch-size应当为2的幂数,大小为32~256,大模型时可以用16)
2.考虑用尽所有内存
3. mini-batch可能引入了正则化效果,如果希望最大化这些效果的话,batchsize越小越好

要点:
1. 不同的算法对批量的影响不同,只用梯度的在100的batch-size上就能表现得很好,但是用Hessian的则要10000。
2. 基于无偏估计的原理,样本应该是彼此独立的,因此样本要打乱顺序后,从中抽取
3. 计算一个batch上的梯度的时候,也可以同时计算其他batch上更新
4. 只要没有重复样本的时候,随机梯度下降会沿着真实泛化误差的梯度下降,一旦重复遍历了样本,对真实泛化误差的估计就变成有偏的了

优化中的挑战

神经网络一般都会遇到非凸函数,即使是凸函数也并非没有问题
1. 病态
病态最突出的就是H的病态,体现在随机梯度下降会卡在某些点下不去,尽管梯度很大,比如在峡谷间一直左右震荡。
经常用梯度的范数来检查是否进入了病态情况
2. 局部极小
即使不是由于非凸的原因,模型的在很多情况下参数可以交换,这被称为模型不可辨认,不可辨认的模型会存在很多的局部极小点
一般认为,对于足够大的网络而言,大部分局部极小值的效果已经足够好
经常用梯度是否已经很小来确定是否进入了极小点
3. 高原,鞍点等平坦问题
对于高维数据来说,多数梯度等于0的点都出现在鞍点上,对于维度为n的数据,鞍点和局部极小点的比率随着n指数级增长
实际上,大多数随机梯度下降可以逃离鞍点,尽管未经优化的牛顿很容易跳进鞍点
比较容易出问题的反而高原,平坦的高代价函数经常跳不出去。
4. 悬崖和梯度爆炸
长期时间序列经常引入大量的参数乘法,从而带来悬崖,悬崖上用传统的SGD很容易出问题,因为会根据梯度跳过很大一步到未出现的区域中“被瀑布弹飞出去”
启发式梯度截断能解决此问题,其限制对参数进行极大的更新,在建议对参数进行很大更新的时候,选择更新到小的值上
梯度消失令我们不知道更新的正确方向,梯度爆炸使得学习不稳定
使用前馈网络即使是深度的前馈网络也可以避免梯度消失和爆炸问题
5. 长期依赖
因为太深的网络结构使得模型失去了学习先前信息的能力
RNN中经常有这个问题,因为其计算图经常很深【循环网络中的挑战Chapter10.7】
6. 梯度非精确
大多数优化算法的前提条件都是已经知道了精确的梯度或者H矩阵,但是实际上大多数目标函数都是难以处理的,所以梯度也是近似的。
可以用改进的优化算法或者比真实损失函数更精确的代理损失函数来解决。
7. 局部和全局的弱对应
看过了很多解决局部问题的方法,仍然解决不了整个全局问题。
总是获得局部最小,但是却发现不了或者很花时间(很长的路径)才能找到全局极小。
现在大多数方法获得全局优化的方式,都是寻求良好的初始点。
7. 优化存在性能限制
已经证明有一些问题是不可能,很难全局最优的,但是实际上我们也不用全局最优,我们只要找到一个泛化误差可接受的解就可以了

基本优化算法

SGD

根据数据生成分布抽取m个小批量独立同分布样本,通过计算其梯度均值获得梯度的无偏估计

关键是学习率,有必要随着时间推移降低学习率,因为小批量会引入噪声,当梯度很小的时候噪声会太大飞出最小点,所以用小的学习率可以防止低点的震荡
实践中经常会线性地衰减学习率,直到小于某一个阈值后不再变化

ϵk=(1α)ϵ0+αϵτ
<script type="math/tex; mode=display" id="MathJax-Element-151"> \epsilon_k = (1-\alpha)\epsilon_0+\alpha \epsilon_{\tau} </script>
其中,更新率为
α=kτ
<script type="math/tex; mode=display" id="MathJax-Element-152"> \alpha ={k \over \tau} </script>
τ <script type="math/tex" id="MathJax-Element-153">\tau</script>是迭代次数,一般设为反复遍历训练集几百次的次数
ϵτ <script type="math/tex" id="MathJax-Element-154">\epsilon_{\tau}</script>应当是 ϵ0 <script type="math/tex" id="MathJax-Element-155">\epsilon_0</script>的1%
ϵ0 <script type="math/tex" id="MathJax-Element-156">\epsilon_0</script>一个好的学习率在100次迭代后会有明显效果。
所以一般是用几个参数各自先跑100次迭代,然后选择一个比这几个学习率
中最好的那个稍微大的学习率

收敛率比较好,能用比较少的数据就能实现初始梯度快速更新,其收敛率是 O(1k) <script type="math/tex" id="MathJax-Element-157">O({1 \over {\sqrt k}})</script>,强凸的时候有最佳性能 O(1k) <script type="math/tex" id="MathJax-Element-158">O({1 \over k})</script>,SGD在初始的时候能快速更新,但是梯度变小的时候因为渐进分析的原因收敛率表现不佳。
批量梯度在后期效果更好,接近CR下界指出的 O(1k) <script type="math/tex" id="MathJax-Element-159">O({1 \over k})</script>,这也是机器学习算法的最好性能。
可以学习过程中逐渐增大batchsize来权衡两种算法

momentum

动量主要解决两个问题:
1. Hessian矩阵的病态条件
防止在峡谷两边震荡

  1. 随机梯度的方差
    随机梯度中的方差不稳定会带来梯度上的噪声,而动量基于过去梯度的信息会进行收敛

实践:

  • 实践中步长大小为 ϵ||g||1α <script type="math/tex" id="MathJax-Element-160">\epsilon ||g|| \over 1-\alpha</script>,其中α一般取0.5,0.9和0.99,分别表示其最大速度是SGD的两倍,十倍,一百倍。
  • α随着时间推移应增大
  • 调整α没有调整ε重要

Nesterov

动量的变种,在计算梯度的时候,加入了一个矫正因子
在凸批量梯度的时候,额外误差收敛率从O(1/k)改进到O(1/k^2),可是随机梯度上没有改进

参数初始化算法

  • 在多数算法中,一个好的初始化能影响很多问题,包括收敛速度和泛化误差
  • 但是实际上对此知之甚少,我们通常会让初始的权重满足某种性质,但是训练过程中不一定能保持,而且,我们也不能保证这种性质能一直为泛化提供好的效果
  • 唯一确定的就是“破坏对称性”,应该尽量给每个单元不一样的初始化参数,以使他们探索不一样的函数
  • 权重的分布似乎没有太大影响
  • 权重的大小有影响:
    • 大的能更强地破坏对称性,更大的输出能避免丢失信号
    • 太大的会导致权重爆炸,混沌(对小输入太敏感),使得激活函数饱和
  • 优化观点建议权重大以传播信息,正则化希望权重尽可能小,正则化倾向于使得高斯分布的权重趋于0,用以加入“单元间相互不交互”的先验
  • 现代模型中虽然很多非线性,但是线性模型的策略倒也经常表现得不错

实践

固定数值范围法:
  • 没有太多性能开销
  • 数值范围固定,但是一般来说数值范围也是个超参数,应该尝试在理论标准(Normal init/Xavier init)附近调整。
  • 如果固定标准差的话,层很大的时候每个权重会相当小
搜索数值范围法:
  • 计算性能允许的时候可以尝试,搜索范围,是/否采用稀疏初始化等
  • 手动设定权重的方法:
    • 观测激活值(输出)
    • 如果某一层的输出太小,那么就增加这一层的权重
    • 如果学习很慢,考虑观测对应的梯度,可能是梯度太小了
偏置的初始化:

一般初始化为0
- 对于分类问题,可以手动设置输出单元的偏置以匹配x上的边缘分布
- 对于ReLU,可以设置b=0.1防止初始化就过饱和
- 对于门单元,一般初始化为1(如LSTM遗忘门),以防所控制的单元没机会学习

精度的初始化:
  • 考虑将精度设置为1
  • 吻合训练集输出的边缘方差(即y的分布)

自适应优化算法

损失通常对参数空间中的某些方向特别敏感(可能是对应的维度的数值特别大导致梯度也很大),以至于需要每个维度自适应地调整。

AdaGrad

基本上就是对每个维度统计梯度的平方和r,更新规则:

rr+gg
<script type="math/tex; mode=display" id="MathJax-Element-302"> r \leftarrow r+gg </script>
Δθϵδ+rg
<script type="math/tex; mode=display" id="MathJax-Element-303"> \Delta \theta \leftarrow -{\epsilon \over \delta + \sqrt {r}}g </script>
- 损失越大偏导的参数下降得越快,使得下降方向的变化非常平缓
- 凸优化中性能很好,但是经验表示会令学习率减少得太快(因为一开始就积累了太大的平方和)

RMSProp

  • 改进AdaGrad,防止梯度太快变小,而采用指数衰减平均抛弃掉太久远的历史
  • 还可以结合Nesterov动量进一步改进
  • 最实用

Adam

  • RMSProp的改进,结合RMSProp和动量
  • 通常对超参数很鲁棒,尽管学习率经常不能使用默认的学习率

优化算法的选择

  • 虽然具有自适应学习率的算法会很鲁棒,一般不会差太多,但是也不一定会好太多
  • 一般取决于使用者的了解,以便调节超参数

二阶优化方法

二阶元祖——牛顿法

在H矩阵正定的时候,用 H1 <script type="math/tex" id="MathJax-Element-161">H^{-1}</script>重新调整梯度,能直接下降到极小值。
存在的问题:
- 非凸表面
一般非凸表面会出现H非正定,于是就需要进行正则化,在H的对角线上加α,但是太极端的时候,会使得αI太主导,使得更新率很小
- 计算开销
计算逆的复杂度达到 O(n3) <script type="math/tex" id="MathJax-Element-162">O(n^3)</script>

共轭梯度

只需要 P192 左边
有一种最速下降法,它先对一个维度先用牛顿下降到导数为0的点,然后再选择一个正交的方向继续下降,不断重复。
可是这样的方法再下降后一个步骤的时候有可能抵消上一个步骤的成果,共轭梯度法进行了改进,其对下一个方向的选择不是正交,而是“共轭”,它通过加回一部分(系数为β)原来方向矢量的梯度,确保梯度沿上一个方向的大小不变。

dt=ΔθJ(θ)+βtdt1
<script type="math/tex; mode=display" id="MathJax-Element-163"> d_t=\Delta_\theta J(\theta)+\beta_t d_{t-1} </script>
为了求解β,假设dt和dt-1分别是上一步和下一步的搜索方向,那么共轭的条件是:
dTtHdt1=0
<script type="math/tex; mode=display" id="MathJax-Element-164"> d_t^THd_{t-1}=0 </script>
计算H矩阵开销很大,所以有其他的计算方法,K维空间中,只需要至多k次线搜索就可以达到极小值

实践:

  • 非线性共轭梯度的效果其实挺好,在那之前做几步SGD来初始化甚至更好
  • 虽然属于批方法(一起更新),但是已经出现了小批量的版本

BFGFS/存储限制的BFGFS(L-BGFS)

原理是既然牛顿法计算 H1 <script type="math/tex" id="MathJax-Element-165">H^{-1}</script>开销很大,那么就计算矩阵M近似逆,并迭代低秩地(我猜是逐行)更新M以近似
获得M后下降方向 dt=Mtgt <script type="math/tex" id="MathJax-Element-166">d_t=M_t g_t</script> ,参数更新为 θt+1=θt+ϵdt <script type="math/tex" id="MathJax-Element-167">\theta_{t+1}=\theta_t+\epsilon^*d_t</script>,因此,BGFS也可以像共轭梯度一样进行线搜索,而且由于获得了近似矩阵M能更好地改进每一个线搜索,但是却必须储存逆矩阵M,需要O(n^2)的储存空间,开销较大。

L-BGFS

不是每一次都计算并储存所有的M,而是计算 Mt <script type="math/tex" id="MathJax-Element-168">M_{t}</script>的时候使用 Mt1 <script type="math/tex" id="MathJax-Element-169">M_{t-1}</script>,效果仍然不错

优化策略

有一些优化技术虽然不是算法,但是也可以跟算法协同工作

Batch Normalization

二阶优化方法避免了一阶优化方法“只能看到眼前梯度”的问题,但是也忽略了更高阶的参数之间的相互关系,实际上参数间,层之间相互之间有复杂的相互关系,远不止二阶,而我们想要的非线性关系也是那些超过二姐的关系。
很多情况下,由于一阶和二阶统计量太大掩盖了高阶关系,有必要进行消除。
BN提供了一种更优雅的初始化方法。

算法:
  • 训练时,给每一层输入的时候,经过一个能学习的归一化层
  • 归一化层对数据再加个预处理操作,把均值和方差重新缩放到零均值和单位方差的情况,记录这个均值和方差
  • 再经过一个重构操作:
    y(k)=γ(k)x^(k)+β(k)
    <script type="math/tex; mode=display" id="MathJax-Element-170"> y^(k)=\gamma ^{(k)}\hat x^{(k)}+\beta^{(k)} </script>
    其中γ和β这两个操作可以进行学习,会在原来BP算法的框架上进行学习,允许有特殊的一对值能还原原来的数据分布,每一个神经元xk都会有一对这样的参数γ、β,学习的时候,根据这个单元上的梯度,会在这个单元上更新用于最佳地重建这个分布所需要的β,与其说β是个均值,不如说是这个单元上的偏置(也可以说是这个batch的样本在这个单元上的均值,但是不直观)
  • 其实一般来说激活函数是
    y=g(Wx+b)
    <script type="math/tex; mode=display" id="MathJax-Element-171"> y=g(Wx+b) </script>
    BN后其实b也会被均值到0(重构的时候会学习到b),就变成
    y=g(BN(Wx))
    <script type="math/tex; mode=display" id="MathJax-Element-172"> y=g(BN(Wx)) </script>
    测试阶段用均值和方差进行还原输出
代价:
  • 可能会使得底层网络没有用(罕见)
好处:
  1. 你可以选择比较大的初始学习率,让你的训练速度飙涨。以前还需要慢慢调整学习率,甚至在网络训练到一半的时候,还需要想着学习率进一步调小的比例选择多少比较合适,现在我们可以采用初始很大的学习率,然后学习率的衰减速度也很大,因为这个算法收敛很快。当然这个算法即使你选择了较小的学习率,也比以前的收敛速度快,因为它具有快速训练收敛的特性;
  2. 你再也不用去理会过拟合中drop out、L2正则项参数的选择问题,采用BN算法后,你可以移除这两项了参数,或者可以选择更小的L2正则约束参数了,因为BN具有提高网络泛化能力的特性;
  3. 再也不需要使用使用局部响应归一化层了(局部响应归一化是Alexnet网络用到的方法,搞视觉的估计比较熟悉),因为BN本身就是一个归一化网络层;
  4. 可以把训练数据彻底打乱(防止每批训练的时候,某一个样本都经常被挑选到,文献说这个可以提高1%的精度,这句话我也是百思不得其解啊)。
为什么只有均值和方差:
  • 因为这个是一层线性网络可以影响的所有统计量——一阶和二阶
  • 当网络具有非线性变换能力的时候(非线性激活函数),只归一化了一阶和二阶统计量使得非线性性质得以保留
重点
  • 以前,偏置取决于下层参数间的复杂n阶关系,但是现在去除了这种影响很大的1,2阶关系,每一层只剩下非线性关系,然后让每个单元独立学习新的偏置β,从而让β很容易训练
  • 核心是,默认地去除了一阶二阶统计量只留下高阶特征,而且允许在梯度下降需要的时候,也就是根据梯度需要,恢复被去除的一阶二阶统计量,又进行了可以通过训练保留的特征
  • 要用非线性激活函数,不然没有意义
  • 非线性激活函数中输入的一二阶统计量更符合非高斯,所以进行归一化后,更能消除其中统计量偏离高斯分布,对参数的数值大小带来的显著影响(偏离高斯的一二阶统计量使得更高阶的特征变得很不显著,难以训练)
  • CNN中,经过这样训练后能去除特征映射的空间偏移,只保留非线性特征

坐标下降(coordinate descent)

如果目标函数可以分成几个部分,每个部分各为一个凸问题,并每个部分间相关关系很少,那么就可以固定其他其他的只优化其中一个问题,然后迭代处理其他的。

polyak平均

会对访问过的参数做平均,每一次下一次输出取决于过去所有梯度的平均

监督预训练

Bengio(2007),提出前向传播逐层训练神经网络的方法,一般情况下,预训练对于泛化和优化都是有帮助的

优化模型

增加线性

当代神经网络的一个特点就是线性,LSTM,ReLU,maxout都比sigmoid单元的神经网络更具有线性特征,随着人们对神经网络的了解,不再采用sigmoid单元来粗暴地引入非线性,而是通过引入更切合问题的模型设计来处理非线性问题。
并且,随着更大的模型的引入,更多的数据,需要更快的计算速度,于是引入线性特征,“精细的模型设计,更好的性能–更少的人工设计,更强大的非线性”这对平衡中,天平正逐渐偏移。

用半成品进行辅助

网络中间的梯度,或者用预训练的网络作为半成品,都可以进一步辅助

延拓法

基于对目标函数进行逐步平滑的想法,克服局部最优值,逐步优化初始点。
对于目标函数J(θ),构造一系列构造函数{J1(θ),…,Jn(θ)},依次变难,依次训练同一个深度学习网络,于是,先从解决简单的问题开始,每一个构造函数的最优解会变成下一次训练的一个比较好的起点。
这样的方法可以通过对网络里的参数随机赋值,并采样来近似,采样越少,函数空间平面上的目标函数曲面就会越平滑。
正如前述,局部最小值已经不是主要问题了,但是延拓法还是能用于进行消除平坦区域,减少梯度估计的方差,使得局部更容易计算。

延拓法的改进——课程学习

构造函数的时候,如果通过“先构造简单的概念(场景/动物-动物/植物/有毛的/无毛的)”取代随机采样,能更进一步加速训练
在NLP和CNN上很有效


CNN


RNN

如果只有一个RNN单元,在不断给他标量{x1,x2…xn}的时候,每一代神经元都会把一部分信息留给下一个神经元,下一个神经元根据前辈的信息和新的输入调整参数。
理论上,当使用足够好的系统,那么这样的网络可以学习任意复杂的问题。

长期依赖问题

但是随着信息的流逝,很久之前的信息留下的参数已经很不显著了,因此很难进行长期的记忆。

LSTM


深度学习常见网络

RBM:

BM:玻尔兹曼机,用V个可视节点和H个隐藏节点全连接,可以学习到复杂的规则
RBM:
限制性的,即可视节点之间没有连接,隐藏节点间也没有。
一般隐藏层节点的值只是0或者1表示是否激活,隐藏层值服从伯努利分布。
RBM的概率分布通过能量来定义,能量模型给变量集合定义一个向量,来描绘集合内部的依赖关系(有点像熵),然后让期望在偏好的组合上具有最小的熵(使用损失函数给出一个最小熵假设)
从而,对服从伯努利的RBM分布,有玻尔兹曼分布P264
对二层RBM,其边缘分布为只考察可视层的神经元集合(刚好负责softplus函数,由:In熵+伯努利得到),其条件分布就是给定一个输入,其隐含层的概率服从sigmoid(由独立性+伯努利)
计算的时候因为有指数复杂度,所以一般有对比散度优化

推荐系统的层次:

集群离线层:周期更新,数据预处理,数据量大【用于挖掘数据】
客户端实时层:操作实时,数据少,捕获操作【用于捕获数据】
服务器计算层:根据客户端实时和集群离线层捕获数据,由离线层提供建议,实时层提供限制

推荐的方法:

匹配算法:根据用户画像,采用TF-IDF调用最接近的进行推荐
协同过滤:用Jaccard相似度衡量用户相似度并建立矩阵,无法解决冷启动,数据稀疏,热门频繁
RBM+CF:解决了CF中只考察物品的一阶邻域,使得通过第三者相关的两个物品,无法从一个推送到另外一个。
对物品评价转化为one-hot,每个物品作为可视层,于是隐含层就会挖掘其中的关系,于是对于一个输入,用隐含层记录的先验概率分布进行前向推导,然后作为分类经过softmax,就可以获得对未知物品的预测评分
推荐算法常用误差的标准差来表示

RNN:

Elman:
隐含层的设计:

st=sigmoidUTxt+WTst1
<script type="math/tex; mode=display" id="MathJax-Element-306"> st=sigmoid(UT xt + WT st-1) </script> 即只是把输入和上一次的线性相加后做sigmoid(起了压缩的作用)输出
输出层的设计:随便,根据目标,比如是文本多分类,就用softmax就好

BPTT:

时间上,根据每一步的交叉熵做向后传导,因此t时间的损失函数是-ΣIn(ft),对这个求梯度然后更新参数就可以获得最终的参数的导数公式P298
于是就可以看到,在时间上损失的导数进行BP的过程

结构递归神经网络:

语言学上使用来做句子的语法提取,递归地分解句子为主动宾结构,生成句子的树

语言模型:语言模型会给任意一个句子的合理性打个分
n-gram模型:假设每一个单词只跟前面n-1个单词有关,然后根据这个生成一系列n元单词对,单词对中根据马尔科夫链计算后验概率即可
从计算的角度一般取n=3,对于经常没有出现的单词,采用平滑技术使得其频次至少为1【Laplace,古德图灵,….】
用LSTM构建语言模型的时候,只要把embedding后的n元词对和negative sampling后的负样本一起训练就可以
数据并行:可以吧大量的句子中每个单词embedding后变成矩阵,如果每个门的维度等于句子的数量,那么就可以把所有的句子一次放进去训练,因为每个句子会分别乘以对应的矩阵
Loss用交叉熵

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页