深度学习笔记(二)——激活函数原理与实现
闲聊
昨天详细推了下交叉熵,感觉还可以,今天继续加油。
ReLU
原理
定义:ReLU是修正线性单元(rectified linear unit),在0和x之间取最大值。
出现原因:由于sigmoid和tanh容易出现梯度消失,为了训练深层神经网络,需要一个激活函数神经网络,它看起来和行为都像一个线性函数,但实际上是一个非线性函数,允许学习数据中的复杂关系 。该函数还必须提供更灵敏的激活和输入,避免饱和。而ReLU是非饱和激活函数,不容易发生梯度消失。
def ReLU(input):
if input>0:
return input
else:
return 0
ReLU 的函数表达式:
当 x <= 0 时,ReLU = 0
当 x > 0 时,ReLU = x
ReLU 的导数表达式:
当 x<= 0 时,导数为 0
当 x > 0 时,导数为 1
优点
计算简单
因为ReLU只需要一个max()函数便可以完成运算,而tanh和sigmoid需要指数运算,所以ReLU计算成本很低。
代表性稀疏
ReLU在负输入时可以输出真零值,允许神经网络中的隐藏层包含一个或多个真零值,这就是所谓的稀疏表示。在表示学习,因为它可以加速学习和简化模型。有效缓解过拟合的问题,因为 ReLU 有可能使部分神经节点的输出变为 0,从而导致神经节点死亡,降低了神经网络的复杂度。
线性行为
在输入大于零时,ReLU看起来像一个线性函数,当网络行为是近线性时,更容易优化,不会发生梯度消失或梯度爆炸,当 x 大于 0 时,ReLU 的梯度恒为 1,不会随着网路深度的加深而使得梯度在累乘的时候变得越来越小或者越来越大,从而不会发生梯度消失或梯度爆炸,也因此可以更适合训练深度网络。现在深度学习中,默认的激活函数是ReLU。
缺点
不适合RNN类网络
对 MLPs,CNNs 使用 ReLU,但不是 RNNs。ReLU 可以用于大多数类型的神经网络,它通常作为多层感知机神经网络和卷积神经网络的激活函数 。传统上,LSTMs 使用 tanh 激活函数来激活cell状态,使用 Sigmoid激活函数作为node输出。而ReLU通常不适合RNN类型网络的使用。
代码
import torch
import torch.nn as nn
relu = nn.ReLU(inplace=True)
Sigmoid
原理
Sigmoid 是常用的非线性的激活函数,可以将全体实数映射到(0, 1)区间上,其采用非线性方法将数据进行归一化处理;sigmoid函数通常用在回归预测和二分类(即按照是否大于0.5进行分类)模型的输出层中。
函数公式:
def Sigmoid(x):
return 1. / (1 + np.exp(-x))
曲线图:
导数:
导数图像:
优点
求导容易
梯度平滑,求导容易
优化稳定
Sigmoid函数的输出映射在(0,1)之间,单调连续,输出范围有限,优化稳定,可以用作输出层
缺点
计算量大
在正向传播和反向传播中都包含幂运算和除法,所以存在着较大计算资源。
梯度消失
梯度消失:输入值较大或较小(图像两侧)时,sigmoid导数则接近于零,因此在反向传播时,这个局部梯度会与整个代价函数关于该单元输出的梯度相乘,结果也会接近为 0 ,无法实现更新参数的目的;
关于这点可以从其导数图像中看出,如果我们初始化神经网络的权值为 [0,1] [0,1][0,1] 之间的随机值,由反向传播算法的数学推导可知,梯度从后向前传播时,每传递一层梯度值都会减小为原来的0.25倍,如果神经网络隐层特别多,那么梯度在穿过多层后将变得非常小接近于0,即出现梯度消失现象;
代码
import torch
import torch.nn as nn
sigmoid=nn.Sigmoid()
Softmax
原理
Sigmoid函数只能处理两个类别,这不适用于多分类的问题,所以Softmax可以有效解决这个问题。Softmax函数很多情况都运用在神经网路中的最后一层网络中,使得每一个类别的概率值在(0, 1)之间。Softmax =多类别分类问题=只有一个正确答案=互斥输出(例如手写数字,鸢尾花)。构建分类器,解决只有唯一正确答案的问题时,用Softmax函数处理各个原始输出值。Softmax函数的分母综合了原始输出值的所有因素,这意味着,Softmax函数得到的不同概率之间相互关联。即得到的所有概率和为1,示例看代码部分
def softmax(x):
return np.exp(x) / sum(np.exp(x))
优点
适用范围较广
相较于sigmoid,softmax可以处理多分类问题,因此可以适用于更多领域。
拉开值之间差距
由于Softmax函数先拉大了输入向量元素之间的差异(通过指数函数),然后才归一化为一个概率分布,在应用到分类问题时,它使得各个类别的概率差异比较显著,最大值产生的概率更接近1,这样输出分布的形式更接近真实分布。由于其拉开了差距,这样便于提高loss,能够获得更多的学习效果。
代码
举例:
假如一个鸡鸭鹅的三分类数据集,假如一个batch有三个输入,通过之前的网络,得到结果是([10,8,6],[7,9,5],[5,4,10])。
实际的标签值为[0,1,2],即是鸡鸭鹅。
表示含义是:网络推测鸡的概率为[86.68%],鸭[11.73%],鹅[1.59%],后面两行同理。
import torch
<