2019年2月10日星期日

why-what-how方式的机器学习总结之三

采样方法


why


采样方法最常用的场景是用来求一些不好计算原函数的积分,或者求一些分布的期望值,关键词蒙特卡洛积分。













比如上面这张图,正方形的面积很容易知道,计算绿点占所有采样点的比例乘以正方形面积就可以得到f(x)曲线下方的面积也就是f(x)从a到b的定积分。

还可以从期望的角度来看采样法,假设g(x)不好求积分,令





把g∗(Xi)看成新的独立同分布的随机变量,其密度函数是fx(x),所以可以得到期望,






再由大数定理期望等于均值,





所以只需要按照分布fx(x)大量采样求均值就可以得到g(x)的积分。

这个地方fx(x)是我们自己变换出来的,所以可以随意选择,我们可以选择成在区间[a,b]上的均匀分布,那么剩下的就容易解决了。详细可看蒙特卡洛(Monte Carlo)法求定积分

如果要求一个分布的期望,可能就需要直接对目标分布进行采样,而这是一个难点,所以会有很多采样的方法,比如逆采样,接受-拒绝采样,重要性采样,MCMC采样以及吉布斯采样等等。

what


1.逆采样(Inverse Sampling)

逆采样是想通过均匀分布变换目标分布的采样,如下图


(1)如左图纵坐标,从 Uniform(0,1) 中随机生成一个值用 u 表示。

(2)计算的值 x,则 x 就是从 f(x) 中得出的一个采样点。这个过程就是上图中红线表示的,F(x)是累积分布函数CDF。

更多细节参考逆采样(Inverse Sampling)和拒绝采样(Reject Sampling)原理详解,数学原理可以参考维基百科,这里不展开了,逆采样需要能求CDF的反函数,有时候会很困难。

2.接受-拒绝采样












如上图,红色的p(x)可能采样太困难,我们找一个比较好采样的函数q(x),并且让kq(x)的曲线能包住p(x)。采样过程,
(1)x 轴方向:从 q(x) 分布抽样得到 a。
(2)y 轴方向:从均匀分布(0, kq(a)) 中抽样得到 u。
(3)如果刚好落到灰色区域: u > p(a), 拒绝, 否则接受这次抽样。
(4)重复以上过程。

在高维的情况下,Rejection Sampling 会出现两个问题,第一是合适的 q 分布比较难以找到,第二是很难确定一个合理的 k 值。这两个问题会导致拒绝率很高,无用计算增加。

3.重要性抽样(Importance sampling)

和接受-拒绝采样类似,也是通过较容易采样的分布来解决问题。









如上图对p(z)做了简单的变换,采样的目标分布是q(z),可以吧p(z)/q(z)看成一个样本点的重要性。

这种方法的问题是在高维空间里找到一个这样合适的 q 非常难。更详细的可以看随机采样方法整理与讲解(MCMC、Gibbs Sampling等)


4.MCMC(Markov Chain Monte Carlo)

MCMC采样的基本原理马尔科夫链和马尔科夫稳态的基本原理可以看随机采样方法整理与讲解(MCMC、Gibbs Sampling等),这里只整理一下基本逻辑。

(1)样本按照某个转移矩阵P不断进行转移跳转,最终一定会到达一个马尔科夫稳态再进行跳转也不会发生变化,要求这个转移矩阵P的任意两个状态都是连通的。

(2)马尔科夫稳态有一个特点是满足细致平稳条件,一般的转移矩阵是不太会满足这个条件的,所以我们想把一个一般的转移矩阵P改造得满足细致平稳条件。

(3)改造的方法是按照对称性制造一个接受矩阵,按一定的接受率接受跳转。

(4)实际工作方式按个人理解是采样的过程是先初始化n个采样点,然后对每个采样点做马尔科夫跳转,这个跳转是指转移到其它的状态,而这个跳转概率在我们要求的转移矩阵里面,直到最后不再跳转为止,跳转的方法由细致平稳条件推出的那个跳转公式来决定。

(5)上面的方法存在一个问题是可能会拒绝大量的跳转导致收敛太慢,所以MH方法来优化这个过程。MH方法只是放大了接收率。

(6)实际应用中高维数据很常见,高维下如果固定一个维度做跳转是能满足细致平稳条件的,所以就有了轮换固定维度跳转的Gibbs Sampling,应用非常广泛。

主题模型


why


我们希望机器学习能帮我们自动理解一篇文章,最简单的观点是把文章看成一组单词的无序组合,这个就是词袋模型(BOW)。但是BOW实在太简单,稀疏生僻词,一词多义,同义词等等问题都无法描述,所以我们在词袋模型中引入了主题(Topic)这个概念,认为一篇文章在描述多个主题,每个主题又包含多个单词。

