深度学习——整理

来源:互联网 发布:怪物猎人物语 淘宝 编辑:程序博客网 时间:2024/06/04 23:36

1、什么是随机梯度下降?

梯度下降有三种:stochastic  gradient descent(SGD)、普通的GD以及min-batch GD。

其中caffe里最常用的就是min-batch GD,即每次从训练样本中选取min-batch个样本进行迭代,而普通的GD则是对所有的训练样本计算梯度,而SGD是对训练样本中的某一个样本计算梯度,更新权值。

其实这三种梯度下降的本质是一样的,都是使得每一次的迭代朝着最陡的方向前进,区别在于GD找到的方向是当前点,对于所有的样本点所产生的Cost最陡的方向,而SGD所找到的方向是当前点对于这一次所选取的样本所产生的Cost最陡的方向,因此GD是朝着全局最陡的方向走,而SGD会由于选取的样本不同每次移动都会显得摇摆。

还可以看出来,GD是朝着全局最优的方向前进,而SGD则容易陷入局部最优。

SGD中的S有一种解释是:训练样本时,对样本集打乱顺序,接着一个接一个的进行训练,当所有样本训练完毕之后再一次打乱所有样本顺序,继续训练。

根据:《deeplearning》这本书的解释:随机梯度下降的核心是,梯度是期望。期望可以使用小规模的样本近似估计。具体而言就是在算法的每一步,从训练集中均匀抽取出一小批量(minibatch)样本,小批量的数目通常是一个相对较小的数,从一到几百,重要的是,当训练集大小M增长时,小批量数目m是固定的。

2、监督学习、无监督学习、迁移学习、半监督学习、弱监督学习、非监督学习:

监督学习常见的:分类与回归。

无监督学习常见的:主成分分析和k-均值聚类。

半监督学习常见的:半监督分类:是在无类标签的样例的帮助下训练有类标签的样本,获得比只用有类标签的样本训练得到的分类器性能更优的分类器,弥补有类标签的样本不足的缺陷。

                       半监督回归:在无输出的输入的帮助下训练有输出的输入,获得比只用有输出的输入训练得到的回归器性能更好的回归器。

                      半监督聚类:在有类标签的样本的信息帮助下获得比只用无类标签的样例得到的结果更好的簇,提高聚类方法的精度;

迁移学习:个人感觉是一种思想吧,并不是一种特定的算法或者模型,目的是将已学习到的知识应用到其他领域,提高在目标领域上的性能,比如说一个通用的语音模型迁移到某个人的语音识别,一个ImageNet上的图片分类问题迁移到医疗疾病识别上。举个例子,假设今天老板给你一个新的数据集,让你做一下图片分类,这个数据集是关于Flowers的。问题是,数据集中flower的类别很少,数据集中的数据也不多,你发现从零训练开始训练CNN的效果很差,很容易过拟合。怎么办呢,于是你想到了使用Transfer Learning,用别人已经训练好的Imagenet的模型来做。
做的方法有很多:把Alexnet里卷积层最后一层输出的特征拿出来,然后直接用SVM分类。这是Transfer Learning,因为你用到了Alexnet中已经学到了的“知识”。把Vggnet卷积层最后的输出拿出来,用贝叶斯分类器分类。思想基本同上。

甚至你可以把Alexnet、Vggnet的输出拿出来进行组合,自己设计一个分类器分类。这个过程中你不仅用了Alexnet的“知识”,也用了Vggnet的“知识”。

最后,你也可以直接使用fine-tune这种方法,在Alexnet的基础上,重新加上全连接层,再去训练网络。

综上,Transfer Learning关心的问题是:什么是“知识”以及如何更好地运用之前得到的“知识”。这可以有很多方法和手段。而fine-tune只是其中的一种手段。

弱监督学习:文章给的定义是: 数据集的标签是不可靠的,如(x,y),y对于x的标记是不可靠的。
这里的不可靠可以是标记不正确,多种标记,标记不充分,局部标记等。
在实际应用中的学习问题往往以混合形式出现,如多标记多示例、半监督多标记、弱标记多标记等。针对监督信息不完整或不明确对象的学习问题统称为弱监督学习。

网传:半监督是弱监督的一种,体现在在少量标注样本的条件下进行学习。

3、CNN为什么能使用在NLP?

