TensorFlow入门(十八、激活函数)

激活函数是什么?

        单个神经元的网络模型:

        用计算公式表达如下:

        即在神经元中,输入的x通过与权重w相乘,与偏置量b求和后,还被作用了一个函数,这个函数就是激活函数。

激活函数的作用

        如果没有激活函数,整个神经元模型就是一个简单的线性方程。而在现实生活中,线性方程能解决的事情相对比较简单,不能解决很多复杂的问题。比如使用神经网络模型模拟类似图像、视频、音频、语音这样的复杂数据,隐藏层之间存在非线性特点,需要使用激活函数来帮助模型理解并模拟这类数据。

        激活函数对于人工神经网络模型学习、理解非常复杂的非线性函数来说具有十分重要的作用。通过它,可以将非线性因素引入到网络模型中,将模型中一个节点的输入信号转换成一个输出信号,该输出信号被用作下一层的输入,从而解决线性模型表达能力不足的缺陷。

        示意图如下:

        通过前面各输入值x和权重w的求和计算后输出结果,将输出结果作为激活函数的输入,从而增加模型解决负责问题的能力。

激活函数种类

        激活函数有多种,早期研究神经网络主要采用sigmoid函数或者tanh函数,输出有界,很容易充当下一层的输入。近些年Relu函数及其改进型(如Leaky-ReLU、P-ReLU、R-ReLU等)在多层神经网络中应用比较多。

        Sigmoid函数

                Sigmoid函数,也叫Logistic函数,用于隐层神经元输出,该函数的数学公式、函数曲线和导数曲线如下:

                计算公式:

                函数、导数曲线:

                可以看到:Sigmoid函数连续、光滑、严格单调,是一个非常良好的阈值函数。x可以是正无穷到负无穷,但是对应的y却只有0~1的范围,所以,经过Sigmoid函数输出的函数都会落在0~1的区间里,即Sigmoid函数能够把输入的值"压缩"到0~1之间。

                随着x趋近正负无穷大,y对应的值越来越接近1或-1的情况叫做饱和。处于饱和态的激活函数意味着,当x=100和x=1000时的反映都是一样的,这样的特性转换相当于将1000大于100十倍这个信息给丢失了。为了能有效使用Sigmoid函数,x的极限也只能是-6~6之间,而在-3~3之间时应该会有比较好的效果。由于Sigmoid函数的值域范围限制在(0,1)之间,这和概率值的范围[0,1]很接近,所以二分类的概率常常用这个函数。

                优点 : ①平滑②易于求导

                缺点 : ①在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失,其中梯度爆炸发生的概率非常小,而梯度消失发生的概率比较大

                          ②Sigmoid的output不是0均值,即不以(0,0)为中心点。这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入,会产生一个结果,即当x>0,f=(w^T)x+b时,对w求局部梯度则都为正,这样在反向传播的过程中w要么都往正方向更新,要么都往负方向更新,从而产生捆绑的现象,使得收敛速度比较缓慢

                          ③其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间。

                在TensorFlow中对应的函数为:tf.nn.sigmoid(x,name = None),其中nn代表TensorFlow用于深度学习计算的核心模块。

模拟Sigmoid函数示例代码如下:

import matplotlib.pyplot as plt
import numpy as np

def sigmoid(x):
    return 1./(1. + np.exp(-x))

def plot_sigmoid():
    x = np.arange(-6,6,0.2)
    y = sigmoid(x)
    plt.plot(x,y)
    plt.show()
    
if __name__ == "__main__":
    plot_sigmoid()

        Tanh函数

                Tanh函数,也叫双曲正切函数。该函数在Sigmoid函数值域范围(0~1)的基础上,将值域范围升级到了-1~1,可以说是Sigmoid函数的值域升级版。

                计算公式:

                函数、导数曲线:

                可以看到,x取值也是从正无穷到负无穷,但对应的y值变为-1~1之间,相对于Sigmoid函数有了更广的值域。Tanh函数在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果。但是,Tanh函数跟Sigmoid函数有一样的缺陷,即饱和问题,所以在使用Tanh函数时,要注意输入值的绝对值不能过大,否则模型无法训练。

                优点 : ①Tanh函数的导数比Sigmoid函数的导数数值更大,即梯度变化更快,在训练过程中收敛速度更快

                          ②输出范围为-1到1之间,可以使得输出均值为0,即以(0,0)为中心点,这个性质可以提高BP训练的效率

                          ③可以将线性函数转变为非线性函数

                缺点 : ①也存在梯度消失的情况,并没有解决Sigmoid梯度消失的问题

                          ②幂运算依然比较耗时

                在TensorFlow中对应的函数为:tf.nn.tanh(x,name = None)

模拟Tanh函数示例代码如下:

import matplotlib.pyplot as plt
import numpy as np

def tanh(x):
    return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))

tanh_inputs = np.arange(-10,10,0.1)
tanh_outputs = tanh(tanh_inputs)

