title: 深度学习理论问题小结

date: 2017/7/10 12:04:12

categories:

  • 深度学习
    tags:
  • deeplearning
  • 梯度下降法
  • 正则化
  • 激活函数
  • 神经网络

[TOC]

Michael Nielsen的《Neural Network and Deep Learning》
神经网络和深度学习

神经网络基础

sigmoid神经元

假设在网络的一些权值(或偏移)上做一个小的改变。我们期望的结果是,这些在权值上的小改变,将会为网络的输出结果带来相应的改变,且这种改变也必须是轻微的。我们在后面将会看到,满足这样的性质才能使学习变得可能。我们就可以改变权值和偏移来使得网络的表现越来越接近我们预期。
当使用σ函数时我们就得到了一个平滑的感知机。而且,σ函数的平滑属性才是其关键。sigmoid函数的代数形式保证了其在求微分的时候很方便。
根据我的经验,很多layer后面都会跟上一个激活函数,激活函数用于将该层之前的输入的线性组合进行非线性运算,如果没有激活函数那么整个神经网络就相当于一层了。另外一些激活函数有梯度消失的问题,当层数过深的时候在后向传播的时候梯度趋近于0,relu能够缓解这个问题,同时能够让一些神经元的梯度为0,来减少运算量。

不同激活函数(activation function)的神经网络的表达能力是否一致? - 回答作者: 纳米酱

我们也有一些存在回馈环路可能性的人工神经网络模型。这种模型被称为递归神经网络(recurrent neural networks)。该模型的关键在于,神经元在变为非激活态之前会在一段有限时间内均保持激活状态。这种激活状态可以激励其他的神经元,被激励的神经元在随后一段有限时间内也会保持激活状态。如此就会导致更多的神经元被激活,一段时间后我们将得到一个级联的神经元激活系统。

用简单的网络结构解决手写数字识别

损失函数

平方误差损失函数

为什么要介绍平方代价(quadratic cost)呢?毕竟我们最初所感兴趣的内容不是对图像正确地分类么?为什么不增大正确输出的得分,而是去最小化一个像平方代价类似的间接评估呢?这么做是因为在神经网络中,被正确分类的图像的数量所关于权重、偏置的函数并不是一个平滑的函数。大多数情况下,对权重和偏置做出的微小变动并不会影响被正确分类的图像的数量。这会导致我们很难去刻画如何去优化权重和偏置才能得到更好的结果。一个类似平方代价的平滑代价函数能够更好地指导我们如何去改变权重和偏置来达到更好的效果。这就是为何我们集中精力去最小化平方代价,只有通过这种方式我们才能让分类器更精确。

神经网络与深度学习中对为什么梯度下降法能够work做了详尽的解释

ΔC≈∇C⋅Δv. (9)
Δv=−η∇C, (10)
这里的η是个很小的正数(就是我们熟知的学习速率)。等式(9)告诉我们ΔC≈−η∇C⋅∇C=−η||∇C||2。由于||∇C||2≥0,这保证了ΔC≤0,例如,如果我们以等式(10)的方式去改变v,那么C将一直会降低,不会增加。(当然,要在(9)式的近似约束下)。这就是我们想要的特性!

为了使我们的梯度下降法能够正确地运行,我们需要选择足够小的学习速率η使得等式(9)能得到很好的近似。

反向传播

如果输入神经元是低激活量的,或者输出神经元已经饱和(高激活量或低激活量),那么权重就会学习得缓慢。

反向传播背后的四个基本等式

四个基本等式

反向传播的过程

enter description here

方向传播算法就是将错误量从输出层反向传播。

改进神经网络的方式

学习的速度(收敛速度)与很多因素有关,学习率、代价函数的形式、激活函数的形式都有关系。这是使用平方误差作为代价函数。

代价函数
假设y=0是我们的输出。
对权值偏导
我们能够从图像看出当神经元输出接近Rendered by QuickLaTeX.com时,曲线变得非常平坦,因此激活函数的导数会变得很小。

交叉熵代价函数与sigmoid激活函数

可以用不同的代价函数比如交叉熵(cross-entropy)代价函数来替代二次代价函数来让学习速度加快。

交叉熵代价函数