CNN的一大特性是用局部连接代替了全连接,适用于图像是因为图像的特征是局部强相关的,而文本也有这样的特性。CNN提取的是词的组合特征,相当于由网络自己实现n-gram。在CNN之前,RNN被广泛应用于NLP领域,用于对P(w1,w2,...,wn)=P(w1)P(w2|w1)...P(wn|w1w2...wn-1)建模,比CNN更容易理解,即考虑在前面的词后面接后面的词的条件概率。但这样的模型很依赖登入词,对于未登入效果很不好。而CNN就很好的解决了这个问题,因为提取的是组合特征,并不太受未登入词的影响,因此CNN被广泛应用于NLP领域。
https://www.zhihu.com/question/38544669

4、CNN用在cv、NLP、speech,利用的是他们的相似性,那么他们的相似性在哪里?

相似性在于,都存在局部和整体的关系,由低层次的特征经过组合,组成高层次的特征,并且得到不同特征之间的空间相关性。如下图:低层次的直线/曲线等特征,组合成为不同的形状,最后得到汽车的表示:


5、CNN抓住此共性的手段:局部连接/权值共享/池化操作/多层次结构:

局部连接使网络可以提取数据的局部特征;权值共享大大降低了网络的训练难度,一个Filter只提取一个特征,在整个图片(或者语音/文本) 中进行卷积;池化操作与多层次结构一起,实现了数据的降维,将低层次的局部特征组合成为较高层次的特征,从而对整个图片进行表示。如下图:


上图中,如果每一个点的处理使用相同的Filter,则为全卷积,如果使用不同的Filter,则为Local-Conv。

6、为什么很多做人脸的Paper会最后加入一个Local Connected Conv?

以FaceBook DeepFace 为例:


DeepFace 先进行了两次全卷积+一次池化,提取了低层次的边缘/纹理等特征。
后接了3个Local-Conv层,这里是用Local-Conv的原因是,人脸在不同的区域存在不同的特征(眼睛/鼻子/嘴的分布位置相对固定),当不存在全局的局部特征分布时,Local-Conv更适合特征的提取。

//2017/7/21

1、什麽样的资料集不适合用深度学习?

数据集太小,数据样本不足时,深度学习相对其它机器学习算法,没有明显优势。
数据集没有局部相关特性,目前深度学习表现比较好的领域主要是图像/语音/自然语言处理等领域,这些领域的一个共性是局部相关性。图像中像素组成物体,语音信号中音位组合成单词,文本数据中单词组合成句子,这些特征元素的组合一旦被打乱,表示的含义同时也被改变。对于没有这样的局部相关性的数据集,不适于使用深度学习算法进行处理。举个例子:预测一个人的健康状况,相关的参数会有年龄、职业、收入、家庭状况等各种元素,将这些元素打乱,并不会影响相关的结果。

2、简单理解正则项减轻过拟合:

常用的防治过拟合的方法是在模型的损失函数中,需要对模型的参数进行“惩罚”,这样的话这些参数就不会太大,而越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象。因此在添加权值惩罚项后,应用梯度下降算法迭代优化计算时,如果参数theta比较大,则此时的正则项数值也比较大,那么在下一次更新参数时,参数削减的也比较大。可以使拟合结果看起来更平滑,不至于过拟合。

3、dropout简说:

Dropout是hintion最近2年提出的;为了防止模型过拟合,Dropout可以作为一种trikc供选择。在hinton的论文摘要中指出,在每个训练批次中,通过忽略一半的特征检测器(让一半的隐层节点值为0),可以明显地减少过拟合现象。这种方式可以减少特征检测器间的相互作用,检测器相互作用是指某些检测器依赖其他检测器才能发挥作用。

Dropout可以看做是一种模型平均,所谓模型平均,顾名思义,就是把来自不同模型的估计或者预测通过一定的权重平均起来,在一些文献中也称为模型组合,它一般包括组合估计和组合预测。
  Dropout中哪里体现了“不同模型”;这个奥秘就是我们随机选择忽略隐层节点,在每个批次的训练过程中,由于每次随机忽略的隐层节点都不同,这样就使每次训练的网络都是不一样的,每次训练都可以单做一个“新”的模型;此外,隐含节点都是以一定概率随机出现,因此不能保证每2个隐含节点每次都同时出现,这样权值的更新不再依赖于有固定关系隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况。
  这样dropout过程就是一个非常有效的神经网络模型平均方法,通过训练大量的不同的网络,来平均预测概率。不同的模型在不同的训练集上训练(每个批次的训练数据都是随机选择),最后在每个模型用相同的权重来“融合”,介个有点类似boosting算法。

//2017/7/24

1、何为共线性, 跟过拟合有啥关联?

共线性:多变量线性回归中,变量之间由于存在高度相关关系而使回归估计不准确。
共线性会造成冗余,导致过拟合。
解决方法:排除变量的相关性/加入权重正则。

