激活函数:Sigmoid、Tanh、ReLU、Leaky ReLU、Swish、GELU

一句话概述

激活函数是神经网络中引入非线性的关键组件,如果没有激活函数,无论堆叠多少层,整个网络都等价于一个线性变换。从早期广泛使用的Sigmoid和Tanh,到解决梯度消失问题的ReLU及其变体(Leaky ReLU),再到近年提出的自门控激活函数Swish和基于高斯误差函数的GELU,每一种激活函数都有其独特的数学性质和适用场景。理解激活函数的特性是设计和训练深度神经网络的基础。

💡 核心要点:①激活函数的核心作用是引入非线性,使网络能拟合任意复杂函数 ②Sigmoid和Tanh是早期常用的S型激活函数,但存在梯度饱和问题 ③ReLU及其变体(Leaky ReLU)是目前最广泛使用的激活函数,有效缓解梯度消失 ④Swish和GELU是新一代激活函数,在Transformer等现代架构中表现优异

教学与演示

一、激活函数的作用与非线性的必要性

是什么(定义):激活函数(Activation Function)是作用于神经元线性输出 z = w·x + b 之上的非线性函数 f(z),最终输出 a = f(z)。它将线性变换的结果映射到一个非线性空间,赋予神经网络表达非线性关系的能力。

大白话 激活函数就像翻译官——把神经元算出来的"线性分数"翻译成真正有区分力的"语义信号"。没有翻译官,再多神经元也只能说同一种"线性"语言,表达能力大打折扣。

为什么(原理):线性函数的复合仍然是线性的。如果没有激活函数,一个 N 层的全连接网络等价于一个单层线性变换:W_N(W_{N-1}(...(W_1 x)...)) = W_effective · x。这意味着深层网络退化为浅层网络,完全失去了"深度"的意义。激活函数通过引入非线性,打破了这种退化,使得网络能够逼近任意复杂的函数。这是万能近似定理(Universal Approximation Theorem)的基础。

大白话 想象你在和面:不加激活函数等于永远只用一只手揉——再怎么揉都是一层面。加上激活函数等于两只手配合,能揉出各种形状的面团。线性变换给出"形状",激活函数给出"花样"。

什么用(AI关联):激活函数的选择直接影响网络的训练速度、收敛性能和最终准确率。在深度学习中,ReLU已经成为隐藏层的默认选择,Sigmoid通常只用于二分类输出层,Softmax用于多分类输出层,GELU在Transformer(如BERT、GPT)中广泛使用。

哪些坑(缺点):没有一种激活函数是万能的。Sigmoid和Tanh容易导致梯度消失,ReLU可能造成神经元"死亡",Leaky ReLU引入了需要调参的斜率,Swish和GELU计算开销较大。选择激活函数需要根据具体场景权衡。

二、Sigmoid 激活函数

是什么(定义):Sigmoid函数(也称为Logistic函数)将任意实数输入映射到(0, 1)区间,其数学形式为 σ(x) = 1/(1 + e^{-x})。它是早期神经网络中最广泛使用的激活函数,也是逻辑回归中使用的函数。

大白话 Sigmoid就像一个"概率翻译器"——不管输入多大或多小,它都给压缩到0到1之间,输出可以解读为"这件事发生的概率"。

怎么做(实现)

import numpy as np

# ========================================
# Sigmoid 激活函数 —— 最早的平滑激活函数
# 将任意实数映射到 (0, 1) 区间
# ========================================

def sigmoid(x):
    """
    Sigmoid 激活函数: σ(x) = 1 / (1 + e^(-x))
    参数:
        x: 输入值(标量或numpy数组)
    返回:
        (0, 1) 之间的输出值
    性质:
        输出范围:(0, 1),呈S型曲线
        中心对称:关于 (0, 0.5) 中心对称
        饱和区:|x| 较大时梯度趋近于 0
    """
    # 使用 numpy 的 exp 函数,支持向量化计算
    # 注意:对于很大的负值,exp(-x) 可能溢出
    # 实际框架中使用 safe_sigmoid 避免数值问题
    return 1.0 / (1.0 + np.exp(-x))


def sigmoid_derivative(x):
    """
    Sigmoid 导数: σ'(x) = σ(x) * (1 - σ(x))
    这是反向传播中计算梯度时需要的
    导数在 x=0 处最大,为 0.25;在 |x| 增大时迅速趋近于 0
    """
    s = sigmoid(x)
    return s * (1.0 - s)


