3.4 CNN卷积神经网络基础知识-ReLU激活函数(百度架构师手把手带你零基础实践深度学习原版笔记系列)

3.4 CNN卷积神经网络基础知识-ReLU激活函数(百度架构师手把手带你零基础实践深度学习原版笔记系列)

ReLU激活函数

前面介绍的网络结构中,普遍使用Sigmoid函数做激活函数。在神经网络发展的早期,Sigmoid函数用的比较多,而目前用的较多的激活函数是ReLU。这是因为Sigmoid函数在反向传播过程中,容易造成梯度的衰减。让我们仔细观察Sigmoid函数的形式,就能发现这一问题。

Sigmoid激活函数定义如下:

ReLU激活函数的定义如下:

下面的程序画出了Sigmoid和ReLU函数的曲线图:

# ReLU和Sigmoid激活函数示意图
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches

plt.figure(figsize=(10, 5))

# 创建数据x
x = np.arange(-10, 10, 0.1)

# 计算Sigmoid函数
s = 1.0 / (1 + np.exp(0. - x))

# 计算ReLU函数
y = np.clip(x, a_min=0., a_max=None)

#####################################
# 以下部分为画图代码
f = plt.subplot(121)
plt.plot(x, s, color='r')
currentAxis=plt.gca()
plt.text(-9.0, 0.9, r'$y=Sigmoid(x)$', fontsize=13)
currentAxis.xaxis.set_label_text('x', fontsize=15)
currentAxis.yaxis.set_label_text('y', fontsize=15)

f = plt.subplot(122)
plt.plot(x, y, color='g')
plt.text(-3.0, 9, r'$y=ReLU(x)$', fontsize=13)
currentAxis=plt.gca()
currentAxis.xaxis.set_label_text('x', fontsize=15)
currentAxis.yaxis.set_label_text('y', fontsize=15)

plt.show()

<Figure size 720x360 with 2 Axes>

梯度消失现象

在神经网络里面,将经过反向传播之后,梯度值衰减到接近于零的现象称作梯度消失现象。

从上面的函数曲线可以看出,当x为较大的正数的时候,Sigmoid函数数值非常接近于1,函数曲线变得很平滑,在这些区域Sigmoid函数的导数接近于零。当x为较小的负数的时候,Sigmoid函数值非常接近于0,函数曲线也很平滑,在这些区域Sigmoid函数的导数也接近于0。只有当x的取值在0附近时,Sigmoid函数的导数才比较大。可以对Sigmoid函数求导数,结果如下所示:

(相关导数和最值都可以数学证明,感兴趣的小伙伴可以手动证明一下)

从上面的式子可以看出,Sigmoid函数的导数dy/dx最大值为1/4。前向传播时,y=Sigmoid(x);而在反向传播过程中,x的梯度等于y的梯度乘以Sigmoid函数的导数,如下所示:

使得x的梯度数值最大也不会超过y的梯度的1/4。

由于最开始是将神经网络的参数随机初始化的,x很有可能取值在数值很大或者很小的区域,这些地方都可能造成Sigmoid函数的导数接近于0,导致x的梯度接近于0;即使x取值在接近于0的地方,按上面的分析,经过Sigmoid函数反向传播之后,x的梯度不超过y的梯度的1/4​,如果有多层网络使用了Sigmoid激活函数,则比较靠后的那些层梯度将衰减到非常小的值。

ReLU函数则不同,虽然在x<0的地方,ReLU函数的导数为0。但是在x≥0的地方,ReLU函数的导数为1,能够将y的梯度完整的传递给x,而不会引起梯度消失。

猜你喜欢

转载自blog.csdn.net/coolyoung520/article/details/109075025
今日推荐