1.神经网络激活函数介绍

1.1 为什么使用激活函数

  首先摆结论,因为线性模型的表达能力不够,引入激活函数是为了添加非线性因素。(知乎回答1解释了这句话。)

  简单来说就是如下图所示没有激活函数时,我们的整个网络还是线性的。当我们的输出需要拟合曲线时,我们只能通过更多的线性函数去逼近曲线:

  而如果我们在每层网络中加入非线性函数如sigmoid函数之后,可以拟合出曲线:

激活函数通常有如下一些性质: 2

  • 非线性:当激活函数是线性的时候,一个两层的神经网络就可以逼近基本上所有的函数了。但是,如果激活函数是恒等激活函数的时候(即f(x)=x),就不满足这个性质了,而且如果MLP使用的是恒等激活函数,那么其实整个网络跟单层神经网络是等价的。

  • 可微性:当优化方法是基于梯度的时候,这个性质是必须的。

  • 单调性:当激活函数是单调的时候,单层网络能够保证是凸函数。

  • 激活函数输出约等于输入【f(x)≈x】:当激活函数满足这个性质的时候,如果参数的初始化是random的很小的值,那么神经网络的训练将会很高效;如果不满足这个性质,那么就需要很用心的去设置初始值。

  • 输出值的范围:当激活函数输出值是有限的时候,基于梯度的优化方法会更加 稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是无限的时候,模型的训练会更加高效,不过在这种情况小,一般需要更小的learning rate。

1.2 常用的激活函数

  该部分需要一篇专门的文章【卷积神经网络专题】:6.激活函数来介绍,这里先引用其他博主的介绍:

  各个激活函数的用的地方:https://blog.csdn.net/leo_xu06/article/details/53708647
  各个激活函数的优缺点:https://blog.csdn.net/Jaster_wisdom/article/details/78380839

2.Relu函数的正向传播

Relu 的图像如下:

Relu 的公式如下:

Relu正向传播的python-numpy代码如下:

in_data[in_data<0] = 0


3.Relu函数的反向传播

3.1 反向传播公式:

  其在x=0处是不可微的,但是在深度学习框架的代码中为了解决这个直接将其在x=0处的导数置为1,所以它的导数也就变为了 :
  

3.2反向传播python-numpy代码:

return (self.top_val > 0) * residual                                    
# (self.top_val > 0)表示大于0的为1,不大于0的为0;为relu对输入导数


4.Relu的优点

  1. relu的稀疏性(激活函数的作用);
  2. 还是防止梯度弥散(也叫作梯度消失,是针对sigmoid函数这一缺点的);3
  3. 加快计算(正反向传播代码好实现)

下面展开叙述:4

首先我们看下sigmoid和relu的曲线

然后可以得到sigmoid的导数

以及relu的导数

结论:

  1.sigmoid的导数只有在0附近的时候有比较好的激活性,在正负饱和区的梯度都接近于0,所以这会造成梯度弥散,而relu函数在大于0的部分梯度为常数,所以不会产生梯度弥散现象
  
  2.relu函数在负半区的导数为0 ,所以一旦神经元激活值进入负半区,那么梯度就会为0,也就是说这个神经元不会经历训练,即所谓的稀疏性
  
  3.relu函数的导数计算更快,程序实现就是一个if-else语句,而sigmoid函数要进行浮点四则运算。