Machine Learning Techniques Lecture 12: Neural Network | Cheney Shen

Technology blog

Machine Learning Techniques Lecture 12: Neural Network


 
 

内容:

Neural Network模型,出发点是把原来的perceptron变成更多层来达到越来越复杂,越来越powerful的效果,这样的链接在生物学上模仿的就是神经元的连结。在NN里面一个网络w固定了的话就是一个hypothesis,每一层做的事情就是根据这些权重来萃取pattern,一层一层萃取出来到最后一层是直接输出。NN学到这些权重的基本方法就是gradient descent(GD),透过backprop的方去很快的算这些梯度到底是多少。最后讲到这样的基本模型还需要小心的是怎么去初始化,用什么regularizer,以及透过early stopping的机制来避免overfit。

 
 


 
 

上一讲:

Gradient Boosted Decision Tree 模型透过 functional gradient 的方式去得到一棵棵不一样的树,然后再给每一棵树以 steepest descent 的方式得到其对应的权重,合起来以后可以做到处理任何的error measure。

 
 

这一讲:

Neural Network

 
 


 
 

我们已经学过了 Perceptron 模型,就是把你的输入乘上一堆权重算出一个分数,然后判断这个分数大于0就是正一,小于0就是负一。

 
 

如果我们今天把一堆 Perceptron 用 linear aggregation 的方式组合起来的话,就如上面的图所示,从输入出发,乘上第一组的权重得到g1,乘上第二组权重得到g2,以此类推得到一堆的 Perceptron,之后各个g乘上各自的权重alpha,组合起来得到最后的G。

 
 

数学表达式如右边所示:

这个过程里面有两组权重,第一组是从输入乘上对应的权重得到一堆的g,权重是w_t;第二组是g_t投票的权重alpha_t。

这个过程里面还有两次取sin的过程,第一次是得到g,第二次是得到G。图示中使用红色的阶梯函数来表示这个动作。

 
 

这样的模型到底可以做到什么样的边界。

 
 


 
 

例如如图所示,我们有两个 perceptron g1 和 g2,把两者通过 linear aggregation 合起来可能可以做到右边图所示的结果。然后我们构造了下面的图示的函数,公式就是下右表示的那样,其G所描述的就是和上面所述的AND是一样的。

 
 

也就是说我们在第一层g上面构造一些些逻辑运算,到第二层的时候就可以得到比较复杂的边界,比如上面的AND就已经不是线性边界了,OR,NOT也可以类似的得到。

 
 


 
 

linear aggregation of perceptron 是非常 powerful 的,非常复杂的。

 
 

比如上面的例子,我们的目标是一个圆圈圈,园内是1,圆外是-1,如果用单一的perceptron就可以切出左图所示,16个的话就如中间所示的图,最终的目标是使用一堆的perceptron来逼近得到平滑的边界。也就是说我们可以任意的切出二维平面内的凸多边形,这时候的Dvc是无限大(以前有过证明),也就是说能力足够。

 
 

但是还是有做不到的事情,比如 XOR(有且只有一个true) 就做不到。我们把g当作是资料空间转化,在我们转化完以后,资料还是线性不可分的,这时候就没有办法做到。

 
 

那我们要怎么做到 XOR ?

 
 


 
 

转换一次得不到好的结果,那就得再来一次转换。

 
 

比如上面XOR的例子我们考虑两层的转换,第一层做AND,第二层做OR,这样转换的得到的就可以线性分割,就可以得到XOR的结果,图示如上面。

 
 

这里我们的perceptron就开始分层了,这就是我们这一课要讲的神经网络的基本长相。单一的 perceptron 比较简单,多个 perceptron 比较复杂,这里我们迈向更加复杂的 multi-layer perceptron。

 
 


 
 

这种层次化的perceptron组织方式一开始就是学习生物学的神经元信息处理的方式得来的,神经元对应到node,他们之间有传递关系就用权重代表,最后都会得到反馈,就是生物工程的抽象化结果。

 
 

