激活函数理解

前言

为什么神经网中非要有各种各样的激活函数?他们有什么用?没有他们会怎样?常见的激活函数有哪些,他们都有什么特点?

如果我们不运用激活函数,神经网络的输出信号将仅仅是一个简单的线性函数。线性方程很容易解决,但是它们的复杂性有限,从数据中学习复杂函数映射的能力较小。

一个没有激活函数的神经网络最终只不过是一个线性回归模型罢了,不能解决现实世界中的大多数非线性问题。

现假设只有两层没有激活函数的全连接网络如下:
在这里插入图片描述第一层的权重和偏置为 w 1 w_1 w1 b 1 b_1 b1,其 输出直接连到第二层的输入,权重和偏置为 w 2 w_2 w2 b 2 b_2 b2,最后输出预测值。公式化简化后仍然是一个线性函数。
y ^ = w 2 ( w 1 ⋅ x + b 1 ) + b 2 = w 2 ⋅ w 1 ⋅ x + w 2 ⋅ b 1 + b 2 = w ⋅ x + b \begin{aligned} \hat{y} & = w_2(w_1 \cdot x + b_1) + b_2 \\ & = w_2\cdot w_1 \cdot x + w_2 \cdot b_1 + b_2 \\ & = w\cdot x + b \end{aligned} y^=w2(w1x+b1)+b2=w2w1x+w2b1+b2=wx+b
如果我们在第一层的输出加上一个激活函数,则不能有上式的化简。只有加入了激活函数,神经网络才具备分层的非线性的学习能力。

y ^ = w 2 ( σ ( y 1 ) ) + b 2 y 1 = w 1 ⋅ x + b 1 σ ( ⋅ ) 为激活函数 \begin{aligned} \hat{y} & = w_2(\sigma(y_1)) + b_2 \\ & y_1 =w_1 \cdot x + b_1 \\ & \sigma(\cdot) 为激活函数 \\ \end{aligned} y^=w2(σ(y1))+b2y1=w1x+b1σ()为激活函数

sigmoid

f ( x ) = 1 1 + e − x \begin{aligned} f(x) = \frac{1}{1+e^{-x}} \nonumber \end{aligned} f(x)=1+ex1

在这里插入图片描述

  • 输出范围在(0,1)之间,常用于二元分类问题的最后一层,将输出映射到概率值。
  • sigmoid函数的输出值均大于0,使得输出不是0的均值,从而发生激活函数的偏移现象
  • 从图像中可以看出sigmoid两端的导数接近0,会导致反向传播的梯度也变得非常小,此时网络参数可能得不到更新,难以有效训练。也称梯度消失。
  • 一般来说sigmoid网络在5层之内就会产生梯度消失现象。

tanh

f ( x ) = e x − e − x e x + e − x \begin{aligned} f(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} \end{aligned} f(x)=ex+exexex
在这里插入图片描述

  • 输出范围在(-1, 1)之间,输出均值为0,使得它的收敛速度要比sigmoid快。
  • 同样会存在梯度消失问题,不过相较于sigmoid稍微缓解了梯度消失的程度。
  • 导数dtanh的值域在(0, 1)。

ReLU(Rectified Linear Units)

f ( x ) = { 0 , i f   x < 0 x , i f   x ≥ 0 \begin{aligned} & f(x) =\left\{ \begin{aligned} 0 &, &if \ x < 0 \\ x &, &if \ x \geq 0 \end{aligned} \right.\\ \end{aligned} f(x)={0x,,if x<0if x0
在这里插入图片描述

  • 当输入大于0时,输出等于输入;当输入小于等于0时,输出为0,权重无法更新。
  • 简单且计算效率高,有效缓解了梯度消失的问题。
  • 与sigmoid类似,ReLU的输出均值也大于0,偏移现象神经元死亡会共同影响网络的收敛性。

Leaky-ReLU & L-ReLU

f ( x ) = { α x , i f   x < 0 x , i f   x ≥ 0 \begin{aligned} & f(x) =\left\{ \begin{aligned} \alpha x &, &if \ x < 0 \\ x &, &if \ x \geq 0 \end{aligned} \right.\\ \end{aligned} f(x)={αxx,,if x<0if x0
在这里插入图片描述

  • 在标准ReLU的基础上,对于负半轴的输入赋予了一个小的斜率,从而弥补了ReLU负半轴输出为0导致权重不更新的问题。

softmax

f ( x ) = e i ∑ i = 1 n e i \begin{aligned} f(x) = \frac{e^{i}}{\sum_{i=1}^{n}e^{i}} \end{aligned} f(x)=i=1neiei

在这里插入图片描述

  • 用于多类分类问题的激活函数,值在[0 , 1]范围内,并且向量中元素总和为1。
  • softmax的负半轴的输出接近0,反向传播时该部分的权重几乎不更新。

swish

f ( x ) = x ⋅ s i g m o i d ( β x ) \begin{aligned} f(x) = x\cdot sigmoid(\beta x) \end{aligned} f(x)=xsigmoid(βx)
β \beta β 是常数或者经过学习得到的参数。当 β = 1 \beta = 1 β=1

在这里插入图片描述

  • 与ReLU不同,swish函数全范围内都连续可微。实验表明,Swish作为激活函数经常会获得比ReLU更高的分类精度。但是,与ELU同样,由于需要计算幂函数,其计算代价较高。

numpy实现

import matplotlib.pyplot as plt
import numpy as np


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

def dsigmoid(x):
    return sigmoid(x) * (1 - sigmoid(x))

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

def dtanh(x):
    return 1 - tanh(x) ** 2

def relu(x):
    return np.where(x < 0, 0, x)

def drelu(x):
    x = np.where(x < 0, 0, x)
    x = np.where(x > 0, 1, x)
    return x

def lrelu(x, alpha=0.2):
    y = np.piecewise(x, [x >= 0, x < 0], [lambda x: x, lambda x: alpha * x])

    x = np.where(x >= 0, 1, x)
    dy = np.where(x < 0, alpha, x)
    return (y, dy)

def softmax(x):
    return np.exp(x) / np.sum(np.exp(x))

def dsoftmax(x):
    pass

def swish(x, beta=1.0):
    return x * sigmoid(beta * x)

def dswish(x, beta=1.0):
    sig = sigmoid(beta * x)
    dy = sig * (1 + x * beta * (1 - sig))
    return dy


if __name__ == "__main__":
    x = np.linspace(-10.0, 10.0, num=10, endpoint=True)

    # plt.plot(x, sigmoid(x), label="sigmoid")
    # plt.plot(x, dsigmoid(x), label="dsigmoid")

    # plt.plot(x, tanh(x), label="tanh")
    # plt.plot(x, dtanh(x), label="dtanh")

    # plt.plot(x, relu(x), label="relu")
    # plt.plot(x, drelu(x), label="drelu")

    # plt.plot(x, lrelu(x)[0], label="lrelu")
    # plt.plot(x, lrelu(x)[1], label="dlrelu")

    # x = np.linspace(-5.0, 5.0, num=100, endpoint=True)
    # plt.plot(x, softmax(x), label="softmax")

    beta = 1
    plt.plot(x, swish(x, beta), label="swish")
    plt.plot(x, dswish(x, beta), label="dswish")

    plt.grid()
    plt.legend()
    plt.show()

小结

一句话 激活函数就是为了增加模型的非线性表达能力和学习到更复杂的映射关系

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值