吴恩达深度学习课程总结归纳(二)

之前的学习中了解了一些基本的知识和定义,接下来开始学习核心一点点的东西了。

一、神经网络表示

神经网络的表示方法主要有层数、特征数这些来标记。
吴恩达深度学习课程总结归纳(二)
在给出的PPT中,层数是通过在右上角加入[i]进行标记。
在我的理解中,对于不同的神经元,我们可以配置不同的参数来提取不同的特征。在每个神经元中,保存如下信息:该神经元的参数 w 、 b w、b w、b。通过神经元参数和输入的特征,计算 a = σ ( w T x + b ) a=\sigma(w^Tx+b) a=σ(wTx+b)并作为该神经元的输出提供给下一层神经网络。
吴恩达深度学习课程总结归纳(二)
所以如这张图所示,我们只有三个特征,但是可以设置更多的神经元进行提取。我们给出的初始数据对应的是输入层,中间会有多个隐藏层,最后给出输出的成为输出层。在计算深度神经网络层数时,一般不将输入层也算进去。
在计算神经网络的过程中,我们会像之前提到的一样,将过程向量化(矩阵化)以加快运算。
对于上图中的计算,我们可以得到:
z 1 [ 1 ] = w 1 [ 1 ] T x + b 1 [ 1 ] , a 1 [ 1 ] = σ ( z 1 [ 1 ] ) z 2 [ 1 ] = w 2 [ 1 ] T x + b 2 [ 1 ] , a 2 [ 1 ] = σ ( z 2 [ 1 ] ) z 3 [ 1 ] = w 3 [ 1 ] T x + b 3 [ 1 ] , a 3 [ 1 ] = σ ( z 3 [ 1 ] ) z 4 [ 1 ] = w 4 [ 1 ] T x + b 4 [ 1 ] , a 4 [ 1 ] = σ ( z 4 [ 1 ] ) z^{[1]}_1=w^{[1]T}_1x+b^{[1]}_1,a^{[1]}_1=\sigma(z^{[1]}_1)\\ z^{[1]}_2=w^{[1]T}_2x+b^{[1]}_2,a^{[1]}_2=\sigma(z^{[1]}_2)\\ z^{[1]}_3=w^{[1]T}_3x+b^{[1]}_3,a^{[1]}_3=\sigma(z^{[1]}_3)\\ z^{[1]}_4=w^{[1]T}_4x+b^{[1]}_4,a^{[1]}_4=\sigma(z^{[1]}_4) z1[1]​=w1[1]T​x+b1[1]​,a1[1]​=σ(z1[1]​)z2[1]​=w2[1]T​x+b2[1]​,a2[1]​=σ(z2[1]​)z3[1]​=w3[1]T​x+b3[1]​,a3[1]​=σ(z3[1]​)z4[1]​=w4[1]T​x+b4[1]​,a4[1]​=σ(z4[1]​)这样的的四个计算结果。很明显,矩阵化可以让整体结构更清晰:
吴恩达深度学习课程总结归纳(二)
值得注意的是,每个 w i [ j ] w^{[j]}_i wi[j]​对应的维度都应该是 1 ∗ s i z e o f ( a [ j − 1 ] ) 1*sizeof(a^{[j-1]}) 1∗sizeof(a[j−1]),即上一层输出层的输出个数。
同理,我们在得到多个训练样本后,自然可以进一步矩阵化,结果如下所示:
吴恩达深度学习课程总结归纳(二)之后的层也就是这个步骤的不断重复而已。

二、激活函数的选择