只是模仿,不是模拟!

 
 


 
 

练习

 
 


 
 

上面讲的就是一个简单的神经网络的运作过程,我们从输入出发,经过一层一层的运算,最后一层得到输出。从数学上可以看作是对原始的输入做一次再一次的特征转换,最后通过最后一层的权重去算一个分数,然后输出结果。

 
 

我们可以看到在输出层其实就是一个线性的模型,我们学过的 linear classification(线性分类)/ linear regression(线性回归分析) / logistic regression(软性的分类) 这些线性的分类器都可以放入到这个网络里面。下面为了讲解简单,我们采用 linear regression 方法来讲,你可以轻易的延伸到其它的方法。

 
 


 
 

上面讲了输出的部分,这里说中间的部分,中间的每一步每一个节点都是在做转换。在转换的时候我们应该采用什么样的函数呢?

 
 

如果你每个节点用的都是线性函数,那么整个网路就是一个线性函数,那你直接用一个线性函数替代整个网络就可以了。

如果你每个节点用的都是阶梯函数,是离散的,很难最佳化。

 
 

因此最为常用的就是平滑的s型函数,其中最为代表性的就是 tanh(t) 函数。

 
 

图示和公式如右边,大范围的时候和阶梯函数接近,小范围的时候和线性函数接近,整体上就是大概的逼近我们原来采用的sin函数。这个函数是连续的,最佳化比较容易。tanh(s) = 2 theta(2s) -1 :就是两倍的原来logistic regression函数取2s再减去1的结果。也就是原来的logistic regression函数做放缩平移后的结果。

 
 


 
 

然后我们来描述下我们要讲的 Neural Network Hypothesis 长什么样。

 
 

如果我们固定了hypothesis的一些参数以后,我们就能从一开始的输入得到最终的输出。中间则每一层都是根据前一层的输出当作是输入,再乘上相应的权重之后,得到这一层的输出当作是下一层的输入,直到最后一层直接输出。

 
 

我们把第一次处理叫做第一层,第二次处理叫做第二层,以此类推,输入的部分叫做第0层,层数用L表示。输入层是0 – d-1层,输出层就是 1 – d 层。这样以后这个过程就可以用公式表示出来如上面所示。紫色的 S_j^L 表示的是 第L层第j个节点的输入,红色的 X_j^L 表示的是 第L层第j个节点的输出,除了最后一层其他层都需要做tanh转换再输出出去。

 
 

绿色框框的标题


表示的是我们用每一层有多少个节点来描述这个神经网络。

 
 


 
 

这网络的物理意义:每一层做的事情就是转换,权重就是从资料里面学习得来的。也可以看作是把前一层的结果x向量 和 这里的权重向量 的内积是不是比较一致,如果两个向量比较重合,则表示两者比较接近。

 
 

NNET :每一层在做 pattern extraction,每一层都是从资料中找出潜藏的模式,一层一层的把这些模式做转换匹配,看是否相似。

 
 


 
 

练习

 
 


 
 

如果我们已经有一组特定的权重的话,NN做法就是从输入开始就是一层一层的透过w和tanh来得到一层一层的输出变成下一层的输入一路计算下去,直到最后一层不做tanh而是直接输出。

 
 

现在问题是怎么学习得到权重?

 
 

如果你的网络只有一层,学习的方法我们就已讲过了,就是aggregation of perceptrons。我们可以用 Gradient boosting 每次加一个节点(神经元)进来,一个一个加直到你觉得结果可以为止。

 
 

但是现在你有很多层的话,这个可能就行不通了。现在进过很多层以后最终一定是有一个结果输出,我们希望输出的结果和y是接近的。所以我们可以定义类神经网络的输出结果和y的错误平方是e_n,如果我们可以知道这个e_n和网络中的每个w的变化关系(就是 e_n/w 的偏微分),就可以用 GD/SGD (梯度下降)的方法来一步一步做最佳化。

 
 

因此关键点就是我们怎么算出这个 e_n/w 的偏微分?

 
 


 
 