交叉熵函数为什么能作为代价函数
交叉熵有两个特性能够合理地解释为何它能作为代价函数。首先,它是非负的; 其次,如果对于所有的训练输入x,这个神经元的实际输出值都能很接近我们期待的输出的话,那么交叉熵将会非常接近0。

。而且交叉熵有另一个均方代价函数不具备的特征,它能够避免学习速率降低的情况。为了理解这个,我们需要计算一下交叉熵关于权重的偏导。因为在计算代价函数关于权值的偏导的时候,sigmoid函数的导数会与交叉熵中导数的一部分抵消掉。

误差关于权值的偏导-

当我们的输出层是线性神经元(linear neurons)的时候使用均方误差,假设我们有一个多层神经网络。假设最后一层的所有神经元都是线性神经元(linear neurons)意味着我们不用sigmoid作为激活函数。

激活函数 函数 导数 特点
sigmoid sigmoid sigmoid导数 有饱和状态
tanh tanh enter description here tanh保持非线性单调,延迟饱和 ,[-1,1]
relu y=max(0,x) 导数为常数 节省计算量,避免梯度丢失,网络稀疏
softplus y=log(1+e^x) softplus可以看作是ReLu的平滑

如何选择为自己的模型选择合适的激活函数

  1. 通常使用tanh激活函数要比sigmoid收敛速度更快;
  2. 在较深层的神经网络中,选用relu激活函数能使梯度更好地传播回去
  3. 当使用softmax作为最后一层的激活函数时,其前一层最好不要使用relu进行激活,而是使用tanh作为替代,否则最终的loss很可能变成Nan;
  4. 当选用高级激活函数时,建议的尝试顺序为ReLU->ELU->PReLU->MPELU,因为前两者没有超参数,而后两者需要自己调节参数使其更适应构建的网络结构。

softmax 层的输出是一个概率分布

softmax 的单调性,如果J=K,那么enter description here为正数, 如果J!=K,则为负数,这个表明了 z增大,则相应的a增大,其它a(输出概率)就见效

softmax 的非局部性,任何一个输出激活值a依赖于所有的输入值。

softmax函数的导数

参考softmax分类

Softmax 输出及其反向传播推导

softmax函数

知乎:多类分类下为什么用softmax而不是用其他归一化方法?

free-mind博客,softmax-loss

当 j = k时, enter description here,其中 y=1,所以可以写成enter description here

当j!=k, enter description here

这样的话当j = k 的时候, enter description here,这个形式非常简洁,而且与线性回归(采用最小均方误差目标函数)、两类分类(采用cross-entropy目标函数)时的形式一致。

其中,损失函数对激活函数的结果a的偏导是top_diff, 而对激活函数的输入z的偏导是bottom_diff。

损失函数是最大似然也是交叉熵

因为softmax的输出是一个概率分布,所以它的损失函数可以使用 最大似然估计

损失函数是log最大似然
bottom-diff的值
偏置的偏导
权值的偏导

过拟合与正则化

检测过拟合一个显而易见的方法就是跟踪网络训练过程中测试数据的准确率。如果测试数据的精度不再提高,就应该停止训练。当然,严格地说,这也不一定就是过拟合的迹象,也许需要同时检测到测试数据和训练数据的精度都不再提高时才行。

在每一步训练之后,计算 validation_data 的分类精度。一旦 validation_data 的分类精度达到饱和,就停止训练。这种策略叫做提前终止(early stopping)。validation_data视为帮助我们学习合适超参数的一种训练数据。由于validation_data和test_data是完全分离开的,所以这种找到优秀超参数的方法被称为分离法(hold out method)。

避免过拟合的手段:增大训练集、减小模型的规模、L2正则化、L1 规范化、弃权(Dropout)。正则化的一种手段叫weight-decay 又叫L2正则。L2 正则的思想是,在代价函数中加入一个额外的正则化项。下面是加入
L2正则
项之后的交叉熵代价函数。
weight-decay

直观来说,正则化的作用是让网络偏向学习更小的权值,而在其它的方面保持不变。选择较大的权值只有一种情况,那就是它们能显著地改进代价函数的第一部分。换句话说,正则化可以视作一种能够折中考虑小权值和最小化原来代价函数的方法。

