激活函数主要作用是:加入非线性的因素,以解决线性模型表达能力不足的缺陷,在整个神经网络里面起到至关重要的作用。因为神经网络的数学基础是处处可微的,所以选取的激活函数要能保证数据输入与输出也是可微的。在神经网络中常用的激活函数有Sigmoid、Tanh、ReLU、Softplus以及变种函数Noisy ReLU、Leaky ReLU、Elus、Swish等。
1、Sigmoid函数
Sigmoid函数是常见的非线性激活函数,数学表达式为:,其中,x的取值范围为:负无穷到正无穷,对应y的范围只有0~1,即:经过sigmoid函数输出的函数都会落在0~1的区间里,sigmoid函数能够把输入的值“压缩”到0~1之间。从图像上看,随着x趋近于正负无穷大,y对应的值越来越接近-1或1,这种情况称为:饱和,处于饱和状态的激活函数意味着当x=100和x=1000时的反映是一样的,这样的特征转换相当于将1000大于100十倍这个信息给丢失了,为了能有效使用Sigmoid函数,其x取值的极限也只能在-6到6之间,而在-3到3之间应该会有比较好的效果。
在TensorFlow中对应的函数为:tf.nn.sigmoid(x,name=None)
2、Tanh函数
Tanh函数可以说是sigmoid函数的值域升级版,由Sigmoid函数0~1之间到-1~1,相对于Sigmoid函数有更广的值域,在某些输出需要大于0的情况下,还是要用Sigmoid函数。一般二分类问题中,隐藏层用Tanh函数,输出层用Sigmod函数。不过这些也都不是一成不变的,具体使用什么激活函数,还是要根据具体的问题来具体分析,还是要靠调试的。Tanh函数的表达式为:,Tanh函数与Sigmoid函数有一样的饱和问题,所以在使用Tanh函数时,注意输入值的绝对值不能过大,否则模型无法训练,在TensorFlow中对应的函数为:tf.nn.tanh(x,name=None)
3、ReLU函数
ReLU函数是一个更为常用的激活函数,数学表达式为:,该公式非常简单,大于0的留下,小于0的一律为0,曲线图如下图所示,ReLU函数应用的广泛性与它的优势是分不开的,这种对于正向信号的重视,忽略了负向信号的特征,与我们人类神经元细胞对信号的反映及其相似,所以在神经网络中取得了很好的拟合效果。另外,ReLU函数运算简单,大大提升了机器的运算效率,也是ReLU函数一个很大的优点。虽然ReLU函数函数在信号响应上有很多优势,但着仅仅在正向传播方面,由于其对负值的全部舍去,因此很容易使模型输出全零从而无法进行训练,例如:随机初始化的w加入值中有个值是负值,其对应的正值输入值特征也就全部屏蔽了,同时对应负值反而被激活了,这显然不是我们想要的结果。
在TensorFlow中对应的函数是:tf.nn.relu(featutes,name=None),是一般的ReLU函数,即:max(features,0)
tf.nn.relu6(features,name=None),是以6为阈值的ReLU函数,即:min(max(features,0),6),relu6存在的原因是防止梯度爆炸,当节点和层数特别多而且输出都为正值时,最终的值会离目标值相差太远,误差太大,会导致对参数调整修正值过大,这回导致网络抖动的较厉害,最终很难收敛。
ReLU函数的变种:
(1)Noisy ReLU:为max中的x添加了一个高斯分布噪声,数学表达式为:
(2)Leaky ReLU:在ReLU函数基础上保留一部分负值,当x为负值时乘0.01,即:Leaky ReLU函数不是对负信号的一味拒绝,而是缩小。数学表达式为:
为进一步让上面的0.01作为可调参数,于是当x小于0时,乘以a,a小于等于1,数学表达式为:,
或者为:
4、Softplus函数
Softplus函数与ReLU函数类似,区别在于:Softplus函数会更加平滑,但是计算量很大,而且对于小于0的值保留的相对更多一点。Softplus函数的数学表达式为:,函数曲线如下所示:
TensorFlow中,Softplus函数对应的函数为:tf.nn.softplus(features,name=None)
5、Elus函数
Elus函数在x小于0时,做了更加复杂的变换,数学表达式为:
Elus函数和ReLU函数一样都是不带参数的,而且收敛速度比ReLU函数更快,使用Elus函数时,不使用批处理比使用批处理获得更好的效果,同时Elus函数不使用批处理效果比ReLU函数加批处理的效果更好。Elus函数曲线如下:
6、Swish函数
Swish函数是谷歌公司发现的一个效果更优于ReLU的激活函数,经过测试,在保持所有的模型参数不变情况下,只是把原来模型中的ReLU激活函数修改为Swish函数,模型的准确率均有提升。数学表达式为:,其中为x的缩放参数,一般情况取默认值1即可,在使用BN算法的情况下,还需要对x的缩放值进行调节。β是个常数或可训练的参数,Swish 具备无上界有下界、平滑、非单调的特性。Swish 在深层模型上的效果优于 ReLU。例如,仅仅使用 Swish 单元替换 ReLU 就能把 Mobile NASNetA 在 ImageNet 上的 top-1 分类准确率提高 0.9%,Inception-ResNet-v 的分类准确率提高 0.6%。
在TensorFlow低版本中没有单独的Swish函数,可以手动封装,代码如下:
def Swish(x,beta=1):
return x*tf.nn.sigmoid(x*beta)
当β = 0时,Swish变为线性函数f(x)=x2f(x)=x2.β → ∞, σ(x)=(1+exp(−x))−1σ(x)=(1+exp(−x))−1为0或1. Swish变为ReLU: f(x)=2max(0,x),所以Swish函数可以看做是介于线性函数与ReLU函数之间的平滑函数。
7、激活函数小结:
(1)神经网络中,运算特征是不断进行循环计算的,每个神经元的值也是在不断变化中,导致了tanh函数在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果并显示出来;
(2)但当计算的特征间的相差虽比较复杂却没有明显的区别,或者特征间的相差不是特别大时,就需要更细微的分类判断,这时sigmoid函数的效果就会更好一些;
(3)后来出现的relu函数的优势是,经过其处理后的数据有更好的稀疏性,即:将数据转化为只有最大数值,其他都为0,这种变换可以近似程度地最大保留数据特征,用大多数为0的矩阵来表达数据特征。以稀疏性数据来表达原有数据特征的方法,使得神经网络在迭代运算中能够取得又快又好的效果,所以目前大多数用max(0,x)来代替sigmoid函数。