# --- 演示 Sigmoid 在不同输入值下的输出 ---
print("Sigmoid 函数演示:")
test_inputs = np.array([-5.0, -2.0, -1.0, 0.0, 1.0, 2.0, 5.0])
for x_val in test_inputs:
    y_val = sigmoid(x_val)
    dy_val = sigmoid_derivative(x_val)
    print(f"  σ({x_val:+.1f}) = {y_val:.4f}, 导数 = {dy_val:.4f}")

# --- 展示 Sigmoid 的饱和特性 ---
print("\n饱和特性分析:")
big_neg = -10.0  # 很大的负数
big_pos = 10.0   # 很大的正数
print(f"  σ({big_neg}) = {sigmoid(big_neg):.6f}  ← 趋近于 0")
print(f"  σ({big_pos})  = {sigmoid(big_pos):.6f}  ← 趋近于 1")
print(f"  导数在 ±10 处: {sigmoid_derivative(big_pos):.10f} ← 几乎为 0,梯度消失!")
Sigmoid函数定义\(\sigma(x) = \frac{1}{1 + e^{-x}}\)
大白话 Sigmoid的公式:分母1+e^{-x},当x特别大时e^{-x}≈0,分母≈1,结果≈1;当x特别小时e^{-x}巨大,分母巨大,结果≈0。这就是它把一切压到0和1之间的奥秘。

什么用(AI关联):Sigmoid主要用于二分类问题的输出层,将输出解释为属于正类的概率。在早期浅层网络中也被用作隐藏层激活函数。逻辑回归本质上就是Sigmoid+线性组合。

哪些坑(缺点):①梯度饱和:当|x|较大时,导数趋近于0,导致反向传播中梯度消失,深层网络几乎无法更新前面层的参数。②输出不是零均值的(输出中心约0.5),导致后层神经元接收到非零均值的输入,影响梯度下降效率。③涉及指数运算,计算开销较大。

三、Tanh(双曲正切)激活函数

是什么(定义):Tanh(Hyperbolic Tangent,双曲正切)函数将输入映射到(-1, 1)区间,数学形式为 tanh(x) = (e^x - e^{-x})/(e^x + e^{-x})。它是Sigmoid的线性变换:tanh(x) = 2σ(2x) - 1。

大白话 Tanh可以看作Sigmoid的"升级版"——输出范围从(0,1)变成了(-1,1),零均值输出了,但饱和问题依然存在。

怎么做(实现)

import numpy as np

# ========================================
# Tanh 激活函数 —— 零中心化的 S 型函数
# 将任意实数映射到 (-1, 1) 区间
# ========================================

def tanh(x):
    """
    Tanh 双曲正切激活函数
    数学定义: tanh(x) = (e^x - e^(-x)) / (e^x + e^(-x))
    numpy 内置了 tanh 函数,效率更高
    参数:
        x: 输入值
    返回:
        (-1, 1) 之间的输出值
    """
    return np.tanh(x)


def tanh_derivative(x):
    """
    Tanh 导数: tanh'(x) = 1 - tanh^2(x)
    导数在 x=0 时达到最大值 1.0(比 Sigmoid 的最大 0.25 大 4 倍)
    在 |x| 增大时同样趋近于 0
    """
    return 1.0 - np.tanh(x) ** 2


# --- 对比 Sigmoid 和 Tanh ---
print("Sigmoid vs Tanh 对比:")
test_vals = np.array([-3.0, -1.0, 0.0, 1.0, 3.0])
for x_val in test_vals:
    s_val = 1.0 / (1.0 + np.exp(-x_val))  # Sigmoid
    t_val = np.tanh(x_val)                # Tanh
    s_grad = s_val * (1.0 - s_val)        # Sigmoid导数
    t_grad = 1.0 - t_val ** 2             # Tanh导数
    print(f"  x={x_val:+.1f}: Sigmoid={s_val:+.4f}, Tanh={t_val:+.4f}")
    print(f"          Sigmoid'={s_grad:.4f}, Tanh'={t_grad:.4f}")

