Sigmoid函数
Sigmoid函数,也称S曲线函数,是使用范围最广的一类激活函数,具有指数函数形状,在物理意义上最为接近生物神经元,在生物学中也是常见的S型函数,又称为S型生长曲线,是神经网络中最常用的激活函数之一。Sigmoid函数由下列公式定义:
其函数图像如图:
Sigmoid函数由于单增及反函数单增等性质,常被用作神经网络的阈值函数,将变量映射到0,1之间。
一般来讲,在训练神经网络的过程中,对于求导、连续求导、处理二分类问题,一般使用Sigmoid激活函数,因为Sigmoid函数可以把实数域光滑的映射到[0,1]空间。函数值恰好可以解释为属于正类的概率(概率的取值范围是0~1)。另外,Sigmoid函数单调递增,连续可导,导数形式非常简单。但是对于多分类问题,Sigmoid函数就显得心有余而力不足了。
此外,sigmoid函数的输出均大于0,使得输出不是0均值,这称为偏移现象,这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。
根据上面的结论,我们来总结一下Sigmoid函数的优缺点:
优点
(1)Sigmoid函数的输出映射在(0,1)(0,1)之间,单调连续,输出范围有限,优化稳定,可以用作输出层。
(2)求导容易。
缺点
(1)由于其软饱和性,容易产生梯度消失,导致训练出现问题。
(2)其输出并不是以0为中心的。
由于在TensorFlow框架中已经封装好了Sigmoid函数的方法,因此在TensorFlow中我们可以直接调用tf.sigmoid()方法使用Sigmoid函数。
下面,通过一段代码片段来感受下Sigmoid函数在TensorFlow的具体应用。
import tensorflow as tf
A = tf.Variable([[1, 2], [3, 4]], dtype = tf.float32, name=’A’)
B = tf.Variable([[1, 1], [1, 1]], dtype = tf.float32, name=’B’)
y = tf.matmul(A, B)
z = tf.sigmoid(y)
上面这段代码是在TensorFlow1.x上运行的代码,但是在TensorFlow2.x上,建议将tf.matmul(A,B)改成tf.linalg.matmul(A,B)。
在这段代码中,我们创建了一个矩阵A,然后又创建了一个矩阵B,再将矩阵A和B相乘,相乘后,矩阵的阶就会变得很高,为了方便下一步的使用,调用了tf.sigmoid()这个函数,对所得的结果y使用sigmoid函数进行了激活。
tanh函数
tanh也是一种非常常见的激活函数。它实际上是sigmoid函数的一种变形。tanh函数由下列公式定义:
但是无论是中学课本还是百度百科,都会发现,tanh函数的公式是:
那么,现在就由教科书上的公式向深度学习里面的公式做一个推导,让大家彻底地明白是怎么来的:
tanh的函数图像如图。
可以把tanh函数看作sigmoid函数的升级版,但是这并不意味着tanh函数在任何情况下都要比sigmoid函数好。
一般来讲,tanh函数会在特征相差明显时效果好,在循环过程中会不断扩大特征,效果就显示出来了,但是在特征相差比较复杂或是相差不是特别大时,需要更细微的分类判断的时候,sigmoid效果就不太好了。
下面总结一下tanh函数的优缺点。
优点
(1)tanh函数的输出均值是0,因此收敛速度要比sigmoid快;
(2)迭代次数相对较少。
缺点
(1)与sigmoid函数相同,tanh函数同样具有软饱和性;
(2)还是没有改变sigmoid函数的最大问题——由于饱和性产生的梯度消失。
由于在TensorFlow框架中也已经封装好了tanh函数的方法,因此在TensorFlow中可以直接调用tf.tanh()方法使用tanh函数。
ReLU函数
ReLU的全称是Rectified Linear Units,是一种后来才出现的激活函数。与sigmoid函数相比,ReLU函数的收敛速度会更快,并且只需要一个阈值就可以得到激活值,而不是进行一大堆复杂的运算。ReLU函数的取值是max(0,x),因为神经网络是不断反复计算的,实际上变成了它在尝试不断试探如何用一个大多数为0的矩阵来尝试表达数据特征,结果因为稀疏特性的存在,反而这种方法变得运算得又快效果又好了。ReLU函数的定义公式是:
其函数图像如图所示。此处需要特别说明的是,当x<=0的时候,x会一直在x轴横坐标持续向左,在y轴上永远保持为0。
可以看到,当x<0时,ReLU硬饱和,而当x>0时,则不存在饱和问题。所以,ReLU 能够在x>0时保持梯度不衰减,从而缓解梯度消失问题。这让我们能够直接以监督的方式训练深度神经网络,而无须依赖无监督的逐层预训练。然而,随着训练的推进,部分输入会落入硬饱和区,导致对应权重无法更新。这种现象被称为“神经元死亡”。针对于x<0的硬饱和现象,我们一般会对ReLU函数做出相应的改进,改进后的函数表达式为:
这里的a是一个很小的常数,其存在的目的在于既修正了数据,又保留了部分负轴的值,使得负轴的信息不会全部丢失,这样的变体函数被称为Leaky-ReLU函数。其函数图像如图:
下面总结一下ReLU函数的优缺点。
优点
(1)相比Sigmoid函数和tanh函数,ReLU函数能够快速收敛。
(2)Sigmoid和tanh涉及了很多很高阶的操作(比如指数),ReLU函数可以更加简单地实现。
(3)ReLU函数可以有效地缓解梯度消失问题;
(4)在没有无监督预训练的时候也能有较好的表现。
缺点
(1)随着训练的进行,可能会出现神经元死亡、权重无法更新的情况;
(2)偏移现象和神经元的死亡会大大影响收敛性;
在TensorFlow中,也封装好了ReLU函数,可以调用tf.nn.relu()方法来使用ReLU函数。
Softplus函数
Softplus函数可以看作ReLU函数的平滑形式。Softplus函数也是sigmoid函数的原函数,也就是说,如果对Softplus函数进行求导的话,得到的函数就是sigmoid函数。Softplus函数的表达式为:
其函数图像如图:
Softplus和ReLu更加接近脑神经元的激活模型,而神经网络正是基于脑神经科学发展而来的,这两个激活函数的应用促成了神经网络研究的新浪潮。
下面简单列举Softplus函数的优点:
(1)相比sigmoid函数而言,采用Softplus函数在进行指数运算时,计算量相对小得多;
(2)在进行反向传播求误差梯度时,当求导涉及除法,计算量相对小得多;
(3)对于深层次网络,Softplus函数不会像sigmoid函数那样很容易就会出现梯度消失的情况,从而会使训练变得更加容易;
在TensorFlow框架中,使用tf.nn.softplus()方法来调用Softplus函数。
Softmax函数
Softmax函数也是深度学习的常用激活函数,常用于神经网络的最后一层,并作为输出层进行多分类运算。在强化学习中,常用Softmax函数作为激活函数,并被用于将某个值转化为激活概率。Softmax回归模型的函数表达式为:
对于softmax回归模型可以用下图来解释,对于输入的xs加权求和,再分别加上一个偏置量,最后再输入到softmax函数中。
如果把它写成一个等式,则可以得到Softmax数学表达式:
也可以用矩阵乘法和向量相加来表示这个计算过程,有助于提高计算效率。(也是一种更有效的思考方式):
Softmax矩阵表达式
最后,我们把它写成一个数学公式,可简化为:
再拿Softmax函数和Sigmoid函数做一个对比:
(1)Sigmoid函数主要针对的是二分类问题,而Softmax函数解决的是多分类问题,它们的针对点有所不同,也可以将Sigmoid函数看作Softmax函数的一个特例。
(2)Softmax函数基于多项式分布,而Sigmoid函数则基于伯努利分布;
(3)Softmax函数回归进行多分类时,类与类之间是互斥的,而Sigmoid函数输出的类别并不是互斥的。
在TensorFlow中,可调用tf.nn.softmax()方法来实现Softmax函数。
END