激活函数(activation function)是应用于网络中各个神经元输出的简单变换,为其引入非线性属性,使网络能够对更复杂的数据进行建模,使其能够学习更复杂的模式。如果没有激活函数,神经元只会对输入进行枯燥的线性数学运算。这意味着,无论我们在网络中添加多少层神经元,它所能学习的内容仍然有限,因为输出始终是输入的简单线性组合。
激活函数是应用于神经元输出的数学函数。它将非线性引入模型,使网络能够学习和表示数据中的复杂模式。激活函数就像秘密武器,通过引入非线性并允许神经网络学习复杂模式,使神经网络更加强大。如果没有非线性,即使是深度网络也只能解决简单的线性可分问题。激活函数使神经网络能够对高度复杂的数据分布进行建模并解决高级深度学习任务。添加非线性激活函数可以带来灵活性,并使网络能够从数据中学习更复杂、更抽象的模式。
激活函数还有助于根据我们的要求将神经元的输出值限制在一定范围内。这很重要,因为激活函数的输入是W*x+b,其中W是权重,x是输入,然后将偏置b添加到其中。如果不将这个值限制在某个限度内,它的数量可能会非常高,尤其是在具有数百万个参数的超深神经网络的情况下。这将导致计算问题。
激活函数的目的是为函数(即神经网络)添加某种非线性属性。如果没有激活函数,神经网络只能执行从输入x到输出y的线性映射。如果没有激活函数,前向传播过程中唯一的数学运算就是输入向量和权重矩阵之间的点积。由于单个点积是线性运算,因此连续的点积只不过是多个线性运算一个接一个地重复。连续的线性运算可以被视为单个线性运算。通常,我们试图从中学习某些东西的数据越复杂,特征到真实标签的映射就越非线性。没有任何激活函数的神经网络在数学上无法实现如此复杂的映射,也无法解决我们希望网络解决的任务。如果没有激活函数引入的非线性,多层神经网络相当于单层神经网络。
激活函数通常也是可微的(differentiable),这意味着可以针对给定的输入值计算一阶导数(first-order derivative)。这是必需的,因为神经网络通常使用误差(error)反向传播算法进行训练,该算法需要预测误差的导数来更新模型的权重。
网络可能有三种类型的层:从域中(domain)获取原始输入的输入层、从另一层获取输入并将输出传递到另一层的隐藏层以及进行预测的输出层。所有隐藏层通常都使用相同的激活函数。输出层通常使用与隐藏层不同的激活函数,并且取决于模型所需的预测类型。
激活函数的选择对神经网络的能力和性能有很大影响,模型的不同部分可能使用不同的激活函数。
线性激活函数:也称为Identity,类似于y=x定义的直线。无论神经网络包含多少层,如果它们都使用线性激活函数,则输出是输入的线性组合。
线性激活函数只在一个地方使用,即输出层。在所有层上使用线性激活会限制网络学习复杂模式的能力。
线性激活函数对于特定任务很有用,但必须与非线性函数结合才能增强神经网络的学习和预测能力。
非线性激活函数(例如sigmoid、Tanh、ReLU、ELU):提供的结果与输入不成比例。因此,每种类型的激活函数都有自己独特的特性,可以在不同的场景中发挥作用。
1.Sigmoid:
(1).它将输入值映射到0和1之间,除了二分类中的输出层,几乎很少使用。
(2).计算量大,容易出现梯度消失。当输入变得越来越大或越来越小时,神经元的激活接近饱和,函数的梯度会变得非常小,从而减慢深度神经网络的学习过程。在这种情况下,接近零的导数会使损失函数的梯度非常小,从而阻止权重的更新,从而阻止整个学习过程。
(3).函数的输出不以零为中心(Non-Zero Centered)。通常,这会使神经网络的训练更加困难和不稳定。
2.Tanh:
(1).与Sigmoid类似,是Sigmoid的shifted版本,输出值在-1和1之间。优于Sigmoid,它通常用于隐藏层,因为它可以更好地集中数据,从而提供更强大的学习能力。
(2).与Sigmoid一样,Tanh也会在输入变得非常大或非常小时遭受梯度消失问题。
3.ReLU(Rectified Linear Unit):
(1).它将所有负值设置为0,并保持所有正值不变。大多数隐藏层的默认选择,尤其在CNN中,计算量小,它通常可以加快学习速度。
(2).具有线性、非饱和特性。
(3).如果你不确定隐藏层要使用什么,建议使用ReLU。它有助于缓解深度神经网络中可能出现的梯度消失问题。
(4).ReLU可能遭受称为"dying ReLU"的问题。当神经元的输入为负时,就会发生这种情况,导致神经元输出0,不会对训练过程做出贡献。如果这种情况发生得太频繁,神经元就会"dies"并停止学习。
4.LeakyReLU:ReLU的改进版本,在一定程度上解决了"dying ReLU"问题。与ReLU(对于低于零的输入值,所有输出都为零)不同,使用Leaky ReLU时,我们会向函数添加一个小的线性分量。
5.PReLU:alpha是一个超参,通常设置为0.01。alpha的值永远不会接近1,否则变成线性函数,将毫无用处。
6.ReLU6:
(1).基本上是ReLU的正向限制,定义为: f(x)=min(max(x, 0), 6)
(2).阻止梯度爆炸(趋于无穷大)。
7.ELU:
(1).ReLU一样,它旨在解决梯度消失问题。
(2).与ReLU和Tanh等其他激活函数相比,ELU已被证明可以提高训练和测试准确率。它在需要高精度的深度神经网络中特别有用。
(3).由于指数函数而需要更多计算。
8.Softmax:
(1).在分类任务中预测概率分数时,最后一层应用Softmax。通常用作需要将输入分为多个类别的神经网络输出层的激活函数。它以实数向量作为输入,并返回表示每个类别可能性的概率分布。
(2).强制输出神经元的值取0到1之间的值。
(3).旨在处理多分类问题,它将神经网络的原始输出分数转换为概率,并确保输出概率总和为1,类别是互斥的,从而易于解释结果。它也是可微的,这使得它可以在训练期间用于反向传播。
9.Softplus:
(1).类似于ReLU,但没有ReLU所具有的硬零阈值(hard zero threshold)。
(2).Softplus是一个平滑的连续函数,它避免了ReLU的尖锐不连续性。
10.Swish:
(1).f(x) = x*sigmoid(x)
(2).与ReLU相比,它的性能略好一些,因为它的图与ReLU非常相似。但是,由于它不会像ReLU在x=0时那样在某一点突然改变,因此在训练时更容易收敛。
(3).计算成本高。
11.Hardswish:H-Swish,几乎与Swish相似,但由于它用ReLU(线性类型)取代了Sigmoid(指数函数),因此计算成本更低
PyTorch中激活函数的实现在:torch/nn/modules/activation.py ,支持的激活函数有:Threshold, ReLU, RReLU, Hardtanh, ReLU6, Sigmoid, Hardsigmoid, Tanh, SiLU, Mish, Hardswish, ELU, CELU, SELU, GLU, GELU, Hardshrink, LeakyReLU, LogSigmoid, Softplus, Softshrink, MultiheadAttention, PReLU, Softsign, Tanhshrink, Softmin, Softmax, Softmax2d, LogSoftmax
总结:
1.ReLU应仅用于隐藏层。当对隐藏层使用ReLU时,最好在训练之前将输入数据缩放到0-1(normalize)范围。
2.Sigmoid和Tanh不应在隐藏层中使用,因为它们会在训练期间引起问题。
3.隐藏层使用的激活函数:RNN中仍然普遍使用Tanh或Sigmoid,CNN及MLP中使用ReLU。
4.输出层中使用的激活函数:
(1).回归:Identity
(2).二分类:Sigmoid
(3).多类分类:Softmax
(4).多标签分类:Sigmoid
5.没有一刀切的解决方案,尝试不同的激活函数可以帮助你优化神经网络。
注:以上整理的内容主要来自:
1. https://en.wikipedia.org
2. https://medium.com
3. https://towardsdatascience.com
GitHub:https://github.com/fengbingchun/NN_Test