# --- 验证 Sigmoid 和 Tanh 的关系 ---
print("\n验证关系:tanh(x) = 2σ(2x) - 1")
x_test = 1.5
tanh_val = np.tanh(x_test)
sigmoid_based = 2.0 / (1.0 + np.exp(-2.0 * x_test)) - 1.0
print(f"  tanh({x_test}) = {tanh_val:.6f}")
print(f"  2σ(2*{x_test})-1 = {sigmoid_based:.6f}")
print(f"  差值: {abs(tanh_val - sigmoid_based):.2e}")

# --- 均值分析 ---
many_vals = np.random.randn(1000)  # 标准正态分布采样1000个点
sigmoid_outputs = 1.0 / (1.0 + np.exp(-many_vals))
tanh_outputs = np.tanh(many_vals)
print(f"\n输出均值(理想应为0):")
print(f"  Sigmoid 输出均值: {np.mean(sigmoid_outputs):.4f} — 偏向正值")
print(f"  Tanh 输出均值:     {np.mean(tanh_outputs):.4f} — 接近零均值")
Tanh函数定义\(\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} = 2\sigma(2x) - 1\)
大白话 Tanh就是Sigmoid的"拉偏和放大"版:先把输入放大2倍过Sigmoid,再乘以2减1。结果是输出以0为中学,梯度最大值1.0(比Sigmoid的0.25好很多),但两端饱和的毛病依然在。

什么用(AI关联):Tanh在RNN和LSTM中经常用作隐藏状态的激活函数,因为其零均值特性有助于稳定训练。在一些生成模型中也常用。不过在现代CNN和Transformer中,Tanh基本被ReLU和GELU取代。

哪些坑(缺点):虽然比Sigmoid好(零均值、梯度更大),但饱和问题同样存在。在深层网络中,经过多层Tanh后梯度依然会趋近于零。

四、ReLU(修正线性单元)

是什么(定义):ReLU(Rectified Linear Unit,修正线性单元)是目前深度学习中最广泛使用的激活函数。其数学形式极其简单:f(x) = max(0, x)。当输入为负时输出0,输入为正时输出等于输入本身。

大白话 ReLU就是"有则照搬,无则闭嘴"——正数直接通过,负数全部挡掉。简单粗暴但出奇有效,是深度学习复兴的"幕后功臣"。

为什么(原理):ReLU的设计有两个核心优势:①正半轴梯度恒为1,完美避免了Sigmoid/Tanh的梯度饱和问题,使得深层网络的梯度可以畅通无阻地传播。②计算极其简单(只需要比较和判断),比指数运算快得多。③输出具有稀疏性——大约50%的神经元输出为0,这种稀疏激活在一定程度上模仿了生物神经元的特性。

怎么做(实现)

import numpy as np

# ========================================
# ReLU 激活函数 —— 深度学习的"国标"激活函数
# 简单、高效、解决了梯度消失问题
# ========================================

def relu(x):
    """
    ReLU 激活函数: f(x) = max(0, x)
    参数:
        x: 输入值(标量或numpy数组)
    返回:
        max(0, x),所有负值被置为 0
    关键性质:
        - 正半轴导数恒为 1(无梯度饱和)
        - 负半轴导数为 0(可能导致神经元"死亡")
        - 计算量极小(仅需比较操作)
    """
    return np.maximum(0, x)


def relu_derivative(x):
    """
    ReLU 导数: f'(x) = 1 if x > 0 else 0
    注意: 在 x=0 处数学上不可导,实际中通常取 0 或 0.5
    """
    return np.where(x > 0, 1.0, 0.0)


def leaky_relu(x, alpha=0.01):
    """
    Leaky ReLU: f(x) = max(αx, x)
    给负半轴一个很小的斜率 α,避免神经元彻底"死亡"
    参数:
        x: 输入值
        alpha: 负半轴斜率,通常取 0.01
    """
    return np.where(x > 0, x, alpha * x)


# --- ReLU 基本演示 ---
print("ReLU 函数演示:")
test_vals = np.array([-5.0, -2.0, -0.5, 0.0, 0.5, 2.0, 5.0])
for x_val in test_vals:
    y_val = relu(x_val)
    dy_val = relu_derivative(x_val)
    print(f"  ReLU({x_val:+.1f}) = {y_val:+.1f}, 导数 = {dy_val:.1f}")

