机器学习知识整理

For 面试

Posted by Jiayue Cai on September 3, 2018

Last updated on 2019-11-8…

相关资源整理

基础:线性代数概率统计优化 part1优化 part2信息论及其他

学习:ML整理1ML整理2ML算法ML面试

笔记:斯坦福ML笔记吴恩达ML吴恩达DL

代码:李航MLDL

判别式与生成式

分类与回归

参考链接12种回归算法

回归与分类的根本区别在于输出空间是否为一个度量空间。

  • 对于回归问题,其输出空间B是一个度量空间,即所谓“定量”。也就是说,回归问题的输出空间定义了一个度量去衡量输出值与真实值之间的“误差大小”。
    • 例如:预测一瓶700毫升的可乐的价格(真实价格为5元)为6元时,误差为1;预测其为7元时,误差为2。这两个预测结果是不一样的,是有度量定义来衡量这种“不一样”的。(于是有了均方误差这类误差函数)。
  • 对于分类问题,其输出空间B不是度量空间,即所谓“定性”。也就是说,在分类问题中,只有分类“正确”与“错误”之分,至于错误时是将Class 5分到Class 6,还是Class 7,并没有区别,都是在error counter上+1。

1、Logistic Regression 和 Linear Regression:

Linear Regression: 输出一个标量 wx+b,这个值是连续值,所以可以用来处理回归问题(损失函数为均方误差)

Logistic Regression:把上面的 wx+b 通过 sigmoid 函数映射到(0,1)上,并划分一个阈值,大于阈值的分为一类,小于等于分为另一类,可以用来处理二分类问题(损失函数为交叉熵)

  • 分类阈值需要根据样本分布来决定(假设统计样本是均匀分布的,所以设阈值为0.5)
  • 更进一步:对于N分类问题,则是先得到N组w值不同的 wx+b,然后归一化,比如用 softmax 函数,最后变成N个类上的概率,可以处理多分类问题

2、Support Vector Regression 和 Support Vector Machine:

SVR:输出 wx+b,即某个样本点到分类面的距离,是连续值,所以是回归模型

SVM:把这个距离用 sign(·) 函数作用,距离为正(在超平面一侧)的样本点是一类,为负的是另一类,所以是分类模型

3、Naive Bayes:

用于分类:y是离散的类别,所以得到离散的 p(y|x),给定 x ,输出每个类上的概率

用于回归:对上面离散的 p(y|x)求期望 ΣyP(y|x),就得到连续值。但因为此时y本身是连续的值,所以最地道的做法是,得到连续的概率密度函数p(y|x),然后再对y求期望。

4、前馈神经网络(如 CNN 系列):

用于回归:最后一层有m个神经元,每个神经元输出一个标量,m个神经元的输出可以看做向量 v,现全部连到一个神经元上,则这个神经元输出 wv+b,是一个连续值,可以处理回归问题,跟上面 Linear Regression 思想一样

用于N分类:现在这m个神经元最后连接到 N 个神经元,就有 N 组w值不同的 wv+b,同理可以归一化(比如用 softmax )变成 N个类上的概率(补充一下,如果不用 softmax,而是每个 wx+b 用一个 sigmoid,就变成多标签问题,跟多分类的区别在于,样本可以被打上多个标签)

5、循环神经网络(如 RNN 系列):

用于回归和分类:跟 CNN 类似,输出层的值 y = wv+b,可做分类可做回归,只不过区别在于,RNN 的输出跟时间有关,即输出的是 {y(t), y(t+1),…}序列

上面的例子其实都是从 prediction 的角度举例的,如果从 training 角度来看,分类模型和回归模型的目标函数不同,分类常见的是 log loss、hinge loss,而回归是 square loss

特征方面

正负标签不平衡

个人处理的经验:

  • 负样本欠采样,最简单最常用
  • 正样本过采样,但是一般的过采样具有盲目性:基于邻域粗糙集的采样方法、半监督结合过采样
  • 分类器和决策规则根据目标进行设置:按错误的代价给予不同的权重(在目标函数上体现,自定义目标函数)

这篇有更透彻的理解