我们之前一直在使用sigmoid函数作为激活函数,同时我在之前就已经提到了sigmoid函数的不足,现在让我们讨论另一些激活函数。
首先是tanh函数。tanh函数其实就是sigmoid函数搬移使其通过零点而已,表现形式为:
t a n h ( z ) = e z − e − z e z + e − z tanh(z)=\frac{e^z-e^{-z}}{e^z+e^{-z}} tanh(z)=ez+e−zez−e−z​该函数使得激活函数的平均值为0,使得下一层学习更加容易。根据吴恩达老师的说法,tanh基本上可以完美代替sigmoid函数(除了二分类领域输出需要保持0~1)。
但是无论是tanh函数还是sigmoid函数,都有一个问题:在z非常大的时候,斜率接近于零,这就大大减缓了学习的速度。
所以在这个领域,我们引入了ReLU函数:
R e L U ( z ) = { z if  z > 0 0 if  z < 0 ReLU(z)=\begin{cases} z &\text{if } z>0 \\ 0 &\text{if } z<0 \end{cases} ReLU(z)={z0​if z>0if z<0​这个函数的优势在于z很大的情况下也可以很快完成学习,就是说梯度很大。所以在隐藏层一般现在都用Relu函数。虽然有一半的区域ReLU的导数为0,但是可以设置足够多的隐藏单元令z>0,所以还是够用的。
另外还定义了 L e a k y   R e L U ( z ) = m a x ( 0.01 z , z ) Leaky \ ReLU(z)=max(0.01z,z) Leaky ReLU(z)=max(0.01z,z),就是在z<0处有较小的斜率。这些激活函数的图像如下图所示:
吴恩达深度学习课程总结归纳(二)
这里我要记录一下我对激活函数的思考:以前我一直不知道激活函数有什么用,现在我们除去激活函数,或者使用线性激活函数来看看,很明显,这样的函数就成了特征的线性组合:
a [ 2 ] = z [ 2 ] = w [ 2 ] a [ 1 ] + b [ 2 ] = w [ 2 ] w [ 1 ] x + w [ 2 ] b [ 1 ] + b [ 2 ] = w ′ x + b ′ a^{[2]}=z^{[2]}=w^{[2]}a^{[1]}+b^{[2]}=w^{[2]}w^{[1]}x+w^{[2]}b^{[1]}+b^{[2]}\\ =w'x+b' a[2]=z[2]=w[2]a[1]+b[2]=w[2]w[1]x+w[2]b[1]+b[2]=w′x+b′相当于我们得到的输出仅仅是输入的线性组合而已,这个就是最原始的感知机,所有的隐藏层都可以删去了。也因此可以看出,我们确实需要用非线性的激活函数来提取特征。
另外这里加入一点我对ReLU函数的小思考:ReLU函数在z>0的阶段是有线性函数的特征的,但是它的导数并不连续。这里我要引入一个百度用户的思考,很有启发。

1、首先什么是线性的网络,如果把线性网络看成一个大的矩阵M。那么输入样本A和B,则会经过同样的线性变换MA,MB(这里A和B经历的线性变换矩阵M是一样的)。

2、的确对于单一的样本A,经过由relu激活函数所构成神经网络,其过程确实可以等价是经过了一个线性变换M1,但是对于样本B,在经过同样的网络时,由于每个神经元是否激活(0或者Wx+b)与样本A经过时情形不同了(不同样本),因此B所经历的线性变换M2并不等于M1。因此,relu构成的神经网络虽然对每个样本都是线性变换,但是不同样本之间经历的线性变换M并不一样,所以整个样本空间在经过relu构成的网络时其实是经历了非线性变换的。

这里讲明了ReLU函数是非线性变换的本质之一。同时我也在思考,z<0的部分ReLU结果始终是0,是不是也意味着对于不同的输入,神经元会舍弃掉不同的特征点。这个就是ReLU函数的稀疏性,可以舍弃掉部分无意义的特征。这里引用一个知乎用户的思考:

当前,深度学习一个明确的目标是从数据变量中解离出关键因子。原始数据(以自然数据为主)中通常缠绕着高度密集的特征。然而,如果能够解开特征间缠绕的复杂关系,转换为稀疏特征,那么特征就有了鲁棒性(去掉了无关的噪声)。稀疏特征并不需要网络具有很强的处理线性不可分机制。那么在深度网络中,对非线性的依赖程度就可以缩一缩。一旦神经元与神经元之间改为线性激活,网络的非线性部分仅仅来自于神经元部分选择性激活。

上一篇:常用的激活函数


下一篇:激活函数