# --- Leaky ReLU vs ReLU ---
print("\nReLU vs Leaky ReLU(α=0.01)负值区对比:")
neg_vals = np.array([-3.0, -1.0, -0.1])
for x_val in neg_vals:
    r_val = relu(x_val)
    lr_val = leaky_relu(x_val, alpha=0.01)
    print(f"  x={x_val:+.1f}: ReLU={r_val:.3f}, Leaky ReLU={lr_val:.3f}")

# --- 神经元死亡演示 ---
print("\n'死神经元'模拟:")
# 假设一个神经元权重更新后,对所有样本都输出负值
np.random.seed(42)
weights = np.array([-1.0, -1.0])  # 全部负权重
samples = np.random.randn(10, 2)  # 10个样本
for i, sample in enumerate(samples):
    z = np.dot(weights, sample)
    a = relu(z)
    grad = relu_derivative(z)
    print(f"  样本{i+1}: z={z:+.2f}, ReLU={a:.2f}, 梯度={grad:.1f}")
print("  → 所有梯度都为 0,这个神经元已经'死'了,再也不会更新!")
ReLU函数定义\(\text{ReLU}(x) = \max(0, x) = \begin{cases} x, & \text{如果 } x > 0 \\ 0, & \text{如果 } x \leq 0 \end{cases}\)
大白话 ReLU就是一个"选择性过滤器":好消息(正信号)放大通过,坏消息(负信号)直接屏蔽。正半轴的梯度永远是1,没有Sigmoid那种"传着传着就没了"的问题。

什么用(AI关联):ReLU是CNN中的默认激活函数,几乎所有经典CNN架构(VGG、ResNet、Inception等)都使用ReLU。在MLP中也广泛使用。它的发明是深度学习复兴的标志性事件之一。

哪些坑(缺点):主要问题是"死神经元"(Dying ReLU)——如果权重更新导致某个神经元的输出恒为负,该神经元梯度永远为0,再也无法恢复。这在高学习率或不合理的权重初始化时尤其容易发生。Leaky ReLU、PReLU等变体正是为了解决这个问题。

五、Swish 与 GELU:新一代激活函数

是什么(定义):Swish(由Google Brain于2017年提出)定义为 f(x) = x · σ(βx),其中σ是Sigmoid函数,β是可学习的参数(或固定为1)。GELU(Gaussian Error Linear Unit,高斯误差线性单元)定义为 f(x) = x · Φ(x),其中Φ(x)是标准正态分布的累积分布函数。两者都采用了"自门控"(self-gating)机制——输入x既作为信号又控制自己的通过程度。

大白话 Swish和GELU都是"聪明的ReLU"——它们不粗暴地把负数全砍掉,而是根据输入的大小"平滑地决定"该放行多少。就像一个有经验的审核员,不会简单地"通过"或"拒绝",而是根据情况给出一个柔和的评分。

怎么做(实现)

import numpy as np

# ========================================
# Swish 和 GELU —— 新一代自门控激活函数
# 在 Transformer 等现代架构中表现优异
# ========================================

def swish(x, beta=1.0):
    """
    Swish 激活函数: f(x) = x * σ(βx)
    其中 σ 是 Sigmoid 函数,β 是缩放参数
    参数:
        x: 输入值
        beta: 可选缩放参数(默认1.0),控制门控的"软硬"程度
    性质:
        - 当 β→0 时,Swish → 线性函数 x/2
        - 当 β→∞ 时,Swish → ReLU
        - 平滑可导,无死区
    """
    return x * (1.0 / (1.0 + np.exp(-beta * x)))


def gelu(x):
    """
    GELU 激活函数(精确版): f(x) = x * Φ(x)
    其中 Φ(x) 是标准正态分布的累积分布函数(CDF)
    实际中常用近似公式以提高计算效率
    参数:
        x: 输入值
    性质:
        - 比 Swish 更加平滑
        - 在 Transformer(BERT、GPT)中广泛使用
        - 期望激活率约为 50%
    """
    # 精确版:x * Φ(x),其中 Φ(x) = 0.5 * (1 + erf(x/√2))
    # erf 是误差函数
    return 0.5 * x * (1.0 + np.tanh(
        np.sqrt(2.0 / np.pi) * (x + 0.044715 * x ** 3)
    ))


