从0到1 激活函数(一)sigmod函数

引言

本节主要是介绍神经网络中常见的激活函数-----sigmod函数。

sigmod的函数

简介

sigmod的函数是一个在生物学中常见的S型函数,也称为S型生长曲线。在信息科学中,由于其单增以及反函数单增等性质,常被用作神经网络的激活函数,将变量映射到0,1之间。-------------摘自《百度百科》

sigmod函数也叫作Logistic函数,用于隐层神经单元输出,取值范围为(0,1),它可以将一个实数映射到(0,1)的区间,可以用来做二分类。在特征相差比较复杂或者相差不是特别大的时候效果比较好。

优点: 平滑、易于求导。
缺点: 激活函数计算量大,反向传播求误差的时候,求导涉及到除法,很容易出现梯度消失的情况,从而无法完成深层网络的训练。

定义

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

导数

对其求导可以得到:

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

导数图像为:
在这里插入图片描述

其生成代码为:

def plot_sigmoid_dao():
    x=np.arange(-8,8,0.1)
    y=sigmoid(x)*(1-sigmoid(x))
    plt.plot(x,y)
    plt.show()

图像

它的图像为(形如S曲线):
sigmod函数

图像生成的python代码为:

import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
    return 1.0/(1+np.exp(-x))

def plot_sigmoid():
    x=np.arange(-8,8,0.1)
    y=sigmoid(x)
    plt.plot(x,y)
    plt.show()

if __name__ == '__main__':
    plot_sigmoid()

激活函数

激活函数的定义

激活函数是神经网络中极为重要的一个概念,它决定了某个神经元是否被激活,这个神经元接受到的信息是否有用,是该留下还是该抛弃掉。在神经网络中我们需要一个机制来区分有用信息和无用信息,类似于大脑中的神经元,有的神经对于某些信号是敏感的而有些神经元对这些信号是抑制的,在神经网络中能起到这个作用的就是激活函数

激活函数的形式为: y = f ( i = 1 n w i x i θ ) y=f(\displaystyle\sum_{i=1}^{n} w_ix_i-\theta) ( 1 ) 公式(1)
其中 f f 即为激活函数。 θ \theta 为我们之前提到的神经元的激活阈值。

简介

在这里插入图片描述

在神经网络中,上层神经元的输出和下层神经元的输入之间存在一个关系:例如:输入层神经元节点会将神经网络的初始输入值直接传递给下一层(隐藏层或者输出层)(直接传递或者线性变换);隐藏层神经元节点会将输出值作为下一层(隐藏层或者输出层)神经元节点的输入值,而且往往不是简单地一个直接传递或者简单的映射,而是具有一个函数关系(如公式(1)所示),这个函数就是激活函数(又称激励函数)。

实际上,激活函数可以看作是变量间的一个非线性变换,通过引入激活函数来增加神经网络模型的非线性,以便增加对样本非线性关系的拟合能力(在现实生活中,大部分的数据都是线性不可分的)。只有加入了激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。

如果不用激励函数,在这种情况下,你每一层节点的输入都是上层输出的线性函数,很容易验证,无论神经网络有多少层,输出都是输入的线性组合,与没有隐藏层的效果相当,这种情况下就是最原始的多层感知机了(MLP),那么网络的逼近能力就相当有限。而现实生活中大部分的数据都不是线性可分的,正是因为这样,才引入了非线性的函数作为激活函数,这样深层神经网络表达能力就更加强大了。(不再是输入的线性组合,而是几乎可以逼近的任意函数。

首先,我们将原函数及其导数画在同一个图像中
在这里插入图片描述

sigmod作为激活函数的时候存在的问题

  1. 当很多个使用sigmoid激活函数的Layers 加到神经网络中时,损失函数的梯度会接近0,这会导致 network难以训练。因为通过上图可以看出,当输入值很小或者很大的时候,sigmod的梯度都会趋向于0,而我们经常使用梯度乘以学习率来更新权值函数的,所以会导致权值改变非常小,难以训练。
  2. 通过问题1 可以知道你需要尤其注意参数的初始值来尽量避免saturation(饱和,即梯度趋于0)的情况。也就是说对初始值是有所限制的。(其实,纵使是限制了,对于层数较多的神经网络来说,效果也不是特别好。)
  3. 会导致梯度消失或者梯度爆炸。如果是只有几个sigmoid层的浅层神经网络,这并不会引起很大的问题。然而,当非常多的sigmoid层时,就会产生问题。通常我们会初始化参数的值在(0,1)之间,通过sigmod的导数图像来看,当输入在(0,1)之间的时候,梯度值大约在(0.2-0.25)之间(可以将图像放大来看,如下图)。由反向传播算法的数学推导可知,梯度从后向前传播时,每传递一层梯度值都会减小为原来的0.25倍,如果神经网络隐层特别多,那么梯度在穿过多层后将变得非常小接近于0,即出现梯度消失现象;当网络权值初始化为 (1,+∞) 区间内的值,则会出现梯度爆炸情况,梯度爆炸的情况还是比较少见的。推导如下,或者参见这里
    在这里插入图片描述

神经网络的梯度通过反向传播来得到,简单的说,反向传播通过从最终层到初始层,误差逐层传播来得到梯度,通过链式求导法则,每一层的导数会乘到一起来计算初始层的导数。

  1. Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。 产生的一个结果就是:如果数据进入神经元的时候是正的(e.g. elementwise in ),那么 计算出的梯度也会始终都是正的。

为了解决sigmod这种问题,后面出现了Thah、Relu等激活函数。具体的见后面的章节。

其他资料

1、几种激活函数
这里面包含了几种常见的激活函数公式及其图像代码。
【本章完】

发布了115 篇原创文章 · 获赞 132 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/u010626937/article/details/103633220