深度学习激活函数1.简述在神经元的数学模型中,轴突所携带的信号(例如:x0)通过突触进行传递,由于突触的强弱不一,假设我们以w0表示,那么我们传到下一个神经元的树突处的信号就变成了w0x0。其中突触强弱(参数w)是可学的,它控制了一个神经元对另一个神经元影响的大小和方向(正负)。然后树突接收到信号后传递到神经元内部(cellbody),与其他树突传递过来的信号一起进行加和,如果这个和的值大于某一个固定的阈值的话,神经元就会被激活,然后传递冲激信号给树突。在数学模型中我们假设传递冲激信号的时间长短并不重要,只有神经元被激活的频率用于传递信息。我们将是否激活神经元的函数称为激活函数(activationfunctionf),它代表了轴突接收到冲激信号的频率。2.意义激活函数是用来引入非线性因素的。网络中仅有线性模型的话,表达能力不够。比如一个多层的线性网络,其表达能力和单层的线性网络是相同的。网络中卷积层、池化层和全连接层都是线性的,所以,需要在网络中加入非线性的激活函数层。3.性质激活函数一般具有一下性质:非线性:弥补线性模型的不足;处处可导:反向传播时需要计算激活函数的偏导数,所以要求激活函数除个别点外,处处可导;单调性:当激活函数是单调的时候,单层网络能够保证是凸函数;输出值的范围:当激活函数输出值是有限的时候,基于梯度的优化方法会更加稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是无限的时候,模型的训练会更加高效,不过在这种情况下,一般需要更小的learningrate。4.常见激活函数不同的激活函数效果有好有坏,一般比较常见的激活函数有sigmoid、tanh和Relu,其中Relu由于效果最好,现在使用的比较广泛。3.1Sigmoid函数Sigmoid函数表达式为:它将输入值映射到[0,1]区间内,其函数图像如下图:从数学上来看,非线性的Sigmoid函数对中央区的信号增益较大,对两侧区的信号增益小,在信号的特征空间映射上,有很好的效果。从神经科学上来看,中央区酷似神经元的兴奋态,两侧区酷似神经元的抑制态,因而在神经网络学习方面,可以将重点特征推向中央区,将非重点特征推向两侧区。sigmoid的优点在于输出范围有限,所以数据在传递的过程中不容易发散。Sigmoid有一个十分致命的缺点就是它的导数值很小(sigmoid函数导数图像如下图),其导数最大值也只有1/4,而且特别是在输入很大或者很小的时候,其导数趋近于0。这直接导致的结果就是在反向传播中,梯度会衰减的十分迅速,导致传递到前边层的梯度很小甚至消失(killgradients),训练会变得十分困难。还有就是sigmoid函数的计算相对来说较为复杂(相对后面的relu函数),耗时较长,所以由于这些缺点,现在已经很少有人使用sigmoid函数。另外,Sigmoid的output不是0均值.这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。产生的一个结果就是:如果数据进入神经元的时候是正的(e.g.x0elementwiseinf=wTx+b),那么w计算出的梯度也会始终都是正的。如果按batch去训练,那么batch可能得到不同的信号,所以这个问题可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的killgradients问题相比还是要好很多的。3.2Tanh函数Tanh函数表达式为:它将输入值映射到[-1,1]区间内,其图像为:Tanh函数是Sigmoid函数的一种变体;与sigmoid不同的是,tanh是0均值的。因此,实际应用中,tanh会比sigmoid更好,但Tanh函数现在也很少使用。3.3ReLu(RectifiedLinearUnits)激活函数Relu函数为现在使用比较广泛的激活函数,其表达式为当输入x0时,输出为0;当x0时,输出等于输入值。Relu函数相对于前边2种激活函数,有以下优点:Relu函数的计算十分简单,前向计算时只需输入值和一个阈值(这里为0)比较,即可得到输出值。在反向传播时,Relu函数的导数为,计算也比前边2个函数的导数简单。由于relu函数的导数为,即反向传播时梯度要么为0,要么不变,所以梯度的衰减很小,即使网路层数很深,前边层的收敛速度也不会很慢。Relu函数也有很明显的缺点,就是在训练的时候,网络很脆弱,很容易出现很多神经元值为0,从而再也训练不动。一般我们将学习率设置为较小值来避免这种情况的发生。为了解决上面的问题,后来又提出很多修正过的模型,比如Leaky-ReLU、ParametricReLU和RandomizedReLU等,其思想一般都是将x0的区间不置0值,而是设置为1个参数与输入值相乘的形式,如αx,并在训练过程对α进行修正。3.4Maxout激活函数maxout是一种激发函数形式。通常情况下,如果激发函数采用sigmoid函数,在前向传播过程中,隐含层节点的输出表达式为:其中W一般是2维的,这里表示取出的是第i列,下标i前的省略号表示对应第i列中的所有行。但如果是maxout激发函数,则其隐含层节点的输出表达式为:这里的W是3维的,尺寸为d*m*k,其中d表示输入层节点的个数,m表示隐含层节点的个数,k表示每个隐含层节点对应了k个“隐隐含层”节点,这k个“隐隐含层”节点都是线性输出的,而maxout的每个节点就是取这k个“隐隐含层”节点输出值中最大的那个值。因为激发函数中有了max操作,所以整个maxout网络也是一种非线性的变换。因此当我们看到常规结构的神经网络时,如果它使用了maxout激发,则我们头脑中应该自动将这个“隐隐含层”节点加入。参考一个日文的maxoutppt中的一页ppt如下:maxout的拟合能力是非常强的,它可以拟合任意的的凸函数。最直观的解释就是任意的凸函数都可以由分段线性函数以任意精度拟合,而maxout又是取k个隐隐含层节点的最大值,这些“隐隐含层”节点也是线性的(k个隐隐含层节点可认为是k个线性函数,个人见解),所以在不同的取值范围下,最大值也可以看作是分段线性的(分段的个数与k值有关)。下图表达的意思就是maxout可以拟合任意凸函数,当然也包括了ReLU。作者从数学的角度上也证明了这个结论,即只需2个maxout节点就可以拟合任意的凸函数了(相减),前提是“隐隐含层”节点的个数可以任意多,如下图所示:所以,Maxout具有ReLU的优点(如:计算简单,不会saturation),同时又没有ReLU的一些缺点(如:容易godie)。不过还是存在一些缺点的:就是把参数double了。3.5怎么选择激活函数?这种问题不可能有定论,只能说是个人建议。如果使用ReLU,那么一定要小心设置learningrate,而且要注意不要让网络出现很多“dead”神经元,如果这个问题不好解决,那么可以试试LeakyReLU、PReLU或者Maxout.友情提醒:最好不要用sigmoid,可以试试tanh,不过可以预期它的效果会比不上ReLU和Maxout。通常来说,很少会把各种激活函数串起来在一个网络中使用的。3.6Dropout详解Dropout是指在模型训练时随机让网络某些隐含层节点的权重不工作,不工作的那些节点可以暂时认为不是网络结构的一部分,但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作。训练神经网络模型时,如果训练样本较少,为了防止模型过拟合,Dropout可以作为一种trikc供选择。Dropout是hintion最近2年提出的,其论文中指出,在每个训练批次中,通过忽略一半的特征检测器(让一半的隐层节点值为0),可以明显地减少过拟合现象。这种方式可以减少特征检测器间的相互作用,检测器相互作用是指某些检测器依赖其他检测器才能发挥作用。原理分析Dropout可以看作是一种模型平均,所谓模型平均,顾名思义,就是把来自不同模型的估计或者预测通过一定的权重平均起来,在一些文献中也称为模型组合。对于每次输入到网络中的样本(可能是一个样本,也可能是一个batch的样本),其对应的模型都是不同的,但所有的这些不同的模型又同时share隐含节点的权值。即每次输入到网络中的样本所对应模型是部分权重共享的,只有被舍弃掉那部分权重不同。Dropout中哪里体现了“不同模型”?这个奥秘就是随机选择忽略隐层节点,在每个批次的训练过程中,由于每次随机忽略的隐层节点都不同,这样就使每次训练的网络都是不一样的,每次训练都可以单做一个“新”的模型;此外,隐含节点都是以一定概率随机出现,因此不能保证每2个隐含节点每次都同时出现,这样权值的更新不再依赖于有固定关系隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况。dropout过程就是一个非常有效的神经网络模型平均方法,通过训练大量的不同的网络,来平均预测概率。不同的模型在不同的训练集上训练(每个批次的训练数据都是随机选择),最后再每个模型用相同的权重来“融合”,有点类似boosting算法。训练阶段Dropout是在标准的bp网络的的结构上,使bp网的隐层激活值,以一定的比例v变为0,即按照一定比例v,随机地让一部分隐层节点失效;去掉权值惩罚项,取而代之的事,限制权值的范围,给每个权值设置一个上限范围;如果在训练更新的过程中,权值超过了这个上限,则把权值设置为这个上限的值。这样处理,不论权值更新量有多大,权值都不会过大。此外,还可以使算法使用一个比较大的学习率,来加快学习速度,从而使算法在一个更广阔的权值空间中搜索更好的权值,而不用担心权值过大。测试阶段:在训练过程中神经元以概率p出现,而在测试阶段它一直都存在。在网络前向传播到输出层前时隐含层节点的输出值都要缩减到(1-v)倍;例如正常的隐层输出为a,此时需要缩减为a(1-v)。解释:假设比例v=0.5,即在训练阶段,以0.5的比例忽略隐层节点;那么假设隐层有80个节点,每个节点输出值为1,那么此时只有40个节点正常工作;也就是说总的输出为40个1和40个0;输出总和为40;而在测试阶段,由于我们的权值已经训练完成,此时就不在按照0.5的比例忽略隐层输出,假设此时每个隐层的输出还是1,那么此时总的输出为80个1,明显比dropout训练时输出大一倍;所以为了得到和训练时一样的输出结果,就缩减隐层输出为a(1-v);即此时输出80个0.5,总和也为40。这样就使得测试阶段和训练阶段的输出“一致”了。注:如果有多个隐含层,那么对每一个隐含层分别使用dropout策略。