已有的不平衡学习方法概览:

  • 从多数类别中删除样本的方法(欠采样,如RUS、NearMissENNTomeklink等)
  • 为少数类别生成新样本的方法(过采样,如SMOTEADASYNBorderline-SMOTE等)
  • 结合上述两种方案的混合类方法(过采样+欠采样去噪,如SMOTE+ENN等)

极端类别不平衡数据下的分类问题研究综述

特征共线性

原特征的变换可能会存在共线性,处理的经验:

  • 模型训练前:利用模型对特征排序,做topK筛选
  • 模型训练时:随机选择特征和参数,来减弱特征共线性带来的影响。

非线性转换

为了让线性模型能够学习到原始特征与拟合目标之间的非线性关系,通常需要对原始特征做一些非线性转换。常用的转换方法包括:连续特征离散化、特征之间的交叉等。

Embedding

相对于高维稀疏的one-hot编码表示,embedding-based的方法,学习一个低维稠密实数向量(low-dimensional dense embedding)。

类似于hash方法,embedding方法把位数较多的稀疏数据压缩到位数较少的空间,不可避免会有冲突;

然而,embedding学到的是类似主题的语义表示,对于item的“冲突”是希望发生的,这有点像软聚类,这样才能解决稀疏性的问题。

评价指标

很多机器学习的模型对分类问题的预测结果都是概率,如果要计算accuracy,需要先把概率转化成类别,这就需要手动设置一个阈值,如果对一个样本的预测概率高于这个预测,就把这个样本放进一个类别里面,低于这个阈值,放进另一个类别里面。所以这个阈值很大程度上影响了accuracy的计算。

  • 使用AUC或者logloss可以避免把预测概率转换成类别。
  • AUC对样本类别是否均衡并不敏感,这也是不均衡样本通常用AUC评价分类器性能的一个原因。
  • 可以直接优化AUC来训练分类器(rankboost算法

AUC:Area under curve,曲线下面区域的面积。这个曲线叫ROC曲线。 从所有1样本中随机选取一个样本,从所有0样本中随机选取一个样本,然后根据你的分类器对两个随机样本进行预测,把1样本预测为1的概率为p1,把0样本预测为1的概率为p0,p1>p0的概率就等于AUC。

from sklearn.metrics import roc_auc_score
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
roc_auc_score(y_true, y_scores)

优化方法(学习参数)

梯度下降

GD 梯度下降:梯度下降就是我上面的推导,在梯度下降中,对于θ的更新,需要计算所有的样本然后求平均。其计算得到的是一个标准梯度。因而理论上来说一次更新的幅度是比较大的。(梯度下降算法在每次更新回归系数时都需要遍历整个数据集,如果有十亿个样本和成千上万的特征,那么该方法的计算复杂度就太高了)

SGD 随机梯度下降:”随机“即每次用样本中的一个例子来近似所有的样本,用这一个例子来计算梯度并用这个梯度来更新θ。因为每次只用了一个样本因而容易陷入到局部最优解中。

batch SGD 批量随机梯度下降:用一些小样本来近似全部的,其本质就是既然1个样本的近似不一定准,那就用更大的30个或50个样本来近似。将样本分成m个mini-batch,每个mini-batch包含n个样本;在每个mini-batch里计算每个样本的梯度,然后在这个mini-batch里求和取平均作为最终的梯度来更新参数;然后再用下一个mini-batch来计算梯度,如此循环下去直到m个mini-batch操作完就称为一个epoch结束。

牛顿法

牛顿法:在现有极小点估计值的附近对f(x)做二阶泰勒展开,进而找到极小点的下一个估计值。由于迭代公式是定步长迭代,对于非二次函数,不能保证其函数值稳定地下降。

阻尼拟牛顿法:每次迭代方向与牛顿法相同,但每次迭代需沿此方向作一维搜索,以寻求最优地步长因子。

拟牛顿法DFPBFGSL-BFGS):用近似地正定对称矩阵代替Hessian矩阵(有时海森矩阵无法保持正定,而且原牛顿法二阶偏导计算复杂度大)

其他

Momentum:模拟物理里动量的概念,积累之前地动量来替代梯度。

Adagrad:模拟物理里阻力的概念,对学习率作了一个约束项。

Adam:上面两者结合,为不同的参数计算不同的自适应学习率,适用于大多非凸优化,适用于大数据集和高维空间。