主题模型这里主要记录一下,LSA,PLSA和LDA。之前我认为可以用主题模型搞定评价的标签词分析的,后来发现不合适,评价这样的每篇文档都太短,而且标签词实际上是短语。

what


1.LSA(潜在语义分析)

LSA的工作方式是对Term-Document矩阵做SVD分解,详细可参考LSA,pLSA原理及其代码实现,感觉还是比较简单粗暴,有不少问题,比如一词多义就无法解决。

2.PLSA(概率潜在语义分析)

和LSA不同,PLSA是一种概率模型。PLSA是这样看一篇文章的生成过程的,首先找k个主题,然后对于每个主题按照主题-词语的概率随机生成多个词语,所有这些词语组成文章。

可以看到PLSA并没有考虑词语的顺序以及位置等关系,所以还是词袋模型。这个模型里面doc-topic是随机选择的而topic-word是个多项分布也是我们需要求解的。

每个词语的生成概率是,






对于第m篇文档的n个词语的生成概率是,





有了文档的概率就可以写出最大似然函数然后用EM方法求解了,详细的可参考LDA数学八卦

3.LDA(Latent Dirichlet Allocation)

PLSA是属于频率学派的模型而LDA是属于贝叶斯学派的模型。在PLSA里面文档对应的主题θ,主题对应单词φ都是模型的参数,这些参数都是有确定的值我们求解这些值就可以了。在LDA里面θ和φ都是概率分布,那它们的概率分布是什么呢?由于在PLSA里面θ和φ都是多项分布的参数,所以对应到贝叶斯模型在LDA里面 θ和φ 的先验分布就可以选多项分布的共轭分布Drichlet分布。

LDA一篇文档生成过程大致如下,

(1)通过Drichlet分布(参数α)生成doc-topic多项分布的参数θ。
(2)接下来生成一个词,先用多项分布(θ)生成一个topic编号z。
(3)通过Drichlet分布(参数β)生成k个topic-word多项分布的参数φ1...φk。
(4)挑选出参数φz,然后用多项分布(φz)生成一个词。
(5)重复步骤2和4生成n个词,注意步骤3不用重复做。
(6)生成新的文档的时候需要重做步骤1。

这整个过程中有M+K个独立的Dirichlet-Multinomial共轭结构,其中M对应M篇文档,K对应所有M篇文档相关的K个topic。模型的图解如下。












M篇文档中topics的生成概率是









M篇文档中词的生成概率是









联合概率是







有了联合概率就可以用EM法来求解了,不过解起来相当复杂还需要用到变分法,另一种方法就是用吉布斯采样来解。吉布斯采样的目标是估算模型中的参数φ1...φk和θ1...θm,注意不是α,β,它们是先验参数可以预先指定。

采样的过程如下,
(1)随机初始化,对语料中每篇文档中的每个词随机赋予一个topic编号z。
(2)重新扫描整个语料库,按吉布斯采样公式重新计算topic并在语料库中更新。
(3)重复上面的过程直到收敛。
(4)统计语料库中topic-word共现频率矩阵,就可以得到我们需要估算的参数。

 如果来了一篇新文档需要我们分析对应的topic,那我们只需要求参数θ,同样可以用吉布斯采样过程直到收敛,然后统计文档中的topic分布就能得到θ。

最后剩下的是吉布斯采样公式,就只记录结果了,详细推导过程可以看LDA数学八卦






神经网络和深度学习


why


神经网络要解决的问题和一些基础的机器学习方法相同,也主要是分类问题和回归问题。不同的地方是像逻辑回归,朴素贝叶斯这些本质上来说都是线性模型,而n维线性模型的vc维是n+1也就是说要增加模型的容量只能增加维度。而神经网络尤其是深度神经网络是非线性的,神经网络的vc维是每一层的节点数(维度)的乘积,所以增加神经网络的深度可以很轻易的获得非常高的模型容量,这也是深度学习很火的重要原因。

what


1.神经元是组成神经网络的基本单位,如下图(来自神经网络--反向传播详细推导过程)








这个神经元是以x1,x2,x3以及b=1作为输入的运算单元,其输出是



其中f被称作激活函数,比如可以用sigmoid函数作为激活函数,当使用sigmoid的时候这个神经元实际上是在做逻辑回归。激活函数还有其他的选择,详细可参考《深度学习》,6.3节。

2.多个神经元联接起来就可以组成神经网络,










上图中的输出是单个值,输出也可以是多个值组成一个向量。

