机器学习复习(5)——激活函数

目录

激活函数分类

区别与优缺点

饱和激活函数

非饱和激活函数

综合考虑

Sigmoid激活函数

Tanh激活函数

ReLU激活函数

Leaky Relu激活函数

Swish激活函数

激活函数分类

激活函数可以分为两大类 :

  • 饱和激活函数:sigmoid、tanh
  • 非饱和激活函数: ReLU、Leaky Relu、ELU【指数线性单元】、PReLU【参数化的ReLU 】、RReLU【随机ReLU】

区别与优缺点

饱和激活函数

  1. Sigmoid:

    • 优点:
      • 平滑,输出值在0到1之间,适合用于输出概率。
      • 易于理解和实现。
    • 缺点:
      • 梯度消失问题:当输入值过大或过小时,梯度接近0,使得网络难以学习。
      • 输出不是零中心的:使得优化过程更加复杂。
    • 应用场景: 主要用于二分类问题,如逻辑回归中。
  2. Tanh:

    • 优点:
      • 输出值在-1到1之间,是零中心的,有利于数据的表示。
      • 比Sigmoid更加有效,因为其梯度更强。
    • 缺点:
      • 同样存在梯度消失问题。
    • 应用场景: 适合处理需要考虑正负数的场景,如音频处理。

非饱和激活函数

  1. ReLU(Rectified Linear Unit):

    • 优点:
      • 计算简单,加速了网络的训练。
      • 缓解了梯度消失问题,特别是在网络较深时。
    • 缺点:
      • “死亡ReLU”问题:部分神经元可能永远不会被激活,导致信息丢失。
    • 应用场景: 目前在大多数深度学习网络中被广泛使用,特别是在卷积神经网络中。
  2. Leaky ReLU, PReLU, ELU 等变体:

    • 优点:
      • 尝试解决死亡ReLU问题。
      • 在某些情况下,可以提供比标准ReLU更好的性能。
    • 缺点:
      • 可能会导致训练过程更复杂。
    • 应用场景: 在需要缓解死亡ReLU问题的场景下,如GANs或更深的网络结构。

综合考虑

  • 在选择激活函数时,应根据具体问题和网络结构来决定。
  • 对于一般的深度学习问题,ReLU及其变体通常是首选,因为它们提供了良好的性能和快速的训练。
  • 对于需要输出概率或者处理更复杂的非线性问题的场景,可能会考虑使用Sigmoid或Tanh。

Sigmoid激活函数

sigmoid函数也叫Logistic函数,用于隐藏层的输出,输出在(0,1)之间,它可以将一个实数映射到(0,1)的范围内,可以用来做二分类。常用于:在特征相差比较复杂或是相差不是特别大的时候效果比较好。该函数将大的负数转换成0,将大的正数转换为1。公式描述如下:

实现代码:

import numpy as np
import matplotlib.pyplot as plt

# 定义sigmoid函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 生成一系列点
x = np.linspace(-10, 10, 100)
y = sigmoid(x)

# 绘制图像
plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("Sigmoid(x)")
plt.title("Sigmoid Function")
plt.grid(True)
plt.show()

 如图所示:

Tanh激活函数

Tanh 激活函数又叫作双曲正切激活函数(hyperbolic tangent activation function)。

公式如下:

实现代码:

import matplotlib.pyplot as plt
import math
def tanh(x):
    return (math.exp(x) - math.exp(-x)) / (math.exp(x) + math.exp(-x))
# 生成一系列点
x_values = [x * 0.1 for x in range(-100, 101)]
y_values = [tanh(x) for x in x_values]

# 绘制图像
plt.plot(x_values, y_values)
plt.xlabel("x")
plt.ylabel("tanh(x)")
plt.title("Tanh Activation Function")
plt.grid(True)
plt.show()

如图所示:

与 Sigmoid 函数类似,Tanh 函数也使用真值,但 Tanh 函数将其压缩至-1 到 1 的区间内。与 Sigmoid 不同,Tanh 函数的输出以零为中心,因为区间在-1 到 1 之间。你可以将 Tanh 函数想象成两个 Sigmoid 函数放在一起。在实践中,Tanh 函数的使用优先性高于 Sigmoid 函数。负数输入被当作负值,零输入值的映射接近零,正数输入被当作正值。

优点:它解决了Sigmoid函数的不是zero-centered输出问题。