我们来看怎么计算 平方错误 对于 每一个w 的偏微分。我们从错误对于最后一层的偏微分开始处理,也就是L这一层(输出层),神经元的数量是1,前一层的神经元数量则是i,最后用 W_i1^L 表示。

 
 

为什么从最后一层开始,e_n表示的是我们的观察结果和网络输出结果的比较误差的平方,网络的输出就是最后一层的输出,因此公示网络输出的部分可以替换为 S_1^L (就是L层1节点的输出),就是这一层权重的和。如上面黄色框表示的公式那样,整个关系就是从权重到分数到错误表示的过程链。

 
 

有了这个我们再来看权重和错误的偏微分,就可以用微积分里面的连锁律(就是依靠中间人分数S)就可以轻易的求解。【绿色框所示】,会求解了最后一层,我们再来看前几层,做法也是类似的方式求解,只是其中的分数没有那么容易求解出来,所以先使用delta来表示,delta_j^L 表示的是L层第j个节点的错误相对于分数的变化量【红色框所示】。

 
 

有了delta的定义,前面绿色框里面的delta_1^L就是一个特殊的可以求解的结果,表述如上面PPT所示。我们怎么来求解其他的delta呢?

 
 


 
 

我们来看delta怎么计算,那么我们先来分析一下这个分数怎么会影响到最后的错误e_n。在类神经网络里面,这个分数再经过神经元的转换变成神经元的输出,就是s变成x,然后再经过下一层的权重变成很多不同的神经元的分数,一路以此类推,最后最后才得到e_n。【上面黄色框所示】

 
 

所以我们来看蓝色的s和错误e_n的关系,他们俩之间的中间人很多层,每一层还好几个。因此如果在这么复杂的式子上面用连锁率,可以有蓝色框所示的内容(把中间人的影响要全部加起来),求解后用delta表示的结果如上。

 
 

这个结果表示的是,如果你今天后面那一层的delta你知道是多少,那你就可以推导得到前面那一层的delta的解。同时我们还知道最后一层的delta的结果,因此可以一路往回推得到所有的结果。【绿色的部分可以求解】

 
 

同时你还需要知道蓝色部分的解,tanh的微分可以直接求解【蓝色部分可以求解】

 
 

至此你就可以求解出所有的w,就可以总结出计算w的演算法。

 
 


 
 

算法叫做 Backpropagation (Backprop) Algorithm:

 
 

一开始随便设定一些权重w_ij,每一次

  1. 【Stochastic】随机选一个点算他的梯度是多少,这个梯度可以拆解成两项,一项是x,一项是delta,所以每一个权重他的更新量就和它前一层时候的x和这一层的delta的变化量有关。要更新我们就需要算出红色的值和蓝色的值。
  2. 求红色的值,把资料喂进去,一层一层的求解。
  3. 求解delta,倒着算回来,上面讲的那样。
  4. 【Gradient descent】更新w_ij

更新了足够轮的时候,每一个w_ij就应该在一个比较好的范围内了,让Ein比较小了,就把结果回传形成神经网络模型。

 
 

你每次选择一个点,你都需要从前向后算得到x,从后往前算结果得到delta,才能球解一个,感觉时间会很久。实际操作的时候,第一步到第三步可以并行的做,然后我们把这些并行结果去平均梯度结果来更新第四步,可以加速运算,这个做法叫做 mini-batch。

 
 

这就是基本的类神经网络算法。

 
 


 
 

练习

 
 


 
 

上面介绍了NN里面最佳化的基本方法,其关键就是通过GD的方式去最佳化Ein,Ein包含的是原始的输入一层一层处理最后得到的输出和y在某个错误衡量上的比较结果。这里讲的是NN常用的一些优化方法。

 
 

上面的例子是平方错误衡量,你可以替换使用其他错误衡量。我们这边的重点不是错误衡量,而是在讲经过了那么多层tanh的转换,使用GD来得到的可能是局部最低谷(就是好多山峰的中间的山坳,而不是真的全局最低谷)。

 
 

