面试篇 - Transformer前馈神经网络(FFN)使用什么激活函数?

1. FFN结构分解

原始Transformer的FFN层
FFN(x) = max(0, xW₁ + b₁)W₂ + b₂  # 原始论文公式
  • 输入:自注意力层的输出 x(维度 d_model=512

  • 扩展层xW₁ + b₁(扩展为 d_ff=2048

  • 激活函数ReLU(即 max(0, ⋅)

  • 收缩层(⋅)W₂ + b₂(压缩回 d_model=512

2. ReLU的核心特性

特性公式表现作用
非线性f(x) = max(0, x)使模型能够学习复杂模式(否则多层线性变换等价于单层)
梯度消失缓解f'(x) = 1 if x>0 else 0正区间梯度恒为1,避免Sigmoid/Tanh的梯度指数衰减问题
计算高效只需比较和取最大值操作比Sigmoid(需指数运算)快3-6倍(实测在GPU上)

3. 为什么选择ReLU?

  • 实验验证:原始Transformer论文(《Attention Is All You Need》)通过消融实验确认ReLU优于Sigmoid/Tanh。

  • 深层网络适配:Transformer通常堆叠6-12层,ReLU的梯度特性更适合深度训练。

  • 稀疏激活:约50%神经元输出为0,可能提升特征选择性(但后续研究对此有争议)。

4. GELU的改进与数学细节

GELU公式
GELU(x) = xΦ(x) ≈ 0.5x(1 + tanh[√(2/π)(x + 0.044715x³)])  # 近似计算
  • 与ReLU对比

    • 平滑性:GELU在 x=0 处可导(ReLU二阶不可导)

    • 概率解释Φ(x) 是高斯CDF,相当于对输入进行"随机门控"

BERT中的使用
  • 在BERT-base中,GELU使MNLI任务准确率提升约0.5%(相比ReLU)

  • 计算代价:GELU比ReLU慢约15%(因需计算tanh)

5. 关键代码实现对比

PyTorch中的FFN层
import torch.nn as nn

class TransformerFFN(nn.Module):
    def __init__(self, d_model=512, d_ff=2048):
        super().__init__()
        self.linear1 = nn.Linear(d_model, d_ff)
        self.linear2 = nn.Linear(d_ff, d_model)
        self.activation = nn.ReLU()  # 或 nn.GELU()

    def forward(self, x):
        return self.linear2(self.activation(self.linear1(x)))
激活函数计算速度测试
import timeit
x = torch.randn(10000, 10000).cuda()

# ReLU
timeit.timeit(lambda: nn.ReLU()(x), number=100)  # 约0.12秒

# GELU 
timeit.timeit(lambda: nn.GELU()(x), number=100)  # 约0.18秒

6. 后续模型的发展

  • Switch Transformer:使用ReGLU(ReLU的GLU变体)提升稀疏性

  • GPT-3:保留ReLU,因模型足够大能弥补激活函数缺陷

  • Vision Transformer:部分研究采用LeakyReLU处理负值信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值