查看原文
其他

终于把神经网络中的激活函数搞懂了!!

程序员小寒 程序员学长
2024-09-13
大家好,我是小寒
今天给大家分享神经网络中的一个关键知识点,激活函数
激活函数(Activation Function)是神经网络的重要组成部分。它的主要作用是引入非线性,使得神经网络能够处理复杂的模式和关系。

如果没有激活函数,神经网络的每一层都是线性变换,整个网络就相当于一个线性模型,无论网络的深度如何,都只能解决线性可分问题,无法解决复杂的非线性问题。

如上图所示,这是一个基本神经元,输入为  ,然后,计算加权和为 接下来,我们对其应用激活函数以产生输出。

常见的非线性激活函数

1. Sigmoid 函数

Sigmoid 函数将输入值压缩到 (0,1) 的区间内,表达式为:

特点:

  • 输出范围,输出值位于 (0,1) 之间,通常用于输出层预测概率。

  • 非对称性,输出值集中在 0 和 1 之间,但不对称于零。

  • 梯度消失问题,对于非常大的正或负输入值,梯度(导数)接近于零,导致在深层网络中梯度消失,从而影响模型的训练。

  • 应用场景,常用于二分类任务的输出层。

import numpy as np

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

# Example usage
inputs = np.array([0, 1, 2])
outputs = sigmoid(inputs)
print(outputs)  
# Output: [0.5        0.73105858 0.88079708]

2.Tanh 函数

Tanh 函数的表达式为:

特点:
  • 输出范围,输出值在−1到1之间,中心对称于零。
  • 梯度消失问题,与 Sigmoid 相似,对于非常大的输入值,梯度趋于零,容易导致梯度消失。
  • 应用场景,常用于隐藏层,在数据零均值化后,Tanh 的表现优于 Sigmoid。

import numpy as np

def tanh(x):
    return np.tanh(x)

# Example usage
inputs = np.array([0, 1, 2])
outputs = tanh(inputs)
print(outputs)  
# Output: [0.         0.76159416 0.96402758]

3. ReLU 函数

ReLU 是最常用的激活函数之一,表达式为:

特点:

  • 输出范围,输出值在 之间。
  • 缓解梯度消失,ReLU 的输出非负,且对于正数部分,梯度为 1,有助于缓解梯度消失问题。
  • 死亡神经元问题,当输入为负数时,输出为 0,且梯度为 0,导致这些神经元在后续训练中无法更新,这种现象称为“死亡神经元”。
  • 应用场景,广泛用于各种深度神经网络,尤其是卷积神经网络(CNN)中。

import numpy as np

def relu(x):
    return np.maximum(0, x)

# Example usage
inputs = np.array([-1, 0, 1])
outputs = relu(inputs)
print(outputs)  
# Output: [0 0 1]

4. Leaky ReLU 函数

Leaky ReLU 是 ReLU 的一种改进版,允许负输入值有一个很小的斜率(通常为 0.01),表达式为:

其中, 是一个小的正数(例如 0.01)。

特点:

  • 缓解死亡神经元问题,通过在负输入时提供一个小的梯度,Leaky ReLU 解决了 ReLU 中的神经元死亡问题。

import numpy as np

def leaky_relu(x, alpha=0.01):
    return np.where(x > 0, x, alpha * x)

# Example usage
inputs = np.array([-1, 0, 1])
outputs = leaky_relu(inputs)
print(outputs)  
# Output: [-0.01  0.    1.  ]

5. PReLU 函数

PReLU(Parametric ReLU)是 Leaky ReLU 的进一步推广,允许负输入的斜率 作为可学习的参数。
其表达式为:

其中 是通过训练学习得到的参数,而不是预先固定的值。

特点:

  • 自适应,允许模型通过训练自动调整负输入部分的斜率,从而更好地适应数据分布。

  • 缓解神经元死亡问题,与 Leaky ReLU 相似,通过负输入的非零梯度,缓解神经元死亡问题。

  • 应用场景,在需要更灵活的激活函数时使用,特别是在深层神经网络中。

import numpy as np

class PReLU:
    def __init__(self, alpha_init=0.01):
        self.alpha = alpha_init

    def forward(self, x):
        return np.maximum(self.alpha * x, x)

    def update_alpha(self, new_alpha):
        self.alpha = new_alpha

# Example usage
inputs = np.array([-1, 0, 1])
prelu = PReLU(alpha_init=0.1)
outputs = prelu.forward(inputs)
print(outputs)  
# Output: [-0.1  0.   1. ]

6. ELU 函数

ELU 引入了指数函数来平滑负输入区域,表达式为:

其中, 是一个大于 0 的超参数,通常取值为 1。

特点:

  • 负饱和性,ELU 在负输入时饱和到一个负值,从而有助于产生更鲁棒的网络权重,避免死亡神经元现象。

  • 平滑性,由于指数部分的存在,ELU 在负数区域具有更平滑的导数,这在某些情况下可以带来更稳定的训练过程。

  • 缓解梯度消失问题,与 ReLU 相比,ELU 可以在负数区域生成更大的梯度,缓解梯度消失问题。

import numpy as np

def elu(x, alpha=1.0):
    return np.where(x > 0, x, alpha * (np.exp(x) - 1))

# Example usage
inputs = np.array([-1, 0, 1])
outputs = elu(inputs)
print(outputs)  
# Output: [-0.63212056  0.          1.        ]


最后



今天的分享就到这里。如果觉得近期的文章不错,请点赞,转发安排起来。‍‍欢迎大家进高质量 python 学习群

「进群方式:加我微信,备注 “python”」



往期回顾


Fashion-MNIST 服装图片分类-Pytorch实现

python 探索性数据分析(EDA)案例分享

深度学习案例分享 | 房价预测 - PyTorch 实现

万字长文 |  面试高频算法题之动态规划系列

面试高频算法题之回溯算法(全文六千字)  

    



如果对本文有疑问可以加作者微信直接交流。

继续滑动看下一个
程序员学长
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存