本文总结自百度百科:激活函数

1. 激活函数功能

激活函数就是在人工神经网络的神经元上运行的函数,负责将神经元的输入映射到输出端

ps:其实不仅仅是简单的映射到输出端,是通过激活函数将非线性特性引入神经网络,不然不加激活函数输入和输出始终是线性的,下边会具体讲到。

2. 什么是激活函数

激活函数对学习人工神经网络,理解复杂和非线性函数来说有十分重要的作用。它们将非线性特性引入到我们的网络中。如下图所示,在神经元中,输入的input通过加权求和后,还被作用了一个函数,这个函数就是激活函数。引入激活函数是为了增加神经网络模型的非线性没有激活函数的每层相当于矩阵相乘,就算你叠加了若干层之后,依然是矩阵相乘。    

3. 为什么要用激活函数

如果不用激活函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合

如果使用的话,激活函数给神经元引入了非线性元素,使得神经网络可以逼近任何非线性函数,这样神经网络就可以应用到众多非线性模型中。

4. 常用的激活函数

(1)sigmoid函数

sigmoid函数,又称为Logistic函数,模拟了生物的神经元特性,即当神经元获得的输入信号累计超过一定的阈值后,神经元被激活而处于兴奋状态,否则处于抑制状态,是一个生物学中常见的S型函数,其。在信息科学中,由于其单增以及反函数单增等性质,常被用于作神经网络的阈值函数,将变量映射到[0,1]之间。公式如下:

f(x)=\frac{1}{1+e^{-x}

图像如下:

可以看到,sigmoid函数将特征压缩到了(0,1)区间,0端对应抑制状态,1对应激活状态,中间部分梯度较大。

pytorch实现如下:

import torch
from torch import nn

input = torch.ones(1, 1, 2, 2)
print(input)

sigmoid = nn.Sigmoid()
out = sigmoid(input)

print(out)

sigmoid函数可用来做二分类,但其计算量较大,并且容易出现梯度消失现象。上图可以看出,函数两端的特征导数接近于0,这将导致梯度反传时损失的误差难以传到前面的网络层(因为根据链式求导,梯度接近于0)。

(2)tanh函数

tanh是双曲函数中的一个,为双曲正切,在数学中,有双曲正弦和双曲余弦推导而来,公式如下:

f(x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}

图像如下:

(3)relu函数

为缓解梯度消失现象,修正线性单元(Rectified Linear Unit,ReLU)被引入到神经网络中。由于其优越的性能和简单的实现,relu函数已经成为最常用的激活函数之一。

relu激活函数(The Rectified Linear Unit),用于隐层神经元输出,公式如下:

f(x)=max(0,x)

图像如下:

函数图像和梯度图像如上图所示。可以看出,小于0的部分,值与梯度都为0,大于0的部分导数保持为1,避免了sigmoid函数中梯度接近于0导致的梯度消失问题。

pytorch实现relu函数示例:

from torch import nn

input = torch.ones(1, 1, 2, 2)
print(input)
>> tensor([[[[1., 1.],
          [1., 1.]]]])

# nn.ReLU()可以实现inplace操作, 即可以直接将运算结果覆盖到输入中, 以节省内存
relu = nn.ReLU(inplace=True)
print(relu(input))
# # 可以看出大于0的值保持不变, 小于0的值被置为0
>> tensor([[[[1., 1.],
          [1., 1.]]]])

relu函数计算简单,收敛快,并在众多卷积网络中验证了其有效性。

(4)Leaky Relu函数

relu函数虽然高效,但是其将负区间所有的输入都强行置为0,Leaky Relu函数优化了这一点,讲负区间的输入避免了直接置为0,而是赋予了很小的权重,表达式如下:

以上公式中ai代表权重,即小于0的值被缩小的比例。函数曲线如下:

用pytorch实现Leaky Relu激活函数如下:

import torch
from torch import nn

input = torch.randn(1, 1, 2, 2)
print(input)
>>  tensor([[[[-0.7955,  0.3595],
          [ 0.1483,  0.2836]]]])

# 利用nn.LeakyReLU()构建激活函数, 并且其为0.04, 即ai为25, True代表in-place操作
leakrelu = nn.LeakyReLU(0.04, True)
# 从结果看大于0的值保持不变, 小于0的值被以0.04的比例缩小
print(leakrelu(input))
>> tensor([[[[-0.0318,  0.3595],
          [ 0.1483,  0.2836]]]])

虽然从理论上讲,Leaky Relu函数的使用效果应该比Relu函数好,但是从大量的实验结果看并没有看出其效果更好。此外,对于Relu函数的变种,除了Leaky Relu函数之外, 还有PReLU和RReLU 函数等。

(5)softmax函数

在物体检测中,经常要面对多物体分类问题,虽然可以用sigmoid函数来构造多个二分类器,但比较麻烦,多物体类别较为常用的分类器是softmax函数。

在具体的分类任务中,softmax函数的输入往往是多个类别的得分,输出则是每一个类别对应的概率,所有类别的概率取值都在0—1之间,且和为1.softmax函数的表达式如下所示,其中vi表示第i个类别的得分,C表示分类的类别总数,输出Si为第i类别的概率。

 在PyTorch中, Softmax函数在torch.nn.functional库中, 使用方法如下 :

import torch

import torch.nn.functional as F
score = torch.randn(1, 4)
print(score)
>> tensor([[ 0.4768,  0.8797,  0.9180, -0.3224]])

# 利用torch.nn.functional.softmax()函数, 第二个参数表示按照第几个维度进行
# Softmax计算
out = F.softmax(score, 1)
print(out)
>> tensor([[0.2222, 0.3324, 0.3454, 0.0999]])

 

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