def gelu_approx(x):
    """
    GELU 近似公式(常用,更快)
    GELU(x) ≈ 0.5 * x * (1 + tanh(√(2/π) * (x + 0.044715 * x³)))
    """
    sqrt_2_over_pi = np.sqrt(2.0 / np.pi)
    return 0.5 * x * (1.0 + np.tanh(sqrt_2_over_pi * (x + 0.044715 * x ** 3)))


# --- 四种激活函数对比 ---
print("ReLU vs Leaky ReLU vs Swish vs GELU 对比:")
test_vals = np.array([-3.0, -1.0, -0.1, 0.0, 0.1, 1.0, 3.0])
for x_val in test_vals:
    r = np.maximum(0, x_val)                                    # ReLU
    lr = np.where(x_val > 0, x_val, 0.01 * x_val)              # Leaky ReLU
    sw = x_val / (1.0 + np.exp(-x_val))                         # Swish(β=1)
    gl = 0.5 * x_val * (1.0 + np.tanh(                         # GELU
        np.sqrt(2.0/np.pi) * (x_val + 0.044715 * x_val**3)))
    print(f"  x={x_val:+.1f}: ReLU={r:+.4f}, LReLU={lr:+.4f}, Swish={sw:+.4f}, GELU={gl:+.4f}")

# --- Swish 的 β 参数效应 ---
print("\nSwish 的 β 参数效应:")
x_test = np.array([-2.0, -0.5, 0.0, 0.5, 2.0])
for beta in [0.1, 1.0, 10.0]:
    print(f"  β={beta:.1f}: ", end="")
    for x_val in x_test:
        out = x_val / (1.0 + np.exp(-beta * x_val))
        print(f"{out:+.4f} ", end="")
    print()

# --- 可视化对比:输出值的平滑性 ---
print("\n负值区域的平滑性对比(Refined对比):")
fine_neg = np.array([-2.0, -1.5, -1.0, -0.5, -0.1, -0.01])
for x_val in fine_neg:
    r = np.maximum(0, x_val)
    sw = x_val / (1.0 + np.exp(-x_val))
    gl = gelu_approx(x_val)
    print(f"  x={x_val:+.2f}: ReLU={r:.5f}(硬截断), Swish={sw:.5f}(平滑), GELU={gl:.5f}(平滑)")
Swish与GELU定义\(\text{Swish}(x) = x \cdot \sigma(\beta x) = \frac{x}{1 + e^{-\beta x}}\)
GELU定义\(\text{GELU}(x) = x \cdot \Phi(x) \approx 0.5x\left(1 + \tanh\left(\sqrt{\frac{2}{\pi}}(x + 0.044715x^3)\right)\right)\)
大白话 Swish = x · Sigmoid(x),可以看作ReLU的"软化版"——负值不会被粗暴地砍为0,而是逐渐趋近于0。GELU更进一步,用正态分布的累积概率来门控,比Swish还要平滑。两者的共同思想是"让数据自己决定该通过多少"。

什么用(AI关联):Swish在EfficientNet等现代CNN中表现出色。GELU是目前Transformer架构的标准激活函数——BERT、GPT系列、ViT等都使用GELU。选择GELU的核心原因是它在保持非线性的同时,比ReLU的梯度传播更加平滑,这对基于自注意力的架构尤为重要。

哪些坑(缺点):两者计算开销大于ReLU(需要指数/tanh运算),在推理阶段可能成为瓶颈。GELU的精确计算需要误差函数erf,实践中都用近似公式。另外,这些新激活函数主要在大模型和深层网络中才有明显优势,小网络上ReLU通常就够用了。

六、激活函数的选择策略

是什么(定义):激活函数选择是在特定任务和网络架构下,根据数学特性和实践经验做出决策的过程。没有一种激活函数在所有场景下都是最优的,需要根据网络深度、任务类型和计算资源权衡。

大白话 选激活函数就像选工具——不同的活需要不同的工具。ReLU是瑞士军刀(万能但不够精细),GELU是精密仪器(效果好但贵),Sigmoid是专用工具(只适合做概率输出)。
激活函数输出范围适用场景主要优势主要劣势
Sigmoid(0, 1)二分类输出层、门控机制输出可解释为概率梯度消失、非零均值
Tanh(-1, 1)RNN隐藏状态零均值、梯度比Sigmoid大仍有饱和问题
ReLU[0, +∞)CNN/MLP隐藏层(默认)无饱和、计算快、稀疏激活死神经元
Leaky ReLU(-∞, +∞)替代ReLU防死亡解决死神经元问题额外超参数α
Swish(-∞, +∞)EfficientNet等现代CNN平滑、自门控、无死区计算量较大
GELU(-∞, +∞)Transformer(BERT/GPT)最平滑、与Dropout配合好计算量最大