《深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)》

范数

解读范数的文章:通俗版认真版

1、范数的应用:

  • 正则化——权重衰减/参数范数惩罚

2、权重衰减的目的:

  • 限制模型的学习能力,通过限制参数 θ 的规模(主要是权重 w 的规模,偏置 b 不参与惩罚),使模型偏好于权值较小的目标函数,防止过拟合。

3、范数大家庭:

  • L0: 向量中非零元素的个数 (Lasso regularization)
  • L1: 向量中所有元素的绝对值之和 (L0范数的最优化问题是一个NP hard问题,而且理论上有证明,L1范数是L0范数的最优凸近似,因此通常使用L1范数来代替。)
  • L2: 向量中所有元素平方和的开方 (Ridge Regression,岭回归,“权值衰减weight decay”)
  • Lp (p>=1):其中 L1 和 L2 范数分别是Lp范数的特例
  • L∞: 向量中最大元素的绝对值,也称最大范数
  • Frobenius 范数:相当于作用于矩阵的 L2 范数

4、L1和L2对比:

我们假定:wi等于不为0的某个正的浮点数,学习速率η 为0.5:

  • L1的权值更新公式为wi= wi- η * 1  = wi- 0.5 * 1,也就是说权值每次更新都固定减少一个特定的值(比如0.5),那么经过若干次迭代之后,权值就有可能减少到0。
  • L2的权值更新公式为wi= wi- η * wi= wi- 0.5 * wi,也就是说权值每次都等于上一次的1/2,那么,虽然权值不断变小,但是因为每次都等于上一次的一半,所以很快会收敛到较小的值但不为0。

所以:

  • L1能产生等于0的权值,即能够剔除某些特征在模型中的作用(特征选择),即产生稀疏的效果。
  • L2可以得迅速得到比较小的权值,但是难以收敛到0,所以产生的不是稀疏而是平滑的效果。

机器学习中正则化项L1和L2的直观理解 - CSDN博客

5、L0.5~L2:

k-d树

»原文

k-dimensional树的简称,是一种分割k维数据空间的数据结构。主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。步骤大致如下:

  • 统计每个维上的数据方差,选取方差最大作为分割方向
  • 按这个方向取中值,去该点并垂直于分割方向的平面作为分割超平面
  • 超平面两侧便作为左右子空间,然后对左子空间和右子空间内的数据 重复根节点的过程 就可以得到下一级子节点

应用:SIFT算法中做特征点匹配的时候就会利用到k-d树。而特征点匹配实际上就是一个通过距离函数在高维矢量之间进行相似性检索的问题。针对如何快速而准确地找到查询点的近邻,现在提出了很多高维空间索引结构和近似查询的算法,k-d树就是其中一种。

当位数直接利用k-d树快速检索(维数不超过20)的性能急剧下降。假设数据集的维数为D,一般来说要求数据的规模N满足N»2D,才能达到高效的搜索。所以这就引出了一系列对k-d树算法的改进。有待进一步研究学习。

LDA线性判别分析

Linear Discriminant Analysis

假设我们有两类数据,这些数据特征是二维的,我们希望将这些数据投影到一维的一条直线,让每一种类别数据的投影点尽可能的接近,而两类数据中心之间的距离尽可能的大。

实质:投影后使得类内方差最小,类间方差最大。

朴素贝叶斯

»原文

前提:假设特征独立

Sklearn

  • 高斯模型:适用于多个类型变量,假设特征符合高斯分布。
  • 多项式模型:用于离散计数。如一个句子中某个词语重复出现,我们视它们每个都是独立的,所以统计多次,概率指数上出现了次方。
  • 伯努利模型:如果特征向量是二进制(即0和1),那这个模型是非常有用的。不同于多项式,伯努利把出现多次的词语视为只出现一次,更加简单方便。

提升方法

  • 如果连续特征不是正态分布的,我们应该使用各种不同的方法将其转换正态分布。
  • 如果测试数据集具有“零频率”的问题(如果分类变量的类别(测试数据集)没有在训练数据集总被观察到,那这个模型会分配一个0概率给它,同时也会无法进行预测),应用平滑技术“拉普拉斯估计”修正数据集。
  • 删除重复出现的高度相关的特征,可能会丢失频率信息,影响效果。
  • 朴素贝叶斯分类在参数调整上选择有限。我建议把重点放在数据的预处理和特征选择。
  • 大家可能想应用一些分类组合技术 如ensembling、bagging和boosting,但这些方法都于事无补。因为它们的目的是为了减少差异,朴素贝叶斯没有需要最小化的差异。

