3w+深度盘点:机器学习面试知识点梳理!
Posted Python学习与数据挖掘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3w+深度盘点:机器学习面试知识点梳理!相关的知识,希望对你有一定的参考价值。
大家好,今天我来梳理一下机器学习、算法、数据挖掘等岗位面试时必备的知识点,欢迎收藏学习,喜欢点赞支持。
机器学习主要分为监督学习和无监督学习。
- 有监督学习:对具有标记的训练样本进行学习,以尽可能对训练样本集外的数据进行分类预测。(LR、SVM、BP、RF、GBRT)
- 无监督学习:对未标记的样本进行训练学习,比发现这些样本中的结构知识。(KMeans、DL)
监督学习
回归
线性回归
所谓的线性回归,就是要找一个线性的超平面,去尽可能地拟合各个样本点。在一维的情况下,如图所示:
我们要寻找一条直线,让它尽可能地穿过这些点。“尽可能”可能有一些度量,比如说让误差平方和最小。
求解这条直线的方法有最小二乘方法等。
线性回归是一种简单但却使用的回归技术。
多重共线性(Multicollinearity)是指线性回归模型中的自变量之间由于存在高度相关关系而使模型的权重参数估计失真或难以估计准确的一种特性,多重是指一个自变量可能与多个其他自变量之间存在相关关系。共线性不影响模型的预测而是影响对模型的解释。神经网格本来可解释性就差,就不存在这种共线性的问题。
岭回归
lasso回归
分类
k最近邻分类
所谓物以类聚,人以群分,你的圈子基本决定了你的状态。我们可以用周围的邻居来判断自己的情况,基于这个思想,就有了k-NN算法。k近邻算法不仅可以用于分类,也可以用于回归,我这里将它放在了分类的条目下。
分类问题中,一个对象的分类是由其邻居的“多数表决”确定的,k个最近邻居(k为正整数,通常较小)中最常见的分类决定了赋予该对象的类别。若k=1,则该对象的类别直接由最近的一个节点赋予。无论是分类还是回归,衡量邻居的权重都非常有用,使较近邻居的权重比较远邻居的权重大。例如,一种常见的加权方案是给每个邻居权重赋值为1/d,其中d是到邻居的距离。这样会避免一些单纯计数带来的问题。
k 参数的选择可以使用交叉验证和自助法等等。
k-近邻算法的缺点是对数据的局部结构非常敏感。
三要素:
- k 值的选择
- 距离的度量(常见的距离度量有欧式距离,马氏距离等)
- 分类决策规则 (多数表决规则)
k 值的选择
k 值越小表明模型越复杂,更加容易过拟合。k 值越大,模型越简单,极端情况如果 k=N 的时候就表明无论什么点都是训练集中类别最多的那个类。所以一般 k 会取一个较小的值,然后用过交叉验证来确定。这里所谓的交叉验证就是将样本划分一部分出来为预测样本,比如 95% 训练,5% 预测,然后 k 分别取1,2,3,4,5之类的,进行预测,计算最后的分类误差,选择误差最小的 k。简单地来说,就是试一试。
KNN 的回归
在找到最近的 k 个实例之后,可以计算这 k 个实例的平均值作为预测值。或者还可以给这 k 个实例添加一个权重再求平均值,这个权重与度量距离成反比(距离越大,权重越低)。
优缺点:
KNN算法的优点:思想简单,理论成熟,既可以用来做分类也可以用来做回归;可用于非线性分类;训练时间复杂度为O(n);准确度高,对数据没有假设,对 outlier 不敏感。
KNN算法的缺点:计算量大;样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少);需要大量的内存。
KNN 算法中 KD 树的应用
我们知道在上述 KNN 的计算中,我们要找一个点的 k 近邻,必须要计算这个点到所有点的距离,再取小的一部分。这个计算量超大。KD tree 就是为了解决这个问题的。顺着 KD tree 去搜索,我们可以很快地找到一个点的最近邻,而不需要计算这个点到所有点的距离。
当点随机分布的时候,搜索的复杂度为log(N),N 为实例的个数,KD 树更加适用于点的
数量远大于空间维度的 KNN 搜索,如果空间维度与点个数差不多时,它的效率基于等于线性扫描。
关于 KD 数的构建,搜索和 KNN 查找,网上有很多资料,这里就不介绍了。
可以观察到 KD-tree 是这样一种 tree。它的第一层的第一个元素大于左子树的第一个元素,小于右子树的第一个元素。第二层的第二个元素大于左子树的第二个元素,小于右子树的第二个元素。第 i 层的第 i%k 个元素大于左子树的第 i%k 个元素,小于右子树的,依次类推。
朴素贝叶斯分类
朴素贝叶斯真的很朴素,用到的仅仅只是贝叶斯公式。以二分类为例,它给定若干组的带标签的数据,当新给一组特征时,我们需要判断它属于哪一类。
我们通过比较这组特征下的条件概率P(标签1∣{特征1,特征2,特征3})和P(标签2∣{特征1,特征2,特征3})大小来对其分类。条件概率的计算可通过贝叶斯公式来计算,即
P(标签i∣{特征1,特征2,特征3})=P({特征1,特征2,特征3})P({特征1,特征2,特征3}∣标签i)∗P(标签i)
我们假设特征之间是独立的,那么就有
P({特征1,特征2,特征3}∣标签i)P({特征1,特征2,特征3})==P(特征1∣标签i)∗P(特征2∣标签i)∗P(特征3∣标签i)P(特征1)∗P(特征2∣标签i)∗P(特征3)
这些量和**P(标签i)**都是可以通过统计已有的样本数据,用频率来概率得到。
注意要,使用朴素贝叶斯分类方法,我们假设了特征之间相互独立,看起来很有局限。事实上,我们在处理文本数据的时候,常常用到这种方法。
主要就是利用贝叶斯公式,把某组特征下产生某个标签的概率进行了拆解,进一步拆解是利用到了特征之间的不相关性。
基本过程如下:
- 假设现在有样本 x=(a1,a2,a3,…an) 这个待分类项 (并认为 x 里面的特征独立)。
- 再假设现在有分类目标 Y={y1,y2,y3,y4…yn}。
- 那么 max{P(y1∣x),P(y2∣x),P(y3∣x)…P(yn∣x)} 就是最终的分类类别。
- 而根据贝叶斯公式 P(yi∣x)=P(x)P(x∣yi)∗P(yi)。
- 因为 x 对于每个分类目标来说都一样, 所以不用管分子,就是求 max{P(x∣yi)∗p(yi)}。
- P(x∣yi)∗P(yi)=P(yi)∗j=1∏n(P(aj∣yi))
- 而具体的 P(aj∣yi) 和 P(yi) 都是能从训练样本中统计出来:p(aj∣yi) 表示该类别下该特征出现的概率,p(yi) 表示全部类别中这个这个类别出现的概率。
就这么简单。特征为离散值时直接统计即可(表示统计概率)。特征为连续值的时候假定特征符合高斯分布。
拉普拉斯校验
当某个类别下某个特征划分没有出现时,会有 P(a∣y)=0, 就是导致分类器质量降低, 所以此时引入 Laplace 校验,就是对每个类别下所有划分的计数加1。
特征不独立问题
参考改进的贝叶斯网络,使用有向无环图来进行概率图的描述。
优缺点
- 优点: 对小规模的数据表现很好,适合多分类任务,适合增量式训练。
- 缺点:对输入数据的表达形式很敏感 (离散、连续, 值极大极小之类的) 。
logistic回归
逻辑回归在有些书中也叫对数几率回归,常用于分类问题,特别是二分类问题。逻辑回归是线性回归的一个延伸,对于二分类问题,我们需要将回归的连续值搞成离散值,基本做法是看其是否大于零。那么参数如何选取呢?所谓的逻辑回归,就是我们在原有的线性回归的基础上,外套一个Sigmoid函数作为取值的概率(准确地来说,应该是取值为正样本 1 的概率),其实上也就是:
p(y=1∣x)=1+ewTx+bewTx+bp(y=0∣x)=1+ewTx+b1
我们通过最大似然估计来估计参数,最大似然估计就是写出在参数下出现这个结果的概率(为了计算方便,一般取个对数),然后对于参数变量,极大化这个概率值,一般可以直接对参数直接求导。其实,也就是极大化如下的似然函数。
ℓ(w,b)=i=1∑mlnp(yi∣xi;w,b)
所谓的Sigmoid函数,它的表达式和图像如图所示,图像右端y的取值表示将线性回归的连续值按零点离散化。
逻辑回归的并行化最主要的就是对目标函数梯度计算的并行化。逻辑回归的条件分布是伯努利分布,而线性回归的是高斯分布。逻辑回归认为函数其概率服从伯努利分布,将其写成指数族分布的形式,最后是可以推导得到 sigmoid 函数,这也是用这个函数的原因。
逻辑回归用于多分类:
对于多分类问题,我们可以用 softmax,这时候优化的参数,不是向量,而是矩阵θ。我们用线性函数外套一个 softmax 作为每个第 j 个类别取值的概率:
pj=∑s=1keθsTxeθjTx
别的过程是一样的。
优缺点:
优点
- 实现简单。
- 分类时计算量非常小,速度很快,存储资源低。
缺点
- 容易欠拟合,一般准确度不太高。
- 只能处理两分类问题(在此基础上衍生出来的 softmax可以用于多分类),且必须线
性可分。
支持向量机
支持向量机,我们先说线性的情况,以可分的二维的二分类问题为例,它其实上就是寻找一根直线,将平面上的数据点正确地分为两类,并满足分割的间隔达到最大。如图所示,
要分割(a)所示的数据点,显然(b)的分割间隔要大于©的分割间隔。这里可变参数是分割线(“决策面”)的斜率和截距。所谓的间隔就是分割线离两个数据集合的距离,它是用离它最近的一个点来衡量的。我们引两根平行于分割线的面,相切两个数据集,那么就形成了一个间隙。这个间隙内部不含任何的数据点。间隙边缘上的点称作支持向量。
如果将直线表示为w Tx +b =0,那么合理的分割如图。
通过数学推导,我们可以知道,这个问题其实就是求解如下的一个优化问题(w 和b 是待求变量):
KaTeX parse error: Unknown column alignment: @ at position 70: …\\begin{array}{r@̲{\\quad}r@{}l@{\\…
其中yi∈{−1,1},表示两类样本的标签。通过最优化的基本理论(拉格朗日对偶,KKT条件,SMO算法等),我们可以求解这个优化问题。
一般情况下,数据点不一定可以通过一个线性的超平面将其分开。那么我们可以将其映射到更高维的空间中,使其在高维的特征空间中线性可分,通过线性SVM方法将其分开。
线性情况下,最后的决策面的表达式可以表示为f(x)=i=1∑nαiyi⟨xi,x⟩+b,这里的αi是原问题拉格朗日乘子系数。对应于高维特征空间,使用线性SVM方法,最后决策面的表达式为:
f(x)=i=1∑nαiyi⟨Φ(xi),Φ(x)⟩+b,也就是说,分类决策函数只依赖于输入x与训练样本的输入的内积。
这里的Φ是原始空间到高维空间的一个映射,比如说它可以是(x,y)→(x,y,x2+y2)。因为升维可能造成计算量暴涨,我们寻求一种方法可以直接计算内积⟨Φ(xi),Φ(x)⟩,即寻找一个函数k(xi,x)来表示⟨Φ(xi),Φ(x)⟩,这种替换技巧叫做核技巧。因为核函数方法的存在,使得高维空间中的两个向量的内积可以直接计算,大大减少了计算量。
高维空间的决策平面用核函数来表达,那么高维空间中的对偶问题等也可以用核函数来表达,当使用SMO算法迭代求解时,计算量就会大大减小。简单地说,核方法通过用核函数表示高维空间中向量的内积,将原空间升维至高维空间和在高维空间中使用线性SVM方法两个步骤合成了一个步骤。所谓的升维,也可以理解为在原来线性基的基础上,添加一些非线性的基函数,使得分割线不再是直线。
常用的核函数为径向基函数,它的表达式为:
κ(x1,x2)=e2σ2−∣∣x1−x2∣∣2
σ越小,非线性化程度越高。如果σ选得很小,则可以将任意的数据映射为线性可分。这有可能会过拟合问题。
常用核函数有:多项式核函数、高斯核函数、字符串核函数。
数学推导:
关于第一步的数学推导,我们只需要有以下的几个基本认知:
- 我们用线性水平集函数z=wTx+b的零水平集wTx+b=0来表示决策面。
- 点到决策面的距离是:
r=∥w∥∣∣wTx+b∣∣.
这里的∥w∥实际上是表示这个水平集函数的斜率。 - 因为斜面的斜率不影响决策面,那么就不影响分类的结果,那么对于上述问题,事实上就多了一个自由度。那么我们就可以限制 w,是的支持向量的距离 $d = \\frac{1} {|\\boldsymbol{w}|} $。那么约束的目标函数实际上就有了。
- 上述约束,其实也就以为着,对于决策点 ∣∣wTx+b∣∣=1,那么要想其他点正确地分类,自然而然地就有:
{wTxi+b⩾+1,wTxi+b⩽−1,yi=+1yi=−1
优缺点:
优点:
- 使用核函数可以向高维空间进行映射,可以解决非线性的分类。
- 分类思想很简单,就是将样本与决策面的间隔最大化。
- 分类效果较好。
缺点:
- 对大规模数据训练比较困难。
- 无法直接支持多分类,一般使用间接的方法来做。直接方法可以在目标函数上下功夫,但计算量比较大。间接法有两种,一种是一对多,即取出一类作为一类,另外的 N-1 类作为一类,做一次二分类,接着在分得的子类中重复这个操作。第二种是一对一,即两两之间都进行一次分类,最后看哪一类被分到的次数最多,就选哪一类(vote 的思想,libsvm,可以用循环图加速)。
其他
随机梯度下降
我们知道,在做有监督的问题中,有一个损失函数,用来衡量模型的好坏。在回归问题中,如果我们已经知道方程的形式,我们可以做出问题的损失函数。那么我们要做的就是寻找方程的最佳参数,即寻找参数,使得损失函数函数达到最小。乍一听,这就是个优化问题。当然可以对参数的各个分量求导,最后解方程组。问题是,你能确定最后的方程组好解?一般的数值解法有梯度下降法、牛顿法、拟牛顿方法以及信赖域方法等等。
梯度下降方法简单易行,可是当数据量比较大时,梯度下降的计算就特别大。为解决大数据量的优化求解,我们一般可以采用随机梯度下降。
所谓的随机梯度下降,就是相比梯度下将,我们不选择全部的数据点,而是每次随机选择一个或者若干个数据点来构建损失函数,接着再用梯度下降方法求解。看起来很不靠谱的样子,事实上多做几次这个操作,它是可以收敛的最优解的某个邻域的。
随机梯度下降比起梯度下降:
- 可以避免局部极值
- 收敛速度快
- 易并行
说完随机梯度下降,顺便提一下 Adam加速,Adam使用动量和自适应学习率来加快收敛速度。其在SGD基础上加入了一、二阶动量。
AdaGrad 能够实现学习率的自动更改。如果这次梯度大,那么学习速率衰减的就快一些;如果这次梯度小,那么学习速率衰减的就满一些。
线性判别分析
所谓的线性判别分析(LDA),实际上是一种有监督的降维方法。之所以把它放在分类的标题下,是因为数据通过这种方式,在距离上有了更高的区分度,也可以说是为后续的分类做了降维处理。
线性判别分析,以二维数据点举例,就是要一条直线,使得数据点在这根直线上的投影满足类内方差尽可能小,类间距离尽可能大,如图所示。
投影面的选择,往往会影响类内方差,和类间距离。显然图所示的右边一个图更能满足我们的要求。
我们将类间距离的度量作为分子,类内距离的度量作为分母,形成一个目标函数,我们要做的就是最大化这个目标函数。利用广义瑞利商等一些基本的知识,我们就将问题转化为了求特征值的问题。
决策树
决策树,顾名思义就是像树一样不断分支。我们对每个特征,选择一定的条件进行判断,就可以将数据不断地分类,直到最后叶子节点满足一定的条件,比如说有同一个标签,那么这就是一棵决策树。举个例子,比如说西瓜好坏的判断,从数据中,我们可能会学习出如图所示的一棵决策树。
分类问题,往往是给定若干组数据,每组数据有一些特征和标签。需要找一棵决策树,使得每组数据按照决策树路径走,最后尽可能地能走到使它正确分类的叶子节点中。一般来说,可能满足条件的决策树有很多,用于做判断特征选择的次序和特征判断条件(阈值设定不同等)的不同都会导致树的不同,我们要做的就是找一棵最好的树。在不同的算法中,“好”的标准往往不同。
比较常用的决策树有ID3、C4.5和分类回归树(CART),他们分别使用信息增益、信息增益率和基尼指数来作为分类条件选择好坏的标准。C4.5是为解决ID3因偏向细小分割造成的过拟合问题的,CART方法的过拟合往往由剪枝方法来处理。
- ID3 选择信息增益最大的特征作为当前节点的决策特征。
- C4.5 选择信息增益率大的作为划分特征。
- CART 选择那个使得划分后基尼指数最小的属性作为最优划分属性。
优缺点:
优点:
- 计算量简单,可解释性强,比较适合处理有缺失属性值的样本,能够处理不相关的特
征。
缺点:
2. 单棵决策树分类能力弱,并且对连续值变量难以处理。
3. 容易过拟合(后续出现了随机森林,减小了过拟合现象)。
基本概念:
信息熵:
Ent(D)=−k=1∑∣Y∣pklog2pk
信息增益:
Gain(D,a)=Ent(D)−v=1∑V∣D∣∣Dv∣Ent(Dv)
增益率:
Gain_ratio(D,a)=IV(a)Gain(D,a)
IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣
基尼值:
Gini(D)=k=1∑∣Y∣k′=k∑pkpk′=1−k=1∑∣Y∣pk2
属性 a 基尼指数:
KaTeX parse error: Expected ‘}’, got ‘_’ at position 14: \\text { Gini_̲index }(D, a)=\\…
简单来说就是分而治之的思想。
Cart : 分类模型:采用基尼系数的大小度量特征各个划分点的优劣。回归模型:采用误差平方和度量。
无监督学习
聚类
k均值
所谓的k-mean算法,就是要找到点的一个划分(假设分成k类),使得类内平方和达到最小。用数学来表述就是要求解下式表示的优化问题。
Sargmini=1∑kx∈Si∑∣∣x−μi∣∣2
算法的基本思想是迭代。首先选择k个点作为k个类中心,将所有点按距离中心的远近分配给k个类。接着计算k个类的重心作为新的类中心,继续前述的分配过程,直到中心不再改变,那么分类也不再改变。
容易想到,更新中心为重心步骤,类内距离平方是不增的,重新分配点的步骤距离也是不增,距离平方和有下界,故而算法必然是收敛的。
事实上,算法收敛到会收敛到一个局部最优值,初始点选择得不同,那么最终收敛到的结果可能就不同。
初始点的选择:
-
首先随机选取一个点作为初始点,然后选择距离与该点最远的那个点作为中心点,再选择距离与前两个点最远的店作为第三个中心店,以此类推,直至选取大 k 个。
-
选用层次聚类或者 Canopy 算法进行初始聚类。
kmeans 的优化:使用 kd 树。将所有的观测实例构建成一颗 kd 树,之前每个聚类中心都是需要和每个观测点做依次距离计算,现在这些聚类中心根据 kd 树只需要计算附近的一个局部区域即可。
k 怎么选?
- 根据专家、行业经验进行主观判断
- 基于变化的算法:即定义一个函数,随着 k 的改变,认为在正确的 k 时会产生极值。
- 基于结构的算法:即比较类内距离,类间距离以确定 k。这也是比较常用的方法,如使用平均轮廓系数,越趋近于1,聚类效果越好。
- 基于一致性矩阵的算法:即认为在正确的 k 时,不同次聚类的结果会近似,以此确定 k。
- 基于层次聚类:即基于合并或分裂的思想,在一定情况下停止从而获得 k。
- 使用 BIC 算法进行初始划分。
- 基于采样的算法:即对样本采样,分别做聚类。根据这些结果的相似性确定 k。
- 使用 Canopy Method 算法进行初始划分。
分层次聚类
谱聚类
高斯混合模型
EM算法可以形象地比喻鸡生蛋,蛋生鸡的过程。EM 用于隐含变量的概率模型的极大似然估计。它一般分为两步:
- 第一步求期望(E)
- 第二步求极大(M)
如果概率模型的变量都是观测变量,那么给定数据之后就可以直接使用极大似然法或者
贝叶斯估计模型参数。但是当模型含有隐含变量的时候就不能简单的用这些方法来估计,EM 就是一种含有隐含变量的概率模型参数的极大似然估计法。
应用到的地方:混合高斯模型、混合朴素贝叶斯模型、因子分析模型。
降维
PCA降维
所谓的主成分分析,不过是在高维的空间中寻找一个低维的正交坐标系,比如说在三维空间中寻找一个二维的直角坐标系。那么这个二维的直角坐标系就会构成一个平面,将三维空间中的各个点在这个二维平面上做投影,就得到了各个点在二维空间中的一个表示,由此数据点就从三维降成了二维。
这个过程的关键在于,我们如何选取这个低维的坐标系,即坐标系原点在哪?各个轴朝哪个方向?一个原则就是使得各个点到到这个平面的距离平方和达到最小。由此,通过简单地数学推导,就能得到原点的表达公式和坐标系的各个基向量的表达公式。
下面以基于矩阵的视角写出PCA算法的算法流程,输入为p*N矩阵X,输出为d*N矩阵Y。矩阵的每一列都表示一个对象,每一行都表示对象的一个特征表示。
选取了2000x1680的数据集进行了测试,选取降维后维数为20,其降维前后的图像(降维后的图像指的是投影点还原到原空间对应的坐标值重构出的图像)如下所示(选取第一个点为代表):
LLE降维
当数据具备某些非线性结构,如流形结构时,我们希望降维后的数据仍然保持这些结构。那么就提出了LLE降维算法。
LLE (Locally linear embedding):在数据降维后仍然保留原始高维数据的拓扑结构,这种拓扑结构表现为数据点的局部邻接关系。
此算法我们首先要寻求每个数据点的k个最近邻,然后将当前数据点用k个最近邻线性表出,那么就有相对的权重系数。
我们希望数据在降维后数据点之间依然能保持这种线性表出的关系,并且在满足另外一些约束条件的前提下,我们很容易求得降维后的数据。
具体原理和公式网络上有很多人整理得很好,这里不提了。
下面时LLE算法的算法流程,输入为p*N矩阵X,输出为d*N矩阵Y。矩阵的每一列都表示一个对象,每一行都表示对象的一个特征表示。
MDS和t-SNE
独立成分分析
独立成分分析的经典问题是“鸡尾酒会问题”(cocktail party problem)。该问题描述的是给定混合信号,如何分离出鸡尾酒会中同时说话的每个人的独立信号。当有N个信号源时,通常假设观察信号也有N个(例如N个麦克风或者录音机)。
等距特征映射
谱嵌入
深度学习(一些基本概念)
我所理解的神经网络,无非就是向量和矩阵做乘法,对得到的向量加一个偏置后,外嵌套一个激活函数,得到一个新的向量。对新的向量反复以上过程,就得到新的一层网络……最后的结果和最后的标签有偏差,我们通过链式法则等方式,调整权值矩阵,使偏差达到最小。训练多层神经网络的过程一般就叫做深度学习。
我们所需要考虑的细节就是矩阵的规模,激活函数选什么,内存处理等等问题。
深度学习中的一些基本概念。
一维卷积(离散)
对于一维卷积的理解,是在一次坐火车的时候。所谓的一维卷积,无非就是两列火车相向而驰,从头碰头,到尾离尾的过程。我们把两个向量比作两列火车,向量的元素比作每个车厢,那么两个向量做卷积得到的值的每个分量就是计算每个时刻火车重叠部分的点乘,所谓的点乘,就是对应位置做乘法最后求和。花了一点时间做了一个gif如下:
这里需要注意的是,两列火车的长度不定,更不一定等长,可能只有一节车厢,也可能有一列火车或者两列火车有无限长度。所以,卷积的长度=长火车的车厢数+短火车的车厢数-1。当然,也有的一维卷积只考虑计算短火车和长火车重叠部分包含短火车的时刻,即所谓的没有padding。当然,滑动步长也可以不是1。
二维卷积(离散)
理解了一维卷积,二维卷积不过只是在一维卷积的基础上,将一维向二维进行了扩充。即拿一个所谓的小矩阵(卷积核、滤波器)去按一定的顺序去扫原矩阵,每个“时刻”都计算矩阵的一个点积,得到一个数值。如下图所示:
可以看出,在从有数字的地方开始卷(没有padding)的话,且步长为1的话,卷出来的矩阵边长=大矩阵边长-小矩阵边长+1。
那么,这么多有什么意义呢?举个简单的例子,它可以提取边缘,如下:
padding
卷积网络,经常说padding,那么所谓的padding又是什么意思呢?一般来说,为了减少信息的丢失或者其他的一些目的。padding表示在原有向量或者矩阵的边缘上扩充地补一些数,比如说补0(zero padding)。padding有三种模式,valid、same和full。什么意思呢?
- **valid:**表示不填充,那么在二维情况下,那么它输出的size就可以表示为:
out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))
这个表达式中的 out_height 表示输出的高度,in_height表示输入的高度,filter_height 表示滤波器的高度,strides表示步长(两个维度)。width亦如是。
也就是说当步长为1时,如果用valid(不填充),那么做完卷积之后,矩阵的边的长度就会减小 滤波器的长度-1。如果步长不为1,卷到后面如果不够的话,后面的也不填充,直接drop掉。
举个例子,一维,输入长度为13,滤波器长度为6,步长为5。后面两个数字,不够滤波器长度,直接drop掉。
- **same:**所谓的相同,做填充,使得输出的特征图的空间维度和输入的特征图的空间维度是相同的(这里特征图的概念后面会讲到)。事实上,这句话只是对步长为1的时候的描述是准确的。
我们先来看看这个输出长度的表达式,再理解这个就简单了。
out_height = ceil(float(in_height) / float(strides[1]))
out_width = ceil(float(in_width) / float(strides[2]))
我们现在要做的就是,在两边均匀地填充,使得卷出来的输出满足这个长度。一般的填充,我们都是尽可能均匀地填充在两边,如果要填充的个数为奇数个,实在无法均匀地填充地话,我们一般选择让右边多填充一个。
很容易计算得到,我们需要填充的量为,以宽为例:max{filter_width-in_width%strides[2],0}
,百分号表示取余,特别地,in_width%1
的值为1,算得这个数字之后,平均分配到两边。
下面举几个例子:
1、步长为1,卷出来的规模和原来的相同,体现了same的含义。
从这也可以看出,如果步长为1的话,我们做卷积一般是让卷积核的中心放到最边上一个开始卷,这样的话,能保持卷出来的规模和原来的一样。但是如果步长不为1的话就不一样了,可以看下面一个例子。
2、一维,输入长度为13,滤波器长度为6,步长为5。因为13/6取上界为3,所以要做一些填充,使得卷出来的东西长度为3。这也体现了所谓的same。
- **full:**如图所示,设输入的大小是7x7,filter的大小是3x3,full型的padding就是让卷积卷出来的矩阵在不完全失去原有信息的基础上尽可能大,所谓的不完全失去,就是做卷积卷积核和原矩阵至少有一格的重复。
橙色部分为输入, 蓝色部分为filter。full模式的意思是,从filter和输入矩阵刚相交开始就做卷积,白色部分为填0。
反卷积(转置卷积)
好像要说清楚这个东西不是特别容易的事情。一句话解释就是:反卷积相对于卷积,像是一个逆过程,注意,这里说的逆,只是规模上的逆,而不是整整意义下恢复原来矩阵的逆,想想这也是不可能的。
转置卷积,把矩阵拉成向量来理解比较好理解。举个栗子:4x4的输入,卷积Kernel为3x3, 没有Padding / Stride, 则输出为2x2。这时,输入矩阵可展开为16维向量,记作x,输出矩阵可展开为4维向量,记作y。那么卷积运算可表示为y=Cx。事实上,C可以表示为如下:
那么,转置卷积是什么呢?没错,就是x=CTy。
矩阵拉成向量确实好理解了,但是它在原矩阵(向量)时,又是怎么样一种表现呢?能否可视化一下?二维比较抽象,以一维举个例子。考虑no padding,步长为1的卷子,看看它的反卷积是什么。因为:
由上描述,可知:
可以看得出来,这种情况下的反卷积,其实就是把卷积核倒过来,然后对输入做full_padding的卷积。这是没有步长的情况,我们再来看看有步长的情况。假设步长是2,依然是没有padding的卷积,我们来看看反卷积。
反卷积表示为:
我们找一下上面两种情况的规律,发现所谓的反卷积,就是把卷积核倒一下,对输入矩阵做一些0值得插补,最后做各种形式的卷积(same、full等)。我们把这个推广到二维,梳理一下过程如下:
- 首先是将卷积核反转(并不是转置,而是上下左右方向进行递序操作)。
- 再将卷积结果作为输入,做补0扩充操作,即往每一个元素后面补0。这一步是根据步长来的,对于每个元素沿着步长方向补(步长-1)个0。例如,步长为1就不用补0了。
- 在扩充后的输入基础上再对整体补0。以原始输入的shape作为输出,按照前面介绍的卷积padding规则,计算pading的补0的位置及个数,得到补0的位置及个数,得到补0的位置要上下和左右各自颠倒一下。
- 将补0后的卷积结果作为真正的输入,反转后的卷积核为filter,进行步长为1的卷积操作。
注意:计算padding按规则补0时,统一按照padding=‘SAME’、步长为1*1的方式来计算。
通过以上的介绍,我们已经基本了解了反卷积操作的过程,看下面几张图能够更好地帮助理解。
上图是步长为2的反卷积的一个图示,在蓝色内部补够0后,需要做到5的same padding,所以需要在蓝色外部也要做padding。这里灰色那个是卷积核,表示原卷积核的一个上下颠倒,左右颠倒。当然,反卷积还有很多更一般的情况,总结起来为一下几种:
反卷积,可以理解为卷积操作的逆运算。千万不要当成反卷积操作可以复原卷积操作的输入值,反卷积并没有那个功能,它仅仅是将卷积变换过程中的步骤反向变换一次而已,通过将卷积核转置,与卷积后的结果再做一遍卷积,所以它还有个名字叫转置卷积。
虽然它不能还原出原来卷积的样子,但是在作用上具有类似的效果,可以将带有小部分缺失的信息最大化恢复,也可以用来恢复被卷积生成后的原始输入。
学习率
就是梯度下降的步长。
反向传播
应用梯度下降方法,需要导数,求导数的方法,有反向传播,其实就是链式法则。
正则化
正则化是针对过拟合而提出的,正则化项是模型参数向量的范数,是为了降低模型的复杂度。一般的优化问题只是最小化经验风险,正则化是在此基础上加上模型复杂度这一项。并用一定的比率来衡量这一项的系数。加上这一项,可以防止模型训练过度复杂,有效的降低过拟合的风险。
避免过拟合,提高泛化能力的方法有:
- L1、L2正则化
- 早点停止训练
- 数据集扩增
- dropout
- 其他
正则化(Regularization)包括L1正则化、L2正则化。正则化其实就是在原有的loss funtion后面加上权重。
L2正则化(权重衰减)为:
对权重求导,可得:
这里体现了权重的一个衰减。
L1正则化为:
这个也可以做类似的求导。
L正则化,有点罚函数的味道,这里因为把权重加入到损失函数了,就尽量使得权重尽量小了。人们普遍认为:更小的权值w,从某种意义上说,表示网络的复杂度更低,对数据的拟合刚刚好(这个法则也叫做奥卡姆剃刀)。
参数服从拉普拉斯分布导出 L1 正则化,参数服从高斯分布,导出 L2 正则化。
softmax
softmax是一种归一化,它的好处就是使得计算上非常方便,谁用谁知道。
Softmax计算简单,效果显著,非常好用。它也能缓解局部极值的问题。
dropout
所谓的dropout,就是以一定的概率p(比如说0.5)先把隐藏层的部分节点藏起来(之所以叫藏起来,是因为与之相关的权重一直都在,只是不更新,下一次选择的时候,如果被藏的节点显示出来了,与之相关的权重还是保持原来的权重),变成一个比较小的网络,对于这个比较小的网络训练,训练到一定程度后,这些显示节点的权重有所更新了,这时候显示隐藏节点,重新以概率p进行选择……反复进行这个过程,知道训练好一个网络。测试的时候,用的是所有的节点,只不过权重得乘以p。
它的基本过程如下:
- 首先随机(临时)删掉网络中一半的隐藏神经元(备份被删除神经元的参数),输入输出神经元保持不变(图中虚线为部分临时被删除的神经元)。
- 对于修改后的网络,使用一小批训练样本去训练,按随机梯度下降法更新对应的参数。
- 恢复隐藏的神经元,包括恢复与它相关的原来的参数,重复上述过程(此时被删除的神经元保持原样,而没有被删除的神经元已经有所更新)。
dropout是一种有效的防止过拟合的方法,另外也是为了减少计算量。它是缓解过拟合的技巧之一。
dropout也是一种集成,如图:
它相当于训练时随机丢弃部分神经元,测试时整合所有神经元。dropout为什么能work呢?好像大家都没有一个很好的解释。简单地理解,有时候,老板交付的任务,两个人单独完成再整合,总比两个人一块做结果要好,有点“三个和尚没水喝”的意思,但也不是绝对的。
历史
随机梯度下降(mini-batch)
我们知道,在做有监督的问题中,有一个损失函数,用来衡量模型的好坏。在回归问题中,如果我们已经知道方程的形式,我们可以做出问题的损失函数。那么我们要做的就是寻找方程的最佳参数,即寻找参数,使得损失函数函数达到最小。乍一听,这就是个优化问题。当然可以对参数的各个分量求导,最后解方程组。问题是,你能确定最后的方程组好解?一般的数值解法有梯度下降法、牛顿法、拟牛顿方法以及信赖域方法等等。梯度下降方法简单易行,可是当数据量比较大时,梯度下降的计算就特别大。
为解决大数据量的优化求解,我们一般可以采用随机梯度下降。所谓的随机梯度下降,就是相比梯度下降,我们不选择全部的数据点,而是每次随机选择一个或者若干个数据点(一个数据点)来构建损失函数,接着再用梯度下降方法求解。看起来很不靠谱的样子,事实上多做几次这个操作,它是可以收敛的最优解的某个邻域的。
万有逼近定理
-
如果一个隐层包含足够多的神经元,三层前馈神经网络(输入-隐层
-输出)能以任意精度逼近任意预定的连续函数。 -
当隐层足够宽时,双隐层感知器(输入-隐层1-隐层2-输出)可以逼
近任意非连续函数:可以解决任何复杂的分类问题。
几种激活函数
常用激活函数如下:
白化
白化的目的是去除输入数据的冗余信息。比如训练数据是图像,由于图像中相邻像素之间具有很强的相关性,所以用于训练时输入是冗余的。白化的目的就是降低输入的冗余性。
所谓白化,就是对输入数据分布变换到均值为0,方差为1的正态分布,那么神经网络较快收敛。BN也是源于这个想法。
动量方法
梯度下降,一般是沿着当前点的负梯度方向走一小步,到下一点,又沿那个那个点的负梯度方向走一步,那么这样走走停停,无疑是走得很慢。
而一个真正的小球的下降要比这聪明多了,从A点滚动到B点的时候,小球带有一定的初速度,在当前初速度下继续加速下降,小球会越滚越快,更快的奔向谷底。momentum动量法就是模拟这一过程来加速神经网络的优化的。
它的基本算法如下:
最为关键的一步就是,走的步长vn(称为速度)是由当前的负梯度方向和前一步的速度vn−1做线性组合得到的。前一步的速度又和前前步的速度有关,以此类推,就把速度积累下来了。也就是说,当前的行走的方向和步长,还要综合考虑之前所有的走过的步的方向和步长。我们知道,不管是做傅里叶分析还是做半加速迭代,都习惯把之前的值做个加权平均,好像收敛就会快很多,monmentum好像就有点这个意思。它是为了解决一般SGD方法一直震荡而迟迟不收敛的情况。
动量方法有点像CG,要结合之前的信息。
交叉熵和KL散度
交叉熵和KL散度以及JS散度都是衡量两个分布(向量)的距离的一种度量。
交叉熵:
KL散度(KL距离,相对熵):
JS散度(JS距离,KL散度的变形):
batch normalization
所谓的batch normalization(批量归一化、批量正则化)就是“减去均值,除以方差”的标准化过程,比如一般正态分布变成标准正态分布。基本思想就是让每个隐层节点的激活输入分布固定下来,来提升训练速度。
它有什么用呢?它主要是为了**避免梯度消失,加速收敛。**把输入数据重新拉回到均值为0,方差为1的区域,这样让每层的输入落在(-1,1)区间,这段刚好是激活函数性能最好的区域。它是分布变得更加均匀,从而梯度方向更接近极值点方向,如下图:
另外,它也克服神经网络受不同初值影响较大的缺点。促进神经网络稳定性发展:使不同层相对独立,每一层可以专注解决本层的问题。
maxout
maxout是一种新型的激活函数,能够缓解梯度消失,规避了ReLU神经元死亡的情况,但增加的参数和计算量。它其实就是在原有激活的基础上,取个最大值,如下所示:
既然maxout是一个函数,那么它的输入,输出是什么?函数图像又是如何?
如果我们设置maxout的参数k=5,maxout层就如下所示:
相当于在每个输出神经元前面又多了一层。这一层有5个神经元,此时maxout网络的输出计算公式为:
z1=w1*x+b1
z2=w2*x+b2
z3=w3*x+b3
z4=w4*x+b4
z5=w5*x+b5
out=max(z1,z2,z3,z4,z5)
所以这就是为什么采用maxout的时候,参数个数成k倍增加的原因。本来我们只需要一组参数就够了,采用maxout后,就需要有k组参数。
上采样和下采样
下采样就是变小输入,上采样就是就是变大矩阵,有点“插值”的意思。
一般来说下采样指的就是池化。上采样包括unpooling和转置卷积(transpose convolution)和一般的插值等。unpooling就是反池化,在池化过程中,记录下max-pooling在对应kernel中的坐标,在反池化过程中,将一个元素根据kernel进行放大,根据之前的坐标将元素填写进去,其他位置补0 。
池化
池化对特征图的每个局域进行下采样,作为这个区域的概括。池化包括平均池化mean-pooling和最大池化max-pooling。所谓的池化,其实就是讲输入分块,对每块去平均值或者最大值。
预训练
假设你想要解决一个复杂的任务,你没有太多的标记的训练数据,但不幸的是,你不能找到一个类似的任务训练模型。 不要失去所有希望! 首先,你当然应该尝试收集更多的有标签的训练数据,但是如果这太难或太昂贵,你仍然可以进行无监督的训练。 也就是说,如果你有很多未标记的训练数据,你可以尝试逐层训练层,从最低层开始,然后上升,使用无监督的特征检测算法,如限制玻尔兹曼机(RBM)或自动编码器。 每个层都被训练成先前训练过的层的输出(除了被训练的层之外的所有层都被冻结)。 一旦所有层都以这种方式进行了训练,就可以使用监督式学习(即反向传播)对网络进行微调。
然而,貌似主流的深度学习平台甚至都不支持RBM和预训练。所以,不必深究。
预训练在没有太多工具的情况下,能够解决梯度消失和局部极值,训练困难,训练时间长等问题。但它本质上无法解决梯度消失的问题。
自编码机
自编码器其实是通过神经网络,学会重构自己的过程。
自编码器(autoencoder)假设输出与输入相同(target=input),是一种尽可能复现输入信号的神经网络。将input输入一个encoder编码器,就会得到一个code,加一个decoder解码器,输出信息。通过调整encoder和decoder的参数,使得重构误差最小。它是一种非监督学习,因为无标签数据,误差的来源是直接重构后信号与原输入相比得到。
梯度消失(爆炸)和局部极值
所谓的梯度消失,具体来说,由于在向后传递过程中,sigmoid向下传递的梯度包含了一个f’(x) 因子(sigmoid关于输入的导数),因此一旦输入落入饱和区,f’(x) 就会变得接近于0,导致了向底层传递的梯度也变得非常小。此时,网络参数很难得到有效训练。这种现象被称为梯度消失。一般来说, sigmoid 网络在5 层之内就会产生梯度消失现象。Relu函数可以有效缓解这种情况。
反之,如何激活函数导数乘以很大的神经网络权重参数w,那么因为乘积大于1,就会发生梯度爆炸现象。
局部极小值很好理解,因为近似的函数非凸,就容易陷入局部极值。
Flatten
Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。其实就是把矩阵拉成一条。
特征图
在做二维卷积中,用滤波器卷一次得到的结果就是一个特征图,不同的滤波器,做多次卷积操作就会得到多个特征图。滤波器就是卷积核。
强化学习
强化学习到底是什么?若是想略微了解强化学习大概的意思和操作,把握一个主干知识,而不做深入研究,看这篇文章就很够了。
核心内容
元素简介
强化学习考察的是对于一个对象(智能体),从一个状态执行某种动作到下一个状态,并在这个过程中,给其一定的奖赏或者惩罚,是它尽可能往好的方面去做。就像马戏团的驯养师,对其宠物,若其表现好,就给它一点吃的,若其表现不好,就抽它两鞭子,使得它最后,能够有一系列出色的表现。
为了说清楚这个问题,我们需要介绍一下状态空间S、动作集A、状态转移概率P和奖赏R。
如图所示,状态空间表示所有状态的一个集合,动作集表示所有动作的一个集合。
状态转移概率是一个函数,表示在当前状态s下,执行某个动作a之后,转移到某个状态的概率,即P:S×A×S↦R指定了转移概率。举例比如说状态s1下,执行动作a1,可能转移到s1,也可能转移s2,二者概率不同。图示s2也是可以以一定的概率执行相应的动作,执行相应的动作,都以一定的概率转移到不同的状态,为了图示简明,没有画出来。
R:S×A×S↦R指定了奖赏。这个奖赏不仅跟起始状态和动作有关,也和动作执行后达到的状态有关。
还有一个是策略函数π,它表示给你一个状态,你应该要执行什么动作,当然,如果你执行的动作不确定,而是以一定概率执行相应的动作,那么π其实就是对应于动作的概率函数,即用π(s,a)表示在状态s下选择动作a的概率。要有∑aπ(s,a)=1。
优化目标:状态值函数
给定一个策略π(这个策略不一定是最优的),那么对于执行动作的步数有限(设为T步)和无限的时候,我们分别定义状态值函数:
{VTπ(s)=Eπ[T1∑t=1Trt∣s0=s]Vγπ(s)=Eπ[∑t=0+∞γtrt+1∣s0=s]
这个状态值函数的意思就是在当前状态s下,平均累积奖赏的一个数学期望,它是一个函数,对于不同的状态s,它有不同的值。当步数是无穷的时候,我们定义一个折扣因子γ,使得距离越远的地方,奖赏的对累积
以上是关于3w+深度盘点:机器学习面试知识点梳理!的主要内容,如果未能解决你的问题,请参考以下文章
一周精选技术小文:Python 深度学习框架回顾;机器学习中的数学知识;52 个有用的机器学习与预测 API 盘点