也就是说NN不是简单的像单层的二次曲线求山谷谷底(non-convex)就是全局最优,而是有多个山峰山谷,你从当前点出发得到的是局部最优。换个角度就是说你从不同的起点出发,你可能得到不一样的局部最优解。

 
 

那有什么技巧可以让我们避免不好的山谷呢?

 
 

我们来看tanh函数,前面有图示意其函数,在两头权重很大的时候,其x的变化带来的y的变化量非常小,如果在这里每次走一小步,你走老半天也可能是原地踏步。所以一开始你需要一个小一点的随机权重,这样你不会卡住走不动,随机则意味着你可以走到不同的山谷。

 
 

NN不是一个容易的最佳化问题,里面包含很多技巧去尝试。

 
 


 
 

我们来看看这个模型的复杂度,大概的结果是 Dvc = V(神经元的数量) * D(权重,就是图中连线的数量),也就是说图的节点和连线越多,这个NN的能力(Dvc表示)就越强,但是就越容易overfit。

 
 


 
 

避免overfit的一个经典方法就是 regularizer,最佳化的过程里面加入regularizer让权重不要太大是对整体复杂度的一个限制,具体可以见以前讲regularizer的时候的推导。

 
 

这边如果我们采用以前讲过的 L2 regularizer,也就是平方和,越小越好。但是有一些缺点:权重的变化是成比例的,原来比较大的权重缩小后相对还是比较大,原来比较小的权重缩小后还是比较小。也就是说权重缩小也不会是0,也就没有办法做到通过让w是稀疏的来降维度。

 
 

我们的目标是通过让W稀疏来降低Dvc的复杂度,那么可以考虑的是 L1 regularizer。L1 是把w的绝对值得和当作是ergularizer。但是因为绝对值函数是非连续的不可微分,就很难计算(原来的函数是微分导向的性质会被破坏)。

 
 

因此可以考虑的是 weight-elimination (Scaled L2) regularizer,也就是说原来weight很大的话就把它缩小,原来很小的话也缩成一个中等分量,这样的话原来很小的就会消失不见,让w变成sparse的。常用的 weight-elimination ergularizer 如上面所示。

 
 


 
 

NN里面还有一招常用的 regularizer 机制叫做 Early Stopping。

 
 

我们看GD/SGD做的事情就是考虑其周围一个范围内的w走一小步走到另外一个地方,然后在考虑新地点的一个范围内的w再走一小步。所以虽然w很大,但是每一次你都是在一个小范围内做选择;另外你走的步越多,你看过的w就越多。所以说如果考虑的是有效的Dvc,你走的路越多,有效的Dvc就越大。那么反过来考虑你不要走太多的的路,Dvc就会比较小。

 
 

我们来看Dvc的图,山谷形状,好的Dvc会在中间。套到这里,就可以用最佳化的步数来控制Dvc的大小,就是走了一些步数感觉结果可以了就停下来。NN里面步数和Ein/Etest的关系就是上面第二张图所示,我们要的是中间步数的结果是最好的。

 
 

可以通过validation来确定什么时候要停下来比较好。

 
 


 
 

练习

 
 


 
 

总结:

Neural Network模型,出发点是把原来的perceptron变成更多层来达到越来越复杂,越来越powerful的效果,这样的链接在生物学上模仿的就是神经元的连结。在NN里面一个网络w固定了的话就是一个hypothesis,每一层做的事情就是根据这些权重来萃取pattern,一层一层萃取出来到最后一层是直接输出。NN学到这些权重的基本方法就是gradient descent(GD),透过backprop的方去很快的算这些梯度到底是多少。最后讲到这样的基本模型还需要小心的是怎么去初始化,用什么regularizer,以及透过early stopping的机制来避免overfit。

 
 

下一讲:

这里讲的是基本的类神经网路,下一讲继续做延伸变成好多好多层。


Post a Comment

Your email address will not be published. Required fields are marked *

  • Categories

  • Tags