应用

实时预测、多类预测、文本分类、垃圾邮件过滤、情感分析、推荐系统

注:Laplace校准(拉普拉斯平滑):它的思想非常简单,就是对每个类别下所有划分的计数加1,这样如果训练样本集数量充分大时,并不会对结果产生影响,并且解决了上述频率为0的尴尬局面。

  • 假设在文本分类中,有3个类,C1、C2、C3,在指定的训练样本中,某个词语K1,在各个类中观测计数分别为0,990,10,K1的概率为0,0.99,0.01,
  • 对这三个量使用拉普拉斯平滑的计算方法如下:1/1003 = 0.001,991/1003=0.988,11/1003=0.011
  • 在实际的使用中也经常使用加 lambda(1≥lambda≥0)来代替简单加1。如果对N个计数都加上lambda,这时分母也要记得加上N*lambda。

SVM

»详细见原文

SVM是一种二类分类模型。它的基本模型是在特征空间中寻找间隔最大化的分离超平面的线性分类器。(间隔最大是它有别于感知机)

  • 当训练样本线性可分时,通过硬间隔最大化,学习一个线性分类器,即线性可分支持向量机。
  • 当训练数据近似线性可分时,引入松弛变量,通过软间隔最大化,学习一个线性分类器,即线性支持向量机。
  • 当训练数据线性不可分时,通过使用核技巧及软间隔最大化,学习非线性支持向量机。

以上各SVM的数学推导应该熟悉:硬间隔最大化(几何间隔)—学习的对偶问题—软间隔最大化(引入松弛变量)—非线性支持向量机(核技巧)

为什么要将求解SVM的原始问题转换为其对偶问题

  • 1.对偶问题往往更易求解(当我们寻找约束存在时的最优点的时候,约束的存在虽然减小了需要搜寻的范围,但是却使问题变得更加复杂。为了使问题变得易于处理,我们的方法是把目标函数和约束全部融入一个新的函数,即拉格朗日函数,再通过这个函数来寻找最优点。)
  • 2.自然引入核函数,进而推广到非线性分类问题。

为什么SVM要引入核函数

  • 当样本在原始空间线性不可分时,可将样本从原始空间映射到一个更高维的特征空间,使得样本在这个特征空间内线性可分。

为什么SVM对缺失数据敏感

  • 这里说的缺失数据是指缺失某些特征数据,向量数据不完整。SVM没有处理缺失值的策略(决策树有)。
  • 而SVM希望样本在特征空间中线性可分,所以特征空间的好坏对SVM的性能很重要。缺失特征数据将影响训练结果的好坏。

决策树

基本思想

不同于逻辑回归,决策树属于非线性模型,可以用于分类,也可用于回归。它是一种树形结构,可以认为是if-then规则的集合,是以实例为基础的归纳学习。

基本思想:自顶向下,以信息增益(或信息增益比,基尼系数等)为度量构建一颗度量标准下降最快的树,每个内部节点代表一个属性的测试,直到叶子节点处只剩下同一类别的样本。

优点:计算复杂度不高,对中间缺失值不敏感,解释性强,决策树的预测准确性一般比回归和分类方法弱,但可以通过用集成学习方法组合大量决策树,显著提升树的预测效果。

分类树

最小化均方误差选择划分特征,切分点(值)将数据切分成两部分。

决策树的学习包括三个重要的步骤:

1.特征选择:常用的特征选择有信息增益,信息增益比,基尼系数等。(这三种指标分别对应三种算法ID3,C4.5,CART。)

2.生成过程:通过计算信息增益或其它指标,选择最佳特征。从根结点开始,递归地产生决策树,不断的选取局部最优的特征,将训练集分割成能够基本正确分类的子集。