2、梯度消失问题

可以看到tanh和sigmoid函数在两端导数均为0。它们逐渐成为一条直线,当这个现象发生时,我们就说相应的神经元已经饱和了。它们的梯度为0,驱动前一层的其它梯度也趋向于0。因此,矩阵中有小值,并且经过矩阵相乘(t - k次),梯度值快速的以指数形式收缩,最终在几个时刻之后完全消失。较远的时刻贡献的梯度变为0,这些时刻的状态不会对你的学习有所贡献:你最终以无法学习到长期依赖而结束。梯度消失不仅仅出现在循环神经网络中。它们也出现深度前馈神经网络中。它仅仅是循环神经网络趋向于很深(在我们这个例子中,深度与句子长度一样),这将会导致很多问题。
依赖于我们的激活函数和网络参数,如果雅克比矩阵的值非常大,我们没有出现梯度消失,但是却可能出现梯度爆炸。这就是梯度爆炸问题。梯度消失问题比梯度爆炸问题受到更多的关注,主要有两个原因:1)梯度爆炸很明显,你的梯度将会变成Nan(不是一个数字),你的程序将会挂掉;2)在预定义阈值处将梯度截断(具体参考这篇 On the difficulty of training recurrent neural networks)是一种简单有效的方法去解决梯度爆炸问题。梯度消失问题更加复杂是因为它不明显,如论是当它们发生或者如何处理它们时。
幸运的是,目前已经有了一些缓解梯度消失问题的方法。对矩阵 W 合理的初始化可以减少梯度消失的影响。也可以加入正则化项。一个更好的方案是使用 ReLU而不是tanh或者sigmoid激活函数。ReLU函数的导数是个常量,要么是0,要么是1,所以它不太可能出现梯度消失。更加流行的方法是使用长短时记忆(LSTM)或者门控循环单元(GRU)架构。LSTM是在 1997年提出,在NLP领域可能是目前最为流行的模型。GRU是在2014年提出,是LSTM的简化版。这些循环神经网络的设计都是为了处理梯度消失和有效学习长期依赖。我们将会在后面的博文中介绍。

4、几种常见的激活函数:

a)Sigmoid 非线性激活函数的形式是σ(x)=1/(1+e−x),其图形如上图左所示。之前我们说过,sigmoid函数输入一个实值的数,然后将其压缩到0~1的范围内。特别地,大的负数被映射成0,大的正数被映射成1。sigmoid function在历史上流行过一段时间因为它能够很好的表达“激活”的意思,未激活就是0,完全饱和的激活则是1。而现在sigmoid已经不怎么常用了,主要是因为它有两个缺点:

Sigmoids saturate and kill gradients. Sigmoid容易饱和,并且当输入非常大或者非常小的时候,神经元的梯度就接近于0了,从图中可以看出梯度的趋势。这就使得我们在反向传播算法中反向传播接近于0的梯度,导致最终权重基本没什么更新,我们就无法递归地学习到输入数据了。另外,你需要尤其注意参数的初始值来尽量避免saturation的情况。如果你的初始值很大的话,大部分神经元可能都会处在saturation的状态而把gradient kill掉,这会导致网络变的很难学习。
Sigmoid outputs are not zero-centered. Sigmoid 的输出不是0均值的,这是我们不希望的,因为这会导致后层的神经元的输入是非0均值的信号,这会对梯度产生影响:假设后层神经元的输入都为正(e.g. x>0 elementwise in f=wTx+b),那么对w求局部梯度则都为正,这样在反向传播的过程中w要么都往正方向更新,要么都往负方向更新,导致有一种捆绑的效果,使得收敛缓慢。 
当然了,如果你是按batch去训练,那么每个batch可能得到不同的符号(正或负),那么相加一下这个问题还是可以缓解。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。

b)Tanh(双曲正切)和Sigmoid是有异曲同工之妙的,它的图形如上图右所示,不同的是它把实值得输入压缩到-1~1的范围,因此它基本是0均值的,也就解决了上述Sigmoid缺点中的第二个,所以实际中tanh会比sigmoid更常用。但是它还是存在梯度饱和的问题。Tanh是sigmoid的变形:tanh(z)=(ez-e-z)/(ez+e-z)。

c)ReLU. 近年来,ReLU 变的越来越受欢迎。它的数学表达式是: f(x)=max(0,x)。很显然,从上图左可以看出,输入信号 <0时,输出为0,>0时,输出等于输入。ReLU的优缺点如下:

优点1:Krizhevsky et al. 发现使用 ReLU 得到的SGD的收敛速度会比 sigmoid/tanh 快很多(如上图右)。有人说这是因为它是linear,而且梯度不会饱和
优点2:相比于 sigmoid/tanh需要计算指数等,计算复杂度高,ReLU 只需要一个阈值就可以得到激活值。
缺点1: ReLU在训练的时候很”脆弱”,一不小心有可能导致神经元”坏死”。举个例子:由于ReLU在x<0时梯度为0,这样就导致负的梯度在这个ReLU被置零,而且这个神经元有可能再也不会被任何数据激活。如果这个情况发生了,那么这个神经元之后的梯度就永远是0了,也就是ReLU神经元坏死了,不再对任何数据有所响应。实际操作中,如果你的learning rate 很大,那么很有可能你网络中的40%的神经元都坏死了。 当然,如果你设置了一个合适的较小的learning rate,这个问题发生的情况其实也不会太频繁。

d)Leaky ReLU. Leaky ReLUs 就是用来解决ReLU坏死的问题的。和ReLU不同,当x<0时,它的值不再是0,而是一个较小斜率(如0.01等)的函数。也就是说f(x)=1(x<0)(ax)+1(x>=0)(x),其中a是一个很小的常数。这样,既修正了数据分布,又保留了一些负轴的值,使得负轴信息不会全部丢失。关于Leaky ReLU 的效果,众说纷纭,没有清晰的定论。有些人做了实验发现 Leaky ReLU 表现的很好;有些实验则证明并不是这样。 
e) PReLU. 对于 Leaky ReLU 中的a,通常都是通过先验知识人工赋值的。然而可以观察到,损失函数对a的导数我们是可以求得的,可不可以将它作为一个参数进行训练呢? Kaiming He 2015的论文《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》指出,不仅可以训练,而且效果更好。原文说使用了Parametric ReLU后,最终效果比不用提高了1.03%. 

5、深度学习调参有哪些技巧?

1)训练数据预处理:深度学习相对于浅层学习,对数据特征更加不敏感,但是也应做好预处理工作:尽可能获得更多的数据(百万级以上),移除不良数据(噪音、假数据或空值等),做必要的数据增强、减均值等。

2)选择合适的激励函数:合适的激励函数为模型引入必要的非线性因素。sigmoid函数由于其可微分的性质是传统神经网络的最佳选择,但在深层网络中会引入梯度消失和非零点中心问题。tanh函数可以避免非零点中心问题,此外还可以尝试relu和prelu等激励函数。

3)确定隐层单元和数量:隐层单元数量决定了模型是否欠拟合或过拟合,两害相权取其轻,尽量选择更多的隐层单元,因为可以通过正则化的方法避免过拟合。于此类似的,尽可能的添加隐层数量,直到测试误差不再改变为止。

4)权重初始化:权重初始化常采用随机生成方法以避免网络单元的对称性,但仍过于太粗糙,根据目前最新的实验结果,权重的均匀分布初始化是一个最优的选择,同时均匀分布的函数范围由单元的连接数确定,即越多连接权重相对越小。

5)确定学习率:学习率是在收敛速度和是否收敛之间的权衡参数,选择0.01或者伴随迭代逐步减小都是合理选择,最新的方法开始研究学习速率的自动调整变化,例如基于目标函数曲率的动量或自适应调参等。

6)超参数调优:网格搜索是传统机器学习方法中的重要超参数优化手段,然而深度神经网络参数的大幅增多将使得该过程呈指数爆炸而不可行。可行的解决办法是通过随机采样或者添加先验知识来降低搜索空间范围。

7)选择优化算法:传统的随机梯度下降算法虽然适用很广,但并不高效,最近出现很多灵活的优化算法,例如adagrad、rmsprop等,可在迭代优化的过程中自适应的调节学习速率等超参数,效果更佳。

8)参数设置技巧:无论是多核cpu还是gpu加速,内存管理仍然以字节为基本单元做硬件优化,因此将参数设定为2的指数倍,如64,128,512,1024等,将有效提高矩阵分片、张量计算等操作的硬件处理效率。

9)正则优化:除了在神经网络单元上添加传统的L1/L2正则项外,dropout更经常在深度神经网络应用来避免模型的过拟合,初始默认的0.5的丢弃率是保守的选择,如果模型不是很复杂,设置为0.2就可以。

10)其他方法:除了上述训练调优的方法外,还有其他常用方法,包括:使用mini-batch learning方法、迁移训练学习、打乱训练集顺序、对比训练误差和测试误差调节迭代次数,日志可视化观察等。

11)filter的数量是2^n。

12)第一层的filter,数量不要太少,不然学不出来(底层特征很重要)

原创粉丝点击