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.044715x3)]) # 近似計算
-
與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 nnclass 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處理負值信息