3.剪枝过程:首先定义决策树的评价指标,对于所有的叶子结点,累加计算每个叶子结点中的(样本数)与其(叶子节点熵值)的乘积,以叶子数目作为正则项(它的系数为剪枝系数)。然后计算每个结点的剪枝系数,它的大概含义是删除该结点的子树,损失不变的前提下,正则项系数的值为多少,这个值越小说明该子树越没有存在的必要。依次选取剪枝系数最小的结点剪枝,得到决策树序列,通过交叉验证得到最优子树。

参考链接

回归树

一个回归树对应着输入空间(即特征空间)的一个划分以及在划分单元上的输出值。

最小平方误差的准则求解每个单元上的最优输出值(每个叶子节点上的预测值为所有样本的平均值)。

建立回归树的过程大致可以分为两步:

1.将预测变量空间(X1,X2,X3,…,Xp)的可能取值构成的集合分割成J个互不重叠的区域{R1,R2,R3,…,RJ}

2.对落入区域RJ的每个观测值作同样的预测,预测值等于RJ上训练集的各个样本取值的算术平均数。

参考链接

树的Bagging与Boosting

对于Bagging算法来说,由于我们会并行地训练很多不同的分类器的目的就是降低这个方差(variance) ,因为采用了相互独立的基分类器多了以后,h的值自然就会靠近.所以对于每个基分类器来说,目标就是如何降低这个偏差(bias),所以我们会采用深度很深甚至不剪枝的决策树。

对于Boosting来说,每一步我们都会在上一轮的基础上更加拟合原数据,所以可以保证偏差(bias),所以对于每个基分类器来说,问题就在于如何选择variance更小的分类器,即更简单的分类器,所以我们选择了深度很浅的决策树。

随机森林

鉴于决策树容易过拟合的缺点,随机森林采用多个决策树的投票机制来改善决策树:

我们假设随机森林使用了m棵决策树,那么就需要产生m个一定数量的样本集来训练每一棵树,如果用全样本去训练m棵决策树显然是不可取的,全样本训练忽视了局部样本的规律,对于模型的泛化能力是有害的

产生n个样本的方法采用Bootstrap取样法,这是一种有放回的抽样方法,产生n个样本

而最终结果采用Bagging的策略来获得,即多数投票机制

生成方法

1.从样本集中通过重采样的方式产生n个样本

2.假设样本特征数目为a,对n个样本选择a中的k个特征,用建立决策树的方式获得最佳分割点

3.重复m次,产生m棵决策树

4.多数投票机制来进行预测

  • 需要注意的一点是,这里m是指循环的次数,n是指样本的数目,n个样本构成训练的样本集,而m次循环中又会产生m个这样的样本集

模型总结

随机森林是一个比较优秀的模型,它对于多维特征的数据集分类有很高的效率,还可以做特征重要性的选择。

运行效率和准确率较高,实现起来也比较简单。但是在数据噪音比较大的情况下会过拟合,过拟合的缺点对于随机森林来说还是较为致命的。

决策树的Boosting集成

Boosting

让错分的样本权重越来越大,使它们被后面的树更加重视

Boosting 每一步的残差计算其实变相地增大了分错instance的权重,而已经分对的instance则都趋向于0。这样后面的树就能越来越专注那些前面被分错的instance。

Adaboost 按分类对错,分配不同的weight,计算cost function时使用这些weight,从而让“错分的样本权重越来越大,使它们更被重视”。

GBDT

Gradient Boosting Decison Tree 的详细推导GBDT要点总结

每一棵树学的是之前所有树结论和的残差,这个残差就是一个加预测值后能得真实值的累加量

特征重要度:通过计算在每棵树中按这个特征分裂之后损失的减少值,最后取平均值

1、Gradient Boost与传统的Boost的区别:

每一次的计算是为了减少上一次的残差(residual),而为了消除残差,我们可以在残差减少的梯度(Gradient)方向上建立一个新的模型。所以说,在Gradient Boost中,每个新的模型的建立是为了使得之前模型的残差往梯度方向减少。

  • 优点:它的非线性变换比较多,表达能力强,而且不需要做复杂的特征工程和特征变换。
  • 缺点: Boost是一个串行过程,不好并行化,而且计算复杂度高,同时不太适合高维稀疏特征。

2、在回归和多分类任务中的主要区别:

在于损失函数不同造成的算法初始化不同以及叶节点取值和表示含义的不同