3.前向传播,就是通过输入得到输出以及网络中任意一个节点值的过程,比如上图中的神经网络就可以这样计算,







4.反向传播(详细可看深度学习:神经网络中的前向传播和反向传播算法推导),是指在训练的时候把训练误差反馈到神经网络的权值参数矩阵的过程。比如下面的网络,
















每个权重对误差的影响可以通过下图直观的看到,主要也就是一个链式求偏导数的过程,












how


1.神经网络这个牛逼的名字是怎么来的?可以看看这篇科普神经网络浅讲:从神经元到深度学习,神经网络的神经元确实有点模仿人脑神经元的结构,输入可以类比为神经元的树突,而输出可以类比为神经元的轴突,计算则可以类比为细胞核。还有一点仿生的地方在激活函数,激活函数也像人脑神经元一样达到某个临界状态后就一直处于工作状态,否则就一直是休眠状态。再有就是神经网络的反向传播机制也和人脑的反馈机制比较相似。

2.为什么有激活函数?除了仿生之外激活函数在神经网络中的功能即通过对加权的输入进行非线性组合产生非线性决策边界。

3.神经网络牛逼的理论依据?万能近似定理(universal approximation theorem)(Hornik et al., 1989;Cybenko, 1989) 表明,一个前馈神经网络如果具有线性输出层和至少一层具有任何一种‘‘挤压’’ 性质的激活函数(例如logistic sigmoid激活函数)的隐藏层,只要给予网络足够数量的隐藏单元,它可以以任意的精度来近似任何从一个有限维空间到另一个有限维空间的Borel 可测函数。详细可见《深度学习》6.4.1节。

4.为啥需要深度神经网络?这个用vc维可以解释,如果用浅层的神经网络描述精度要求非常高的函数可能需要的隐藏单元的数量是指数级,深度神经网络可以把指数化简到深度。

5.深度学习仅仅就是深度神经网络么?答案当然是no,深度学习有三个核心概念,多层组合,端到端学习以及分布式表示,参考深度学习究竟是个啥?。多层组合比较好理解,神经网络就是一种多层组合。端到端学习是指不用做特征工程,由算法自动学习数据中的特征,卷积神经网络就是一个典型的例子,只用给原始的图像二进制数据和最后需要的分类结果就可以了。而分布式表示则需要重点说一下。

6.分布式表示,比如“你有一辆大的蓝色福特汽车”用分布式表示就是尺寸+颜色+品牌,我个人的理解就是一种正交的本质的表示方式。因为深度学习可以用函数复合的方式来实现分布式表示,我突然想到函数式编程也是这么个玩法,函数式编程也是能做到高度的抽象能提炼出系统本质的东西,主要的区别是函数式编程是靠人去建立这种分布式表示吧。

7.那怎么学习到分布式表示呢?《深度学习》 里面说k-means,决策树,高斯混合模型等等都不是基于分布式表示的学习算法。有一种里程碑式的学习算法叫无监督预训练,简单的说就是多层训练,每一层用自编码器或者受限玻尔兹曼机自动抽取特征,然后把上一层的输出作为下一层的输入。具体可以看《深度学习》15.1节以及浅谈深度学习分布式表示以及不同结构

8.深度神经网络的Batch Normalization(详情见Batch Normalization导读)
(1)深层神经网络的在层次较深的地方输入会逐渐靠近极大和极小值使得梯度消失,BN就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布。
(2)变换的结果是让梯度变大,但是又可能会让函数接近线性化使得多层的意义减弱,因为多层线性网络和单层线性网络等价,所以BN对每层又会做调整y=scale*x+shift,来综合梯度和线性问题,这一步非常非常关键,而且scale和shift都是要通过学习得来的又叫变换重构

9.tf.clip_by_global_norm,是一种处理梯度爆炸或消失的一种方法,实际上就是每层传播的时候对梯度进行缩放,然后按照这个缩放的比例之后去更新参数,详细可见 tf.clip_by_global_norm理解



卷积神经网络(CNN)


关于CNN,这篇吴恩达的课程笔记第四门课 卷积神经网络,写得非常清楚详细,我简单的做一下摘要帮助快速索引。

why


CNN最典型的应用是图像识别,比如图片分类判断一张图片是不是猫。那为什么不用普通的深度神经网络来做呢?这就要提到CNN的三个重要特点参数共享,稀疏连接和等变标识。

1.参数共享是说CNN会用一个过滤器处理图像中所有的部分,比如下图中的3×3的过滤器检测垂直边缘。