plt.plot(tanh_inputs,tanh_outputs)
plt.xlabel("Tanh Inputs")
plt.ylabel("Tanh Outputs")
plt.show()

        ReLU函数

                ReLU函数,即线性整流函数,又称修正线性单元。

                计算公式:

                函数曲线:

                可以看到,ReLU函数对正向信号非常重视,忽略了负向信号。与人类神经元细胞对信号的反映很是类似。因此在神经网络中可以取得很好的拟合效果,应用十分广泛。

                优点 : ①收敛速度比Sigmoid函数和Tanh函数快,解决了梯度爆炸、梯度消失的问题

                          ②计算复杂度低,大大地提升了机器的运行效率

                          ③适合用于后向传播

                缺点 : ①ReLU的输出不是以(0,0)为中心点

                          ②改动了输入数据的分布,下一层输入数据的分布跟前一层输入数据的分布不同,大大降低了模型的训练速度

                          ③ReLU不会对数据做幅度压缩,数据的幅度会随着模型层数的增加不断扩张

                          ④容易出现神经元死亡的问题,当输入接近零或为负时,函数的梯度变为零,网络将无法执行反向传播,也无法学习

                在TensorFlow中,关于ReLU函数的实现,有以下两个对应的函数

                        tf.nn.relu(features,name = None),它是一般的ReLU函数,即max(features,0)

                        tf.nn.relu6(features,name = None),它是以6为阈值的ReLU函数,即min(max(features,0),6)

                        注意 : relu6存在的原因是防止梯度爆炸,当节点和层数特别多而且输出都为正时,它们相加后的和会是一个很大的值,尤其在经历几层变换之后,最终的值可能会离目标值相差太远,误差太大,会导致对参数调整修正值过大,从而引起网络抖动得较厉害,最终很难收敛。

        Softplus函数

                Softplus函数与ReLU函数十分类似,具体的函数曲线为下图中的蓝色虚线:

                Softplus函数与ReLU函数的区别在于 : Softplus函数更加平滑,但是计算量很大,而且对于小于0的值保留的相对更多一点。

                Softplus函数的计算公式:

                在TensorFlow中,对应的函数为:tf.nn.softplus(features,name = None)

        基于ReLU基础上的变种函数

                从ReLU函数的曲线上知道,它在正向传播方面对信号的响应有很多优势,但忽略了负向信号,全部舍去了负值,很容易使模型输出全零导致无法再进行训练。例如,随机初始化的w中有个值是负值,相乘之后为负值,尽管对应的输入是正值,但输入值特征也会被全部屏蔽。同理,对应负值输入值反而被激活了。这显然不是我们想要的结果。于是在基于ReLU的基础上又演化出了一些变种函数。

                Noisy relus函数 : 它为max中的x加了一个高斯分布的噪声,数学公式如下:

                        

                Leaky relus函数 : 它在ReLU基础上,保留一部分负值,让x为负时乘0.01,即Leaky relus对负信号不是一味地拒绝,而是缩小。其数学公式如下:

                        

                        可以进一步让这个0.01作为参数可调,于是,当x小于0时,乘以a,a小于等于1。数学公式变为:

                        

                        可以得到Leaky relus的公式为max(x,ax)

                        Leaky relus的函数曲线:

                        在TensorFlow中,Leaky relus公式没有专门的函数,可以利用现有函数组成而得到:tf.maximum(x,leak * x,name = name),其中leak为传入的参数,可以设为0.01等。

                Elus函数 : Elus函数与ReLU函数一样都是不带参数的,而且收敛速度比ReLU函数更快,使用Elus函数时,不使用批处理比使用批处理能够获得更好的效果,同时Elus函数不使用批处理的效果比ReLU函数加批处理的效果要好。

                        数学公式:

                        在TensorFlow中,Elus函数对应的函数为:tf.nn.elu(features,name = None)

                Swish函数 : 谷歌公司发现的一个效果更优于Relu的激活函数。经过测试,在保持所有的模型参数不变的情况下,只是把原来模型中的ReLU激活函数修改为Swish激活函数,模型的准确率具有提升。

                        数学公式:

                        其中β为x的缩放参数,一般情况下取默认值1即可,在使用BN算法的情况下,还需要对x的缩放值β进行调整。β是个常数或可训练的参数。Swish具备无上界有下界、平滑、非单调的特性。Swish在深层模型上的效果优于ReLU。

                        在TensorFlow低版本中没有单独的Swish函数,可以手动封装,代码如下:

def swish(x,beta = 1):
    return x*tf.nn.sigmoid(x*beta)

                        当beta去不同的值时,函数图像如下:

                                

                        当β = 0时,Swish激活函数变为线性函数f(x) = x/2

                        当β = ∞时,Swish激活函数变为0或x,相当于ReLU

                        所以,Swish函数可以看作是介于线性函数与ReLU函数之间的平滑函数

激活函数总结

        ①神经网络中,运算特征是不断进行循环计算的,每个神经元的值也是在不断变化中。当特征相差明显时,Tanh函数的效果会很好,在循环过程中会不断扩大特征效果并显示出来。

        ②当计算的特征间相差虽较复杂却没有明显的区别,或者特征间的相差不是特别大时,需要更细微的分类判断,这时sigmoid函数的效果会好一些。

        ③ReLU函数的优势在于,其处理后的数据具备更好的稀疏性,即:将数据转化为只有最大数值.其他都为0,这种变换可以近似程度地最大保留数据特征,用大多数元素为0的稀疏矩阵来实现。以稀疏性数据来表达原有数据特征的方法,使得神经网络在迭代运算中能够取得又快又好的效果,因此目前大多数用max(0,x)来代替Sigmoid函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值