缺点:梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。 

ReLU激活函数

Relu激活函数的解析式:

实现代码:

import numpy as np
import matplotlib.pyplot as plt

# 定义ReLU函数
def relu(x):
    return np.maximum(0, x)

# 生成一系列点
x = np.linspace(-10, 10, 100)
y = relu(x)

# 绘制图像
plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("ReLU(x)")
plt.title("ReLU Activation Function")
plt.grid(True)
plt.show()

如图所示: 

 当输入 x<0 时,输出为 0,当 x> 0 时,输出为 x。该激活函数使网络更快速地收敛。它不会饱和,即它可以对抗梯度消失问题,至少在正区域(x> 0 时)可以这样,因此神经元至少在一半区域中不会把所有零进行反向传播。由于使用了简单的阈值化(thresholding),ReLU 计算效率很高。

Relu激活函数缺点:

  • 不以零为中心:和 Sigmoid 激活函数类似,ReLU 函数的输出不以零为中心。
  • 前向传导(forward pass)过程中,如果 x < 0,则神经元保持非激活状态,且在后向传导(backward pass)中「杀死」梯度。这样权重无法得到更新,网络无法学习。当 x = 0 时,该点的梯度未定义,但是这个问题在实现中得到了解决,通过采用左侧或右侧的梯度的方式。

尽管存在这两个问题,ReLU目前仍是最常用的activation function,在搭建人工神经网络的时候推荐优先尝试!

Leaky Relu激活函数

Leaky Relu激活函数的解析式:

 实现代码:

import numpy as np
import matplotlib.pyplot as plt

# 定义Leaky ReLU函数
def leaky_relu(x, alpha=0.01):
    return np.where(x >= 0, x, alpha * x)

# 生成一系列点
x = np.linspace(-10, 10, 100)
y = leaky_relu(x)

# 绘制图像
plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("Leaky ReLU(x)")
plt.title("Leaky ReLU Activation Function")
plt.grid(True)
plt.show()

如图所示:

Leaky ReLU 的概念是:当 x < 0 时,它得到 0.01 的正梯度。

优点:

该函数一定程度上缓解了 dead ReLU 问题。

缺点:

使用该函数的结果并不连贯。尽管它具备 ReLU 激活函数的所有特征,如计算高效、快速收敛、在正区域内不会饱和。

Leaky ReLU 可以得到更多扩展。不让 x 乘常数项,而是让 x 乘超参数,这看起来比 Leaky ReLU 效果要好。该扩展就是 Parametric ReLU。

Swish激活函数

Swish激活函数是一个较新的激活函数,公式如下:

实现代码:

import numpy as np
import matplotlib.pyplot as plt

# 定义Swish函数
def swish(x, beta=1):
    return x * (1 / (1 + np.exp(-beta * x)))

# 生成一系列点
x = np.linspace(-10, 10, 100)
y = swish(x)

# 绘制图像
plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("Swish(x)")
plt.title("Swish Activation Function")
plt.grid(True)
plt.show()

如图所示:

 根据上图,从图像上来看,Swish函数跟ReLu差不多,唯一区别较大的是接近于0的负半轴区域,因此,Swish 激活函数的输出可能下降,即使在输入值增大的情况下。大多数激活函数是单调的,即输入值增大的情况下,输出值不可能下降。而 Swish 函数为 0 时具备单侧有界(one-sided boundedness)的特性,它是平滑、非单调的。

缺点: - 只有实验证明,没有理论支持。 - 在浅层网络上,性能与relu差别不大。

相关推荐

  1. 深度学习 - 激活函数

    2024-01-31 00:12:02       6 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-31 00:12:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-31 00:12:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-31 00:12:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-31 00:12:02       18 阅读

热门阅读

  1. SpringMVC初始化源码学习

    2024-01-31 00:12:02       34 阅读
  2. Chinese and English names of 45 common character symbols

    2024-01-31 00:12:02       27 阅读
  3. Map和Set

    Map和Set

    2024-01-31 00:12:02      33 阅读
  4. 如何编写.gitignore文件

    2024-01-31 00:12:02       28 阅读
  5. C++入门

    C++入门

    2024-01-31 00:12:02      31 阅读
  6. ESLint代码检查系列 ——入门篇

    2024-01-31 00:12:02       36 阅读