而在反向传播过程中,这个正则项只影响权重项。

损失函数对权重和偏置的偏导
如果代价函数没有正则化,那么权重向量的长度倾向于增长,而其它的都不变。随着时间推移,权重向量将会变得非常大。这可能导致权重向量被限制得或多或少指向同一个方向,因为当长度过长时,梯度下降只能带来很小的变化。我相信这一现象令我们的学习算法难于恰当地探索权重空间,因而难以给代价函数找到一个好的极小值

L1正则

L1 规范化,这个方法是在未规范化的代价函数上加上一个权重绝对值的和:
L1正则
其中C0表示的是原来的损失函数,对上面的损失函数求导数得到:
L1求导

那么给予L1规范化的网络的更新规则为:
权值更新规则
可以发现正则项的导数是常数。在 L1 规范化中,权重通过一个常量向 0 进行缩小。在 L2规范化中,权重通过一个和 |w| 成比例的量进行缩小的。所以,当一个特定的权重绝对值 |w| 很大时,L1 规范化的权重缩小得远比 L2 规范化要小得多。相反,当一个特定的权重绝对值 |w| 很小时,L1 规范化的权重缩小得要比 L2 规范化大得多。最终的结果就是:L1 规范化倾向于聚集网络的权重在相对少量的高重要度连接上,而其他权重就会被驱使向 0 接近

弃权(Dropout)
dropout并不修改代价函数,而是修改网络本身。主要是用在全连接层。

因为神经元不能依赖其他神经元特定的存在,这个技术其实减少了复杂的互适应的神经元。所以,强制要学习那些在神经元的不同随机子集中更加健壮的特征。

当我们弃权掉不同的神经元集合时,有点像我们在训练不同的神经网络。所以,弃权过程就如同大量不同网络的效果的平均那样。不同的网络会以不同的方式过度拟合了,所以,弃权过的网络的效果会减轻过度拟合。

人为扩展训练数据data augmentation

可以提高网络性能

** batch normalization **
用在relu前面效果好,是LRN的升级版,把结果映射到0-1之间。

即在每次SGD时,通过mini-batch来对相应的activation做规范化操作,使得结果(输出信号各个维度)的均值为0,方差为1. 而最后的“scale and shift”操作则是为了让因训练所需而“刻意”加入的BN能够有可能还原最初的输入,从而保证整个network的capacity。

batch normalization

1)直接对输入信号的每个维度做规范化(“normalize each scalar feature independently”);
2)在每个mini-batch中计算得到mini-batch mean和variance来替代整体训练集的mean和variance.

BN的提出还是为了克服深度神经网络难以训练的弊病.说到底还是为了防止“梯度弥散”。关于梯度弥散,大家都知道一个简单的栗子:$ 0.9^30 = 0.04 $ ,在神经网络训练时遇到收敛速度很慢,或梯度爆炸等无法训练的状况时可以尝试BN来解决。另外,在一般使用情况下也可以加入BN来加快训练速度,提高模型精度。

知乎:深度学习中 Batch Normalization为什么效果好?

参数初始化

输出神经元在错误的值上饱和导致学习的下降。但是隐含层的饱和没法解决,需要用其它的初始化方法。
假设我们有一个有enter description here个输入权重的神经元。我们会使用均值为 0 标准差为 enter description here 的高斯随机分布初始化这些权重。也就是说,我们会向下挤压高斯分布,让我们的神经元更不可能饱和。我们会继续使用均值为0 标准差为 1 的高斯分布来对偏置进行初始化。

resnet如何解决了梯度消失问题

梯度消失的问题出现的本质原因是梯度连乘问题

而residual 结构出现后,求梯度就成

enter description here

XLXl=Xl+F(Xl,Wl,bl)Xl=1+F(XL,WL,bL)XL\frac{\partial X_L}{\partial X_{l}} = \frac{\partial X_l + F(X_l,W_l,b_l)}{\partial X_l} = 1 + \frac{\partial F(X_L,W_L,b_L)}{\partial X_L}

reference

Deep Residual Network 与 梯度消失

Neural Networks and Deep Learning

解析深度学习中的激活函数

参考:《神经网络与深度学习》连载——哈工大