损失函数:

  • 回归任务:常用均方损失函数、绝对值损失函数和Huber损失函数(前面两者的折中)
  • 多分类任务:采用多类逻辑损失函数(二分类是对数损失函数)

预测值:

  • 对于回归, 定义好损失函数之后, GBDT算法的预测值表示与真实值的偏差
  • 多分类中的预测值则表示预测值为真实值的概率

ps: 对于多分类, GBDT采用一对多策略, 训练过程中的主要区别是多分类中多了一层内部for循环(k个类别都各自拟合完一棵树之后再拟合下一棵树, 一共拟合M轮, 最终有M·K颗树, 最后使用softmax来计算最终的类别概率。(»链接

3、GBDT防止过拟合的几种方法:

  • 控制tree的棵树,即迭代次数M。
  • 控制学习率。根据经验,已经发现使用较小的学习率(例如)会使模型的泛化能力显着提高。
  • 随机采样迭代。类bagging方法,经验来说随机采样率f在0.5<=f<=0.8比较合适,即可以帮助避免过拟合又可以提高训练速度。
  • 控制叶子节点中的最少样本个数。
  • 惩罚树的复杂性(复杂性定义为叶子数占树所有节点的比例),用一个后验剪枝算法来对loss和树的复杂度进行联合优化,该方法为去掉那些降低loss幅度小于指定阈值的分支。
  • 加入正则:特征的正向正则或者负向正则。在分裂的时候,除了满足最小平方差之外,要保证左子树的lable平均值小于右子树的lable平均值,反之为负向正则。

XGBoost

能自动利用cpu的多线程,而且适当改进了gradient boosting,加了剪枝,控制了模型的复杂程度

特征重要度:通过该特征每棵树中分裂次数的和去计算的,比如这个特征在第一棵树分裂1次,第二棵树2次……,那么这个特征的得分就是(1+2+…)。

传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。

传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。(xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。)

它的并行是在特征粒度上的:我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。 这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。

可并行的近似直方图算法:树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。 当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点。

lightGBM

基于决策树算法的分布式梯度提升框架

关于数据分割点:

XGBoost使用的是pre-sorted算法(对所有特征都按照特征的数值进行预排序,在遍历分割点的时候用O(data)的代价找到一个特征上的最好分割点),能够更精确的找到数据分隔点

LightGBM使用的是histogram算法,占用的内存更低,数据分隔的复杂度更低

关于决策树的生长策略:

XGBoost采用的是level-wise生长策略,能够同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合;但不加区分的对待同一层的叶子,带来了很多没必要的开销(因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂)

LightGBM采用leaf-wise生长策略,每次从当前所有叶子中找到分裂增益最大(一般也是数据量最大)的一个叶子,然后分裂,如此循环;但会生长出比较深的决策树,产生过拟合(因此LightGBM 在leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合)。

另一个比较巧妙的优化是histogram 做差加速。一个容易观察到的现象:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。

XGBoost 和 LightGBM 详细对比

RNN

CNN 在处理变长序列时,通过卷积(滑动窗口)+池化的方式将输入转化为一个定长的向量表示,这样做可以捕捉到序列中的一些局部特征,但是很难学习到序列间的长距离依赖。

1、RNN 处理时序数据时的优势:

  • RNN 很适合处理序列数据,特别是带有时序关系的序列,比如文本数据
  • RNN 把每一个时间步中的信息编码到状态变量中,使网络具有一定的记忆能力,从而更好的理解序列信息
  • 由于 RNN 具有对序列中时序信息的刻画能力,因此在处理序列数据时往往能得到更准确的结果

2、如果使用 ReLU 作为 RNN 的激活函数,应该注意什么?

  • 假设使用 ReLU 并始终处于激活状态,把RNN的式子展开,最终结果中将包含 t 个 W 连乘,如果 W 不是单位矩阵,最终结果将趋于 0 或无穷。
  • RNN 因为每一个时间步都共享参数的缘故,容易出现数值溢出问题。因此,推荐的做法是将 W 初始化为单位矩阵。
  • 有实践证明,使用单位矩阵初始化 W 并使用 ReLU 作为激活函数在一些应用中,与 LSTM 有相似的结果

为什么普通的前馈网络或 CNN 中不会出现这中现象? >因为他们每一层的 W 不同,且在初始化时是独立同分布的,因此可以在一定程度相互抵消。即使多层之后一般也不会出现数值问题。

LSTM

1、LSTM 是如何实现长短期记忆的?(遗忘门和输入门的作用)

  • LSTM 主要通过遗忘门和输入门来实现长短期记忆:
    • 如果当前时间点的状态中没有重要信息,遗忘门 f 中各分量的值将接近 1(f -> 1);输入门 i 中各分量的值将接近 0(i -> 0);此时过去的记忆将会被保存,从而实现长期记忆
    • 如果当前时间点的状态中出现了重要信息,且之前的记忆不再重要,则 f -> 0,i -> 1;此时过去的记忆被遗忘,新的重要信息被保存,从而实现短期记忆
    • 如果当前时间点的状态中出现了重要信息,但旧的记忆也很重要,则 f -> 1,i -> 1

2、LSTM 里各部分使用了不同的激活函数?

  • 在 LSTM 中,所有控制门都使用 sigmoid 作为激活函数(遗忘门、输入门、输出门)
  • 在计算候选记忆或隐藏状态时,使用双曲正切函数 tanh 作为激活函数

(1)sigmoid的“饱和”性

  • 所谓饱和性,即输入超过一定范围后,输出几乎不再发生明显变化了
  • sigmoid 的值域为 (0, 1),符合门控的定义:
    • 当输入较大或较小时,其输出会接近 1 或 0,从而保证门的开或关
    • 如果使用非饱和的激活函数,将难以实现门控/开关的效果
  • sigmoid 是现代门控单元中的共同选择

(2)为什么使用tanh

  • 使用 tanh 作为计算状态时的激活函数,主要是因为其值域为 (-1, 1)
    • 一方面,这与多数场景下特征分布以 0 为中心相吻合;
    • 另一方面,可以避免在前向传播的时候发生数值问题(主要是上溢)
  • 此外,tanh 比 sigmoid 在 0 附近有更大的梯度,通常会使模型收敛更快:
    • 早期,使用 h(x) = 2*sigmoid(x) - 1 作为激活函数,该激活函数的值域也是 (-1, 1)

CNN

1、卷积核为3、步幅为1和带有边界扩充的二维卷积结构

卷积的内部实现实际上是矩阵相乘,因此,卷积的反向传播过程实际上跟普通的全连接是类似的。 基本的卷积(+池化)看做“缩小分辨率”的过程,那么转置卷积就是“扩充分辨率”的过程。(» 其他卷积结构链接

2、二维卷积层的结构参数

  • 卷积核大小(Kernel Size):定义了卷积操作的感受野。在二维卷积中,通常设置为3,即卷积核大小为3×3。
  • 步幅(Stride):定义了卷积核遍历图像时的步幅大小。其默认值通常设置为1,也可将步幅设置为2后对图像进行下采样,这种方式与最大池化类似。
  • 边界扩充(Padding):定义了网络层处理样本边界的方式。当卷积核大于1且不进行边界扩充,输出尺寸将相应缩小;当卷积核以标准方式进行边界扩充,则输出数据的空间尺寸将与输入相等。
  • 输入与输出通道(Channels):构建卷积层时需定义输入通道I,并由此确定输出通道O。这样,可算出每个网络层的参数量为I×O×K,其中K为卷积核的参数个数。例,某个网络层有64个大小为3×3的卷积核,则对应K值为 3×3 =9。

3、为什么使用 CNN 代替 RNN? > 文章《关于序列建模,是时候抛弃RNN和LSTM了》

(1)RNN 与目前的硬件加速技术不匹配

训练 RNN 和 LSTM 非常困难,因为计算能力受到内存和带宽等的约束。简单来说,每个 LSTM 单元需要四个仿射变换,且每一个时间步都需要运行一次,这样的仿射变换会要求非常多的内存带宽。添加更多的计算单元很容易,但添加更多的内存带宽却很难——这与目前的硬件加速技术不匹配,一个可能的解决方案就是让计算在存储器设备中完成。

(2)RNN 容易发生梯度消失,包括 LSTM

在长期信息访问当前处理单元之前,需要按顺序地通过所有之前的单元。这意味着它很容易遭遇梯度消失问题;LSTM 一定程度上解决了这个问题,但 LSTM 网络中依然存在顺序访问的序列路径;实际上,现在这些路径甚至变得更加复杂

(3)注意力机制模块(记忆模块)的应用

  • 注意力机制模块可以同时前向预测和后向回顾。
  • 分层注意力编码器(Hierarchical attention encoder)
  • 分层注意力模块通过一个层次结构将过去编码向量汇总到一个上下文向量Ct —— 这是一种更好的观察过去信息的方式(观点)
  • 分层结构可以看做是一棵树,其路径长度为 logN,而 RNN/LSTM 则相当于一个链表,其路径长度为 N,如果序列足够长,那么可能 N » logN

从任务本身考虑,我认为也是 CNN 更有利,LSTM 因为能记忆比较长的信息,所以在推断方面有不错的表现(直觉);但是在事实类问答中,并不需要复杂的推断,答案往往藏在一个 n-gram 短语中,而 CNN 能很好的对 n-gram 建模。

ResNet

1、网络的深度为什么重要?

  • 因为CNN能够提取low/mid/high-level的特征,网络的层数越多,意味着能够提取到不同level的特征越丰富。
  • 并且,越深的网络提取的特征越抽象,越具有语义信息。

2、为什么不能简单地增加网络层数?

  • 对于原来的网络,如果简单地增加深度,会导致梯度消失或梯度爆炸。
  • 对于该问题的解决方法是正则化初始化和中间的正则化层(Batch Normalization),这样的话可以训练几十层的网络。
  • 虽然通过上述方法能够训练了,但是又会出现另一个问题,就是退化问题,网络层数增加,但是在训练集上的准确率却饱和甚至下降了。这个不能解释为overfitting,因为overfit应该表现为在训练集上表现更好才对。

3、退化问题说明了深度网络不能很简单地被很好地优化:

  • 作者通过实验:通过浅层网络后面加上y=x形式的等同映射构造深层模型,结果深层模型并没有比浅层网络有等同或更低的错误率。
  • 推断退化问题可能是因为深层的网络并不是那么好训练,也就是求解器很难去利用多层网络拟合同等函数

4、怎么解决退化问题?

  • 深度残差网络。如果深层网络的后面那些层是恒等映射(identity mappings),那么模型就退化为一个浅层网络。(这反映了多层非线性网络无法逼近恒等映射网络。
  • 那现在要解决的就是学习恒等映射函数了。 但是直接让一些层去拟合一个潜在的恒等映射函数H(x) = x,比较困难,这可能就是深层网络难以训练的原因。
  • 但是,如果把网络设计为H(x) = F(x) + x,如下图。我们可以转换为学习一个残差函数F(x) = H(x) - x. 只要F(x)=0,就构成了一个恒等映射H(x) = x. 而且,拟合残差肯定更加容易

ResNet就是用下面这种跳跃结构来作为网络的基本结构。通过在一个浅层网络基础上叠加 y = x 的层(称identity mappings,恒等映射),可以让网络随深度增加而不退化。

  • F是求和前网络映射,H是从输入到求和后的网络映射。比如把5映射到5.1,那么引入残差前是F’(5)=5.1,引入残差后是H(5)=5.1, H(5)=F(5)+5, F(5)=0.1。
  • 这里的F’和F都表示网络参数映射,引入残差后的映射对输出的变化更敏感。比如s输出从5.1变到5.2,映射F’的输出增加了1/51=2%,而对于残差结构输出从5.1到5.2,映射F是从0.1到0.2,增加了100%。明显后者输出变化对权重的调整作用更大,所以效果更好。
  • 残差的思想都是去掉相同的主体部分,从而突出微小的变化
  • 至于为何shortcut的输入时X,而不是X/2或是其他形式。kaiming的另一篇文章中探讨了这个问题,对以下6种结构的残差结构进行实验比较,shortcut是X/2的就是第二种,结果发现还是第一种效果好啊…

这种残差学习结构可以通过前向神经网络+shortcut连接实现,如结构图所示。而且shortcut连接相当于简单执行了同等映射,不会产生额外的参数,也不会增加计算复杂度。 而且,整个网络可以依旧通过端到端的反向传播训练。

相关资料链接:PPT简书