2.稀疏连接如下图,绿圈这个0是通过3×3的卷积计算得到的,它只依赖于这个3×3的输入的单元格,右边这个输出单元(元素0)仅与36个输入特征中9个相连接,红圈这个30也是这样。而且其它像素值都不会对输出产生任影响,这就是稀疏连接的概念。这个和普通神经网络对比很鲜明,普通神经网络是全连接的,也就是说下一层中的一个值会和上一层所有的值发生连接。











3.等变表示指的是,图像中某一元素/成分的移动,在上层神经元中也表现为一定的移动。这是由参数共享直接带来的,因为移动过程中卷积核的参数不变。这种等变表示使得图像的平移不会对分类预测结果产生太大的影响,使得学习算法能够对相同内容不同位置的图像较为准确的识别。

what


1.卷积的概念,知乎上一个比较通俗的解释是加权叠加,一个更通俗的理解是以一个固定的速率殴打某人,那他承受的伤害就是一个叠加的过程。稍微数学一点的理解可以看如何通俗易懂地解释卷积?。实际上加权叠加的理解对于CNN就基本够用了。

2.卷积核,就是指过滤矩阵,比如下图就是一个用于检测图片边缘的卷积核,卷积核的作用在于特征提取因为做了加权求和所以突出了一些重点。










3.Padding,因为卷积操作会让图像变小丢失一些信息,所以需要在原始图像周围填充一圈默认值。

4.卷积步长,是指卷积操作一次移动几个格子,这个比较直观。

5.池化层,用来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性,也比较直观,比如下图是最大池化的例子。







6.Dropout,是正则化的手段的一种为了提高模型的泛化能力,直观的理解就是以一定的概率关闭某些神经元,如下图。








举个小栗子吧,假如有两个特征,有一只耳朵,有尾巴,假如这两个特征同时出现的时候,能判定它是一只猫,当只有有尾巴这个特征的时候,也能判定它是一只猫,但只有有一只耳朵这个特征的时候,就不能判定它是一只猫,那神经网络就知道有一只耳朵这个特征在分类是否是猫这个问题时,是个冗余信息,那分类的时候就不用它了嘛(来自(CNN)卷积神经网络(四)dropout)。

7.全部放一起的一段代码表示,
stride = 1  # output is 28x28
Y1 = tf.nn.relu(tf.nn.conv2d(X, W1, strides=[1, stride, stride, 1], padding='SAME') + B1)
stride = 2  # output is 14x14
Y2 = tf.nn.relu(tf.nn.conv2d(Y1, W2, strides=[1, stride, stride, 1], padding='SAME') + B2)
stride = 2  # output is 7x7
Y3 = tf.nn.relu(tf.nn.conv2d(Y2, W3, strides=[1, stride, stride, 1], padding='SAME') + B3)

# reshape the output from the third convolution for the fully connected layer
YY = tf.reshape(Y3, shape=[-1, 7 * 7 * M])

Y4 = tf.nn.relu(tf.matmul(YY, W4) + B4)
Ylogits = tf.matmul(Y4, W5) + B5
Y = tf.nn.softmax(Ylogits)



循环神经网络(RNN,LSTM)


why


RNN适合处理序列类型的数据,比如,当我们在理解一句话意思时,孤立的理解这句话的每个词是不够的,我们需要处理这些词连接起来的整个序列; 当我们处理视频的时候,我们也不能只单独的去分析每一帧,而要分析这些帧连接起来的整个序列。

CNN不太适合处理很长的序列问题,因为CNN擅长的是捕捉局部的相邻的特征,距离较远的关联信息CNN不太适合处理。在循环网络中使用的参数共享的前提是相同参数可用于不同时间步的假设,这个关系应该不随时间去改变。

RNN当序列较长的时候有梯度消失的问题,所以就出现了LSTM。

what


1.RNN可以用下面这张图来表示,









RNN最关键的是在模型中加入了状态S然后状态可以随着时间传播下来所以有了记忆功能,整体的定义如下









2.梯度爆炸和梯度消失(详细可看LSTM原理分析)





上面的式子是误差传递的过程,可以看到后面的连乘项对一个结构反复相乘,如果这个结构的值大于1就是梯度爆炸,反之就会梯度消失。

3.LSTM的解决方案是原始RNN的隐藏层只有一个状态,即h,它对于短期的输入非常敏感。那么,假如我们再增加一个状态,即c,让它来保存长期的状态,那么问题不就解决了么?如下图所示:







按照时间维度展开








加上输入门和遗忘门来控制c的内容就有了这张经典图











详细的分析可看深度学习笔记(八)LSTM长短期记忆网络









没有评论:

发表评论