概念关系图谱

概念核心含义与AI的关系关联概念
非线性激活函数引入的非直线关系,使网络能拟合复杂函数没有非线性就没有深度学习万能近似定理、复合函数
梯度饱和激活函数导数趋近于0的现象,阻碍反向传播导致深层网络训练困难梯度消失、Sigmoid饱和区
死神经元ReLU神经元输出恒为0,永远无法更新降低模型容量,影响性能Leaky ReLU、PReLU
自门控输入信号同时控制自身通过程度Swish和GELU的核心机制门控网络、LSTM门控
零均值输出激活函数输出以0为中心加速收敛,避免zigzag优化批归一化、Tanh
Softmax多分类输出层专用激活函数将输出转换为概率分布交叉熵损失、多分类

重点答疑

Q1: 为什么ReLU比Sigmoid在深层网络中效果好那么多?

ReLU在深层网络中占据主导地位主要有三个原因:①梯度流通性——正半轴梯度恒为1,反向传播时梯度可以无衰减地穿过数十层,而Sigmoid每传一层梯度至少衰减到原来的25%(最理想情况),实际中衰减更严重。②计算效率——max(0,x)只需一次比较操作,而Sigmoid需要指数运算和除法。③稀疏激活——负半轴输出为0,网络中的神经元平均只有约50%被激活,这种稀疏性带来了类似Dropout的正则化效果,同时计算量也更小。

大白话 把深层网络想象成传话游戏:Sigmoid每传一个人声音就小一圈,传完20个人基本没声了。ReLU则是传正的话原封不动,传负的话自动闭嘴——至少好消息能传到终点。

Q2: GELU和Swish看起来差不多,为什么Transformer选GELU?

两者确实非常相似——都是"x乘以某个门控值"的形式。但GELU的门控是标准正态分布的累积分布函数Φ(x),而Swish的门控是Sigmoid。Φ(x)的尾部比Sigmoid更"重"(即负值区的输出比Sigmoid稍大),这意味着GELU对负值的处理更平滑、梯度衰减更渐进。在Transformer中,自注意力机制对梯度的平滑性要求更高(因为注意力权重涉及大量的softmax和乘法),GELU的平滑性带来了更稳定的训练过程。

Q3: 激活函数和损失函数有什么关系?可以随便搭配吗?

不能随便搭配。激活函数和损失函数的搭配是神经网络设计中的关键决策:①Sigmoid输出层 + 交叉熵损失——这不是随意搭配,而是有深层原因的。交叉熵损失的导数会抵消Sigmoid的导数中的σ(1-σ)因子,最终得到一个简洁的梯度形式(y_pred - y_true),从而完美避免输出层Sigmoid饱和导致的梯度消失。②Softmax + 交叉熵——多分类的黄金组合,同理导数得到简洁形式。③MSE + Sigmoid输出层——不推荐,因为MSE的导数中保留了Sigmoid的饱和因子,容易产生梯度消失。

大白话 Sigmoid配交叉熵是一对"天生一对"——交叉熵的数学形式恰好能把Sigmoid导数里的"减速因子"给消掉。如果硬把Sigmoid配MSE,就像跑车配了牛车轮胎,快不起来。

章节单词汇总

英文音标术语/释义
Activation Function/ˌæktɪˈveɪʃən ˈfʌŋkʃən/激活函数,引入非线性的函数
Sigmoid/ˈsɪɡmɔɪd/S型激活函数,输出(0,1)之间
Tanh/tænʃ/双曲正切激活函数,输出(-1,1)之间
ReLU/ˈrɛluː/修正线性单元,max(0,x)
Leaky ReLU/ˈliːki ˈrɛluː/带泄漏的ReLU,负半轴有小斜率
Swish/swɪʃ/自门控激活函数,x·σ(x)
GELU/ˈdʒiːluː/高斯误差线性单元,用于Transformer
Gradient Saturation/ˈɡreɪdiənt ˌsætʃəˈreɪʃən/梯度饱和,导数趋近于零
Dying ReLU/ˈdaɪɪŋ ˈrɛluː/死神经元,ReLU输出恒为0
Self-gating/sɛlf ˈɡeɪtɪŋ/自门控,输入信号控制自身通过
Universal Approximation/ˌjuːnɪˈvɜːrsəl əˌprɒksɪˈmeɪʃən/万能近似定理,网络可逼近任意函数
Zero-centered/ˈzɪroʊ ˈsɛntərd/零均值,输出以0为中心

面试练习

Q1 [单选] 以下关于激活函数的说法,哪项是正确的?

  • A. 激活函数的作用是加快计算速度
  • B. 如果没有激活函数,多层网络等价于单层线性变换
  • C. Sigmoid是深层网络的首选激活函数
  • D. 激活函数必须在每层都不同
解答:激活函数的核心作用是引入非线性。没有激活函数时,多层线性变换的复合仍然是线性的,等价于单层。

Q2 [单选] ReLU函数的导数在x>0时的值是多少?

  • A. 恒为1
  • B. 随x增大而减小
  • C. 等于x
  • D. 恒为0.25
解答:ReLU在正半轴f(x)=x,导数f'(x)=1,恒定不变。这是ReLU避免梯度消失的关键。

Q3 [多选] 以下哪些是Sigmoid函数的缺点?

  • A. 当|x|较大时梯度趋近于0
  • B. 输出不是零均值的
  • C. 计算速度比ReLU快
  • D. 涉及指数运算,计算开销较大
解答:Sigmoid在饱和区梯度消失(A对),输出均值约0.5非零均值(B对),计算涉及exp相对较慢(D对)。ReLU计算比Sigmoid更快。

Q4 [单选] 什么是"Dying ReLU"问题?

  • A. ReLU函数输出太大导致溢出
  • B. 神经元对任何输入都输出0,梯度永远为0
  • C. ReLU函数计算速度变慢
  • D. ReLU导致网络过拟合
解答:当权重更新使神经元对所有输入都产生非正值时,ReLU输出恒为0,梯度也为0,该神经元再也无法更新,称为"死亡"。

Q5 [单选] 在Transformer(如BERT)中,通常使用哪种激活函数?

  • A. Sigmoid
  • B. ReLU
  • C. GELU
  • D. Tanh
解答:GELU是Transformer架构的标准激活函数,BERT、GPT、ViT等都使用GELU。

Q6 [多选] 以下关于Leaky ReLU的说法,哪些是正确的?

  • A. 在负半轴有一个固定的小斜率,如0.01
  • B. 可以缓解Dying ReLU问题
  • C. 负半轴的输出和ReLU完全相同
  • D. 它比ReLU计算更简单
解答:Leaky ReLU在x<0时输出αx(α为小正数如0.01),给负值区一个非零梯度,避免神经元完全死亡。它略微增加了计算复杂度(需要乘法)。

Q7 [单选] Swish激活函数的表达式是?

  • A. f(x) = x · σ(x)
  • B. f(x) = max(0, x)
  • C. f(x) = tanh(x)
  • D. f(x) = x · tanh(x)
解答:Swish定义为f(x)=x·σ(x),其中σ是Sigmoid函数。这是一种自门控机制。

Q8 [多选] 以下哪些激活函数具有"自门控"特性?

  • A. Swish
  • B. GELU
  • C. ReLU
  • D. Tanh
解答:Swish(x·σ(x))和GELU(x·Φ(x))都是输入x乘以自身的门控值,属于自门控激活函数。ReLU和Tanh不是。

Q9 [单选] 在二分类问题的输出层,最常使用哪种激活函数?

  • A. Sigmoid
  • B. ReLU
  • C. Tanh
  • D. Softmax
解答:Sigmoid输出(0,1)之间,可直接解释为正类的概率,是二分类输出层的标准选择。Softmax用于多分类。

Q10 [单选] 激活函数tanh(x)与sigmoid(x)的数学关系是什么?

  • A. tanh(x) = sigmoid(x) + 1
  • B. tanh(x) = sigmoid(x) - 1
  • C. tanh(x) = 2·sigmoid(2x) - 1
  • D. tanh(x) = sigmoid(x/2)
解答:tanh(x) = (e^x-e^{-x})/(e^x+e^{-x}) = 2/(1+e^{-2x}) - 1 = 2σ(2x) - 1。