transformer模型介紹——大語言模型 LLMBook 學習(二)

1. transformer模型

1.1 注意力機制

**注意力機制(Attention Mechanism)**在人工智能中的應用,實際上是對人類認知系統中的注意力機制的一種模擬。它主要模仿了人類在處理信息時的選擇性注意(Selective Attention),即我們不會平均分配注意力,而是會集中關注關鍵信息。
在這里插入圖片描述

1.2 注意力機制原理

注意力機制是一種動態加權機制,用于在輸入數據中選取最相關的信息,并賦予不同的權重。它最初用于神經機器翻譯(Neural Machine Translation, NMT),后來廣泛應用于自然語言處理(NLP)、計算機視覺(CV)和異常檢測等任務。


1. 注意力計算流程

如圖所示,注意力機制主要包括 Query(查詢)、Key(鍵)、Value(值) 三個核心概念,它們的計算過程分為三步
在這里插入圖片描述

第一步:計算 Query 和 Key 之間的相似度
  • 我們用查詢向量(Query,記作 q q q,去匹配多個鍵向量(Keys,記作 k j k_j kj?,計算它們的相似度
  • 這里采用的是點積(Dot Product來度量相似度:
    e i j = q T k j e_{ij} = q^T k_j eij?=qTkj?
  • 其中:
    • q q q 是查詢向量(query)
    • k j k_j kj?是鍵向量(key)
    • e i j e_{ij} eij?表示查詢 q q q 與鍵 k j k_j kj?的相似度得分

直觀理解

  • 如果 q q q k j k_j kj? 方向相似(即表示的信息相似),則它們的點積 e i j e_{ij} eij? 會較大。
  • 反之,如果 q q q k j k_j kj? 方向不同,則 e i j e_{ij} eij? 會較小。
第二步:將相似度進行 Softmax 歸一化
  • 由于點積計算出的相似度值 e i j e_{ij} eij? 可能較大,因此需要進行Softmax 歸一化,使其變成一個概率分布:
    a i j = exp ? ( e i j ) ∑ j ′ exp ? ( e i j ′ ) a_{ij} = \frac{\exp(e_{ij})}{\sum_{j'} \exp(e_{ij'})} aij?=j?exp(eij?)exp(eij?)?
  • 這樣可以確保所有注意力權重 a i j a_{ij} aij? 的總和為 1,便于后續加權計算。

直觀理解

  • Softmax 歸一化后,最相關的 Key 對應的權重 a i j a_{ij} aij? 會更大,而不相關的 Key 權重會接近 0。

第三步:加權求和 Value
  • 計算出的注意力權重 a i j a_{ij} aij?作用于對應的 Value(值向量),最終得到輸出:
    o i = ∑ j a i j v j o_i = \sum_{j} a_{ij} v_j oi?=j?aij?vj?
  • 其中:
    • v j v_j vj? 是對應的值向量(value)
    • o i o_i oi? 是最終的加權求和結果(即注意力輸出)

直觀理解

  • 這個過程類似于信息檢索,即:
    • 如果某個 Key 與 Query 相似度高(即權重 a i j a_{ij} aij?大),那么它的 Value( v j v_j vj?) 會被重點關注
    • 最終的輸出 o i o_i oi? 是所有 Value 的加權平均

2. 直觀理解

可以把注意力機制類比為搜索引擎

  • Query(查詢):用戶輸入的搜索關鍵詞(如 “Transformer 論文”)。
  • Keys(鍵):數據庫中的所有文檔標題(如 “Attention is All You Need”)。
  • Values(值):數據庫中的所有文檔內容(如 Transformer 論文的正文)。
  • 計算相似度:搜索引擎會計算用戶輸入的關鍵詞與文檔標題的相關性。
  • Softmax 歸一化:搜索引擎會給每個文檔一個相關性分數,并歸一化為一個排名概率。
  • 加權求和:最終,搜索引擎會按照相關性高低,返回最相關的文檔內容。

3. 在 Transformer 中的應用

Transformer 結構(如 BERT、GPT)中,
注意力機制被用于自注意力Self-Attention計算:

  • 輸入是一個句子,每個單詞都有一個 Query、Key、Value。
  • 計算 Query 與所有 Key 的相似度,確定哪些單詞對當前單詞最重要。
  • 對 Value 進行加權求和,生成新的單詞表示。

示例

  • 句子:“The cat sat on the mat.”
  • 計算 “cat” 的注意力:
    • “cat” 可能關注 “The” 和 “sat” 的信息,而忽略 “mat”。
    • Transformer 通過注意力機制動態調整單詞之間的關系,提高理解能力。

4. 計算復雜度
  • 傳統 RNN 計算復雜度:( O(n) )(必須按順序計算)
  • Transformer 注意力計算復雜度:( O(n^2) )(可以并行計算)

雖然 Transformer 的注意力計算復雜度較高,但由于可以并行計算,在實際應用中比 RNN 更高效。


1.3 編碼器

在這里插入圖片描述

1. 編碼器的作用

編碼器(Encoder)是 Transformer 結構的核心組件之一,它的主要作用是將輸入數據轉換為隱藏層特征,以便后續的解碼器(Decoder)進一步處理或用于下游任務(如分類、翻譯等)。

在 Transformer 結構中,編碼器由 N 個堆疊的編碼器層(Encoder Layers) 組成,每個編碼器層都包含:

  • 多頭注意力機制(Multi-Head Attention, MHA)
  • 前饋神經網絡(Feed Forward Network, FFN)
  • 殘差連接(Residual Connection)和層歸一化(Layer Normalization)

2. 編碼器的結構

編碼器的計算流程如下:

(1)多頭注意力(Multi-Head Attention, MHA)
  • 計算輸入序列中每個詞對其他詞的注意力權重,提取全局依賴關系。
  • 采用多頭注意力機制(多個注意力頭并行計算),以學習不同的特征表示。
(2)殘差連接 + 層歸一化
  • 計算多頭注意力的輸出后,使用殘差連接(Residual Connection):
    X l ′ = LayerNorm ( MHA ( X l ? 1 ) + X l ? 1 ) X'_l = \text{LayerNorm}(\text{MHA}(X_{l-1}) + X_{l-1}) Xl?=LayerNorm(MHA(Xl?1?)+Xl?1?)
    其中:
    • X l ? 1 X_{l-1} Xl?1? 是上一層的輸出
    • MHA 是多頭注意力
    • LayerNorm 是層歸一化,防止梯度消失或梯度爆炸
(3)前饋神經網絡(Feed Forward Network, FFN)
  • 由兩個全連接層(MLP)組成:
    FFN ( X ′ ) = ReLU ( X ′ W 1 + b 1 ) W 2 + b 2 \text{FFN}(X') = \text{ReLU}(X' W_1 + b_1) W_2 + b_2 FFN(X)=ReLU(XW1?+b1?)W2?+b2?
  • 作用是增加非線性變換能力,提升模型的表達能力。
(4)再次殘差連接 + 層歸一化
  • 計算 FFN 輸出后,再次應用殘差連接:
    X l = LayerNorm ( FFN ( X l ′ ) + X l ′ ) X_l = \text{LayerNorm}(\text{FFN}(X'_l) + X'_l) Xl?=LayerNorm(FFN(Xl?)+Xl?)
  • 這樣可以穩定梯度傳遞,提高訓練效果

3. 公式解析

從公式來看,編碼器的計算流程可以分為兩步:

  1. 多頭注意力層(MHA)+ 殘差連接 + 層歸一化
    X l ′ = LayerNorm ( MHA ( X l ? 1 ) + X l ? 1 ) X'_l = \text{LayerNorm}(\text{MHA}(X_{l-1}) + X_{l-1}) Xl?=LayerNorm(MHA(Xl?1?)+Xl?1?)
  2. 前饋神經網絡(FFN)+ 殘差連接 + 層歸一化
    X l = LayerNorm ( FFN ( X l ′ ) + X l ′ ) X_l = \text{LayerNorm}(\text{FFN}(X'_l) + X'_l) Xl?=LayerNorm(FFN(Xl?)+Xl?)

其中:

  • ( X_{l-1} ):表示編碼器第 ( l-1 ) 層的輸出
  • ( X’_l ):表示經過多頭注意力后的中間結果
  • ( X_l ):表示編碼器第 ( l ) 層的最終輸出
  • LayerNorm:層歸一化,穩定訓練
  • MHA:多頭注意力
  • FFN:前饋神經網絡

4. 編碼器的特點
  • 并行計算:不像 RNN 需要逐步處理序列,Transformer 編碼器可以一次性處理整個輸入序列,提高計算效率。
  • 長距離依賴建模:通過自注意力機制(Self-Attention),編碼器可以捕捉遠距離的詞語關系。
  • 層歸一化 + 殘差連接:防止梯度消失,提高模型穩定性。
  • 多頭注意力:增強模型的表達能力,讓不同的注意力頭關注不同的信息。

5. 代碼實現

Transformer 編碼器層(Encoder Layer)的 PyTorch 實現

import torch
import torch.nn as nnclass TransformerEncoderLayer(nn.Module):def __init__(self, d_model, num_heads, d_ff, dropout=0.1):"""Transformer 編碼器層參數:- d_model: 輸入特征維度(如 512)- num_heads: 多頭注意力的頭數- d_ff: 前饋神經網絡的隱藏層維度(一般是 4*d_model)- dropout: Dropout 概率"""super(TransformerEncoderLayer, self).__init__()# 多頭注意力層self.self_attn = nn.MultiheadAttention(embed_dim=d_model, num_heads=num_heads, dropout=dropout)# 前饋神經網絡self.ffn = nn.Sequential(nn.Linear(d_model, d_ff),nn.ReLU(),nn.Linear(d_ff, d_model))# 層歸一化self.norm1 = nn.LayerNorm(d_model)self.norm2 = nn.LayerNorm(d_model)# Dropoutself.dropout1 = nn.Dropout(dropout)self.dropout2 = nn.Dropout(dropout)def forward(self, x):"""前向傳播參數:- x: 輸入張量 (batch_size, seq_len, d_model)返回:- 編碼器層的輸出 (batch_size, seq_len, d_model)"""# 多頭注意力attn_output, _ = self.self_attn(x, x, x)x = self.norm1(x + self.dropout1(attn_output))  # 殘差連接 + 層歸一化# 前饋神經網絡ffn_output = self.ffn(x)x = self.norm2(x + self.dropout2(ffn_output))  # 殘差連接 + 層歸一化return x# 測試編碼器層
d_model = 512
num_heads = 8
d_ff = 2048
seq_len = 10
batch_size = 2encoder_layer = TransformerEncoderLayer(d_model, num_heads, d_ff)
input_tensor = torch.rand(batch_size, seq_len, d_model)  # 隨機輸入
output_tensor = encoder_layer(input_tensor)print("編碼器層輸出形狀:", output_tensor.shape)  # (batch_size, seq_len, d_model)

組件作用
多頭注意力(MHA)計算輸入序列中不同位置的相關性,提取全局信息
前饋神經網絡(FFN)增強特征表達能力
殘差連接(Residual)防止梯度消失,提升訓練穩定性
層歸一化(LayerNorm)歸一化激活值,穩定訓練

編碼器的關鍵作用是將輸入轉換為隱藏層特征,并通過層層堆疊提取更高級的語義信息。

1.4 解碼器

1. 解碼器的作用

在這里插入圖片描述

解碼器(Decoder)是 Transformer 結構的另一核心組件,它的主要作用是將編碼器的隱藏層特征轉換為輸出序列(如翻譯任務中的目標語言句子)。

在 Transformer 結構中,解碼器由 N 個堆疊的解碼器層(Decoder Layers) 組成,每個解碼器層包含:

  • 掩碼多頭注意力(Masked Multi-Head Attention, Masked MHA)
  • 交叉多頭注意力(Cross Multi-Head Attention, Cross MHA)
  • 前饋神經網絡(Feed Forward Network, FFN)
  • 殘差連接(Residual Connection)和層歸一化(Layer Normalization)

2. 解碼器的結構

解碼器的計算流程如下:

(1)掩碼多頭注意力(Masked Multi-Head Attention, Masked MHA)
  • 作用:在生成序列時,模型不能看到未來的信息,因此需要掩碼(Mask),確保解碼器在預測第 t t t 個詞時,只能利用 t t t 之前的詞,而不能看到 t + 1 t+1 t+1 及之后的詞。
  • 計算方式
    Y l ′ = LayerNorm ( MaskedMHA ( Y l ? 1 ) + Y l ? 1 ) Y'_l = \text{LayerNorm}(\text{MaskedMHA}(Y_{l-1}) + Y_{l-1}) Yl?=LayerNorm(MaskedMHA(Yl?1?)+Yl?1?)
    • Y l ? 1 Y_{l-1} Yl?1? 是解碼器前一層的輸出
    • Masked MHA 計算當前詞與之前詞的注意力
    • LayerNorm 進行層歸一化

(2)交叉多頭注意力(Cross Multi-Head Attention, Cross MHA)
  • 作用:在翻譯任務中,解碼器需要關注編碼器的輸出,以獲取源語言的信息。
  • 計算方式
    Y l ′ ′ = LayerNorm ( CrossMHA ( Y l ′ , X L ) + Y l ′ ) Y''_l = \text{LayerNorm}(\text{CrossMHA}(Y'_l, X_L) + Y'_l) Yl′′?=LayerNorm(CrossMHA(Yl?,XL?)+Yl?)
    • Y l ′ Y'_l Yl? 是掩碼注意力的輸出
    • X L X_L XL? 是編碼器的最終輸出
    • Cross MHA 計算解碼器的隱藏狀態與編碼器輸出之間的注意力關系

(3)前饋神經網絡(Feed Forward Network, FFN)
  • 作用:增強特征表達能力,提高模型的非線性變換能力。
  • 計算方式
    Y l = LayerNorm ( FFN ( Y l ′ ′ ) + Y l ′ ′ ) Y_l = \text{LayerNorm}(\text{FFN}(Y''_l) + Y''_l) Yl?=LayerNorm(FFN(Yl′′?)+Yl′′?)
    • FFN 由兩個全連接層(MLP)組成:
      FFN ( Y ′ ′ ) = ReLU ( Y ′ ′ W 1 + b 1 ) W 2 + b 2 \text{FFN}(Y'') = \text{ReLU}(Y'' W_1 + b_1) W_2 + b_2 FFN(Y′′)=ReLU(Y′′W1?+b1?)W2?+b2?
    • 采用 ReLU 激活函數,增強非線性表達能力

4. 計算解析

解碼器的計算流程可以分為三步:

  1. 掩碼多頭注意力(Masked MHA)+ 殘差連接 + 層歸一化
    Y l ′ = LayerNorm ( MaskedMHA ( Y l ? 1 ) + Y l ? 1 ) Y'_l = \text{LayerNorm}(\text{MaskedMHA}(Y_{l-1}) + Y_{l-1}) Yl?=LayerNorm(MaskedMHA(Yl?1?)+Yl?1?)
  2. 交叉多頭注意力(Cross MHA)+ 殘差連接 + 層歸一化
    Y l ′ ′ = LayerNorm ( CrossMHA ( Y l ′ , X L ) + Y l ′ ) Y''_l = \text{LayerNorm}(\text{CrossMHA}(Y'_l, X_L) + Y'_l) Yl′′?=LayerNorm(CrossMHA(Yl?,XL?)+Yl?)
  3. 前饋神經網絡(FFN)+ 殘差連接 + 層歸一化
    Y l = LayerNorm ( FFN ( Y l ′ ′ ) + Y l ′ ′ ) Y_l = \text{LayerNorm}(\text{FFN}(Y''_l) + Y''_l) Yl?=LayerNorm(FFN(Yl′′?)+Yl′′?)

其中:

  • Y l ? 1 Y_{l-1} Yl?1? ):表示解碼器第 l ? 1 l-1 l?1 層的輸出
  • Y l ′ Y'_l Yl?:表示掩碼多頭注意力后的中間結果
  • Y l ′ ′ Y''_l Yl′′?:表示交叉多頭注意力后的中間結果
  • Y l Y_l Yl?:表示解碼器第 l l l層的最終輸出
  • X L X_L XL?:編碼器的最終輸出
  • LayerNorm:層歸一化,穩定訓練
  • Masked MHA:掩碼多頭注意力(防止未來信息泄露)
  • Cross MHA:交叉多頭注意力(關注編碼器輸出)
  • FFN:前饋神經網絡

5. 編碼器 vs. 解碼器
組件編碼器(Encoder)解碼器(Decoder)
輸入輸入序列(如源語言)目標序列(如目標語言)
多頭注意力標準多頭注意力(Self-Attention)掩碼多頭注意力(Masked Self-Attention)
交叉注意力??(關注編碼器輸出)
前饋神經網絡??
層歸一化 & 殘差連接??

6. 代碼實現

下面是 Transformer 解碼器層(Decoder Layer)的 PyTorch 實現

import torch
import torch.nn as nnclass TransformerDecoderLayer(nn.Module):def __init__(self, d_model, num_heads, d_ff, dropout=0.1):"""Transformer 解碼器層參數:- d_model: 輸入特征維度(如 512)- num_heads: 多頭注意力的頭數- d_ff: 前饋神經網絡的隱藏層維度(一般是 4*d_model)- dropout: Dropout 概率"""super(TransformerDecoderLayer, self).__init__()# 掩碼多頭注意力self.masked_attn = nn.MultiheadAttention(embed_dim=d_model, num_heads=num_heads, dropout=dropout)# 交叉多頭注意力(關注編碼器輸出)self.cross_attn = nn.MultiheadAttention(embed_dim=d_model, num_heads=num_heads, dropout=dropout)# 前饋神經網絡self.ffn = nn.Sequential(nn.Linear(d_model, d_ff),nn.ReLU(),nn.Linear(d_ff, d_model))# 層歸一化self.norm1 = nn.LayerNorm(d_model)self.norm2 = nn.LayerNorm(d_model)self.norm3 = nn.LayerNorm(d_model)# Dropoutself.dropout1 = nn.Dropout(dropout)self.dropout2 = nn.Dropout(dropout)self.dropout3 = nn.Dropout(dropout)def forward(self, x, encoder_output):"""前向傳播參數:- x: 解碼器輸入 (batch_size, seq_len, d_model)- encoder_output: 編碼器輸出 (batch_size, seq_len, d_model)返回:- 解碼器層的輸出 (batch_size, seq_len, d_model)"""# 掩碼多頭注意力masked_attn_output, _ = self.masked_attn(x, x, x)x = self.norm1(x + self.dropout1(masked_attn_output))  # 殘差連接 + 層歸一化# 交叉多頭注意力cross_attn_output, _ = self.cross_attn(x, encoder_output, encoder_output)x = self.norm2(x + self.dropout2(cross_attn_output))  # 殘差連接 + 層歸一化# 前饋神經網絡ffn_output = self.ffn(x)x = self.norm3(x + self.dropout3(ffn_output))  # 殘差連接 + 層歸一化return x# 測試解碼器層
decoder_layer = TransformerDecoderLayer(d_model=512, num_heads=8, d_ff=2048)
input_tensor = torch.rand(2, 10, 512)  # 解碼器輸入
encoder_output = torch.rand(2, 10, 512)  # 編碼器輸出
output_tensor = decoder_layer(input_tensor, encoder_output)print("解碼器層輸出形狀:", output_tensor.shape)  # (batch_size, seq_len, d_model)

解碼器的核心在于:

  • 掩碼多頭注意力(Masked MHA):防止未來信息泄露
  • 交叉多頭注意力(Cross MHA):關注編碼器的輸出
  • 前饋神經網絡(FFN):增強特征表達能力

1.5 多頭注意力層

在這里插入圖片描述

多頭注意力(Multi-Head Attention, MHA)是 Transformer 結構的核心組件之一,它能夠讓模型關注輸入序列中不同位置的關系,并通過多個注意力頭(heads)學習不同的特征表示


1. Scaled Dot-Product Attention(縮放點積注意力)

多頭注意力的基礎是 縮放點積注意力(Scaled Dot-Product Attention),其計算流程如下:

(1)輸入映射到 Q、K、V

給定輸入矩陣 X X X ,我們將其映射為:

  • 查詢(Query, Q) Q = X W Q Q = X W^Q Q=XWQ
  • 鍵(Key, K) K = X W K K = X W^K K=XWK
  • 值(Value, V):$ V = X W^V$

其中:

  • W Q , W K , W V W^Q, W^K, W^V WQ,WK,WV是可訓練的權重矩陣
  • X X X 是輸入特征(如詞向量)
(2)計算注意力權重

注意力分數使用點積計算
S = Q K T S = QK^T S=QKT
然后進行縮放(防止梯度爆炸):
S scaled = Q K T d k S_{\text{scaled}} = \frac{QK^T}{\sqrt{d_k}} Sscaled?=dk? ?QKT?
其中:

  • d k d_k dk?是鍵向量的維度
  • d k \sqrt{d_k} dk? ?作為縮放因子,防止數值過大導致梯度消失或梯度爆炸
(3)計算 Softmax 權重

α = softmax ( S scaled ) \alpha = \text{softmax}(S_{\text{scaled}}) α=softmax(Sscaled?)
Softmax 歸一化后,表示不同位置的注意力分布。

(4)加權求和

計算最終的注意力輸出:
Attention ( Q , K , V ) = α V \text{Attention}(Q, K, V) = \alpha V Attention(Q,K,V)=αV


2. 多頭注意力(Multi-Head Attention, MHA)

在單頭注意力機制中,所有信息都通過同一個注意力機制計算,可能會忽略一些重要特征。多頭注意力的核心思想是:使用多個注意力頭(heads),讓模型關注不同的特征信息。

(1)多頭注意力計算流程
  1. 輸入映射到多個 Q、K、V

    • 對輸入 X X X進行多組不同的線性變換,得到多個查詢、鍵和值:
      Q i = X W i Q , K i = X W i K , V i = X W i V , i = 1 , 2 , … , h Q_i = X W_i^Q, \quad K_i = X W_i^K, \quad V_i = X W_i^V, \quad i = 1,2,\dots,h Qi?=XWiQ?,Ki?=XWiK?,Vi?=XWiV?,i=1,2,,h
    • 其中 h h h是注意力頭的數量,每個注意力頭都有自己的權重矩陣 W i Q , W i K , W i V W_i^Q, W_i^K, W_i^V WiQ?,WiK?,WiV?
  2. 每個頭獨立計算注意力

    • 每個頭獨立計算縮放點積注意力:
      Attention i ( Q i , K i , V i ) = softmax ( Q i K i T d k ) V i \text{Attention}_i(Q_i, K_i, V_i) = \text{softmax} \left( \frac{Q_i K_i^T}{\sqrt{d_k}} \right) V_i Attentioni?(Qi?,Ki?,Vi?)=softmax(dk? ?Qi?KiT??)Vi?
  3. 拼接多個頭的輸出

    • 將所有注意力頭的輸出拼接在一起:
      MultiHead ( Q , K , V ) = Concat ( head 1 , head 2 , … , head h ) W O \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \text{head}_2, \dots, \text{head}_h) W^O MultiHead(Q,K,V)=Concat(head1?,head2?,,headh?)WO
    • 其中 W O W^O WO是最終的線性變換矩陣,將拼接后的結果映射回原始維度。

3. 公式總結
1.單頭注意力(Scaled Dot-Product Attention)

Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax} \left( \frac{Q K^T}{\sqrt{d_k}} \right) V Attention(Q,K,V)=softmax(dk? ?QKT?)V

2.多頭注意力(Multi-Head Attention)

MultiHead ( Q , K , V ) = Concat ( head 1 , head 2 , … , head h ) W O \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \text{head}_2, \dots, \text{head}_h) W^O MultiHead(Q,K,V)=Concat(head1?,head2?,,headh?)WO
其中:
head i = Attention ( Q i , K i , V i ) \text{head}_i = \text{Attention}(Q_i, K_i, V_i) headi?=Attention(Qi?,Ki?,Vi?)


4. 代碼實現

多頭注意力(Multi-Head Attention, MHA)的 PyTorch 實現

import torch
import torch.nn as nnclass MultiHeadAttention(nn.Module):def __init__(self, d_model, num_heads, dropout=0.1):"""多頭注意力層參數:- d_model: 輸入特征維度(如 512)- num_heads: 注意力頭的數量- dropout: Dropout 概率"""super(MultiHeadAttention, self).__init__()assert d_model % num_heads == 0, "d_model 必須能被 num_heads 整除"self.d_model = d_modelself.num_heads = num_headsself.d_k = d_model // num_heads  # 每個頭的維度# 線性變換矩陣self.W_q = nn.Linear(d_model, d_model)self.W_k = nn.Linear(d_model, d_model)self.W_v = nn.Linear(d_model, d_model)self.W_o = nn.Linear(d_model, d_model)self.dropout = nn.Dropout(dropout)def attention(self, Q, K, V, mask=None):"""計算縮放點積注意力"""scores = torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.d_k, dtype=torch.float32))if mask is not None:scores = scores.masked_fill(mask == 0, float('-inf'))attn_weights = torch.softmax(scores, dim=-1)attn_weights = self.dropout(attn_weights)return torch.matmul(attn_weights, V), attn_weightsdef forward(self, X):batch_size, seq_len, _ = X.shape# 計算 Q, K, VQ = self.W_q(X).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)K = self.W_k(X).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)V = self.W_v(X).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2)# 計算多頭注意力attn_output, attn_weights = self.attention(Q, K, V)# 拼接多個頭的輸出attn_output = attn_output.transpose(1, 2).contiguous().view(batch_size, seq_len, self.d_model)# 線性變換回原始維度output = self.W_o(attn_output)return output, attn_weights# 測試多頭注意力
d_model = 512
num_heads = 8
seq_len = 10
batch_size = 2mha = MultiHeadAttention(d_model, num_heads)
input_tensor = torch.rand(batch_size, seq_len, d_model)  # 隨機輸入
output_tensor, attention_weights = mha(input_tensor)print("多頭注意力輸出形狀:", output_tensor.shape)  # (batch_size, seq_len, d_model)

  • 多頭注意力(MHA)能夠學習不同的注意力模式,提高模型的表達能力。
  • 通過多個注意力頭,模型可以關注輸入序列的不同方面。
  • 縮放點積注意力(Scaled Dot-Product Attention)是 MHA 的基礎,計算 Query-Key 相關性并加權 Value。

1.6 位置編碼

在這里插入圖片描述
在這里插入圖片描述

在 Transformer 模型中,由于 自注意力機制(Self-Attention) 沒有內置的序列順序信息,因此需要 位置編碼(Positional Encoding) 來顯式地提供序列位置信息,使模型能夠區分不同單詞的順序。


1. 位置編碼的數學定義

位置編碼采用 正弦(sin)和余弦(cos)函數 生成,如下公式:
p t ( i ) = { sin ? ( ω k ? t ) , if? i = 2 k cos ? ( ω k ? t ) , if? i = 2 k + 1 p_t^{(i)} = \begin{cases} \sin(\omega_k \cdot t), & \text{if } i = 2k \\ \cos(\omega_k \cdot t), & \text{if } i = 2k+1 \end{cases} pt(i)?={sin(ωk??t),cos(ωk??t),?if?i=2kif?i=2k+1?

其中:

  • p t ( i ) p_t^{(i)} pt(i)? 表示 位置 t t t 處,第 i i i 維的編碼值
  • ω k \omega_k ωk? 是不同維度的頻率,定義為:
    ω k = 1 1000 0 2 k / d \omega_k = \frac{1}{10000^{2k/d}} ωk?=100002k/d1?
    其中:
    • k k k表示當前維度的索引(偶數維和奇數維分別使用 sin 和 cos)。
    • d d d 是隱藏層維度(例如 512)。
    • 這個公式確保 不同維度的頻率不同,以捕捉不同粒度的位置信息。

2. 位置編碼的特點
  • 使用不同頻率的正弦和余弦函數
    • 低維度使用較大的頻率(變化較快),編碼局部信息。
    • 高維度使用較小的頻率(變化較慢),編碼全局信息。
  • 編碼值是固定的,不需要訓練,不同位置的編碼是固定的數學計算結果,不依賴數據訓練。
  • 可以外推到更長的序列,因為是基于數學函數計算的,而不是學習得到的。

3. 位置編碼的作用
  • 提供位置信息:幫助 Transformer 區分不同單詞的順序。
  • 支持長序列建模:由于編碼是基于數學函數計算的,可以推廣到比訓練時更長的序列。
  • 平滑的連續變化:由于使用正弦和余弦函數,編碼值在相鄰位置之間連續變化,使得模型可以更容易學習相對位置信息。

4. 代碼實現

可以使用 Python(PyTorch)實現位置編碼:

import numpy as np
import matplotlib.pyplot as pltdef positional_encoding(seq_len, d_model):pos = np.arange(seq_len)[:, np.newaxis]  # 位置 (t)i = np.arange(d_model)[np.newaxis, :]  # 維度 (i)# 計算頻率omega = 1 / (10000 ** (2 * (i // 2) / d_model))# 計算位置編碼pos_encoding = np.zeros((seq_len, d_model))pos_encoding[:, 0::2] = np.sin(pos * omega[:, 0::2])  # 偶數維pos_encoding[:, 1::2] = np.cos(pos * omega[:, 1::2])  # 奇數維return pos_encoding# 生成位置編碼
seq_len, d_model = 100, 512
pos_encoding = positional_encoding(seq_len, d_model)# 可視化
plt.figure(figsize=(10, 6))
plt.imshow(pos_encoding, aspect='auto', cmap='coolwarm')
plt.xlabel("Dimension i")
plt.ylabel("Position t")
plt.title("Positional Encoding Heatmap")
plt.colorbar()
plt.show()

? 位置編碼通過 sin 和 cos 賦予 Transformer 位置信息
? 不同維度使用不同頻率,捕捉局部和全局信息
? 數學計算得到,不需要訓練,可推廣到長序列

2. 問題備注

Transformer 結構 中,Q(Query)、K(Key)、V(Value) 的來源在 編碼器(Encoder)解碼器(Decoder) 中有所不同,具體如下:


1. 編碼器(Encoder)中的 Q、K、V

編碼器的自注意力(Self-Attention) 機制中:

  • 輸入:編碼器的輸入是一個序列 ( X )(如源語言句子)。
  • Q、K、V 的來源
    Q = X W Q , K = X W K , V = X W V Q = X W^Q, \quad K = X W^K, \quad V = X W^V Q=XWQ,K=XWK,V=XWV
    • Query(查詢):由輸入 X X X 經過線性變換得到
    • Key(鍵):由輸入 X X X 經過線性變換得到
    • Value(值):由輸入 X X X 經過線性變換得到

特點

  • 自注意力(Self-Attention):Q、K、V 都來自相同的輸入 ( X )。
  • 作用:讓編碼器的每個詞關注輸入序列中的其他詞,捕捉全局信息。

2. 解碼器(Decoder)中的 Q、K、V

解碼器的注意力機制 中,注意力分為兩種:

  1. Masked 自注意力(Masked Self-Attention)
  2. 交叉注意力(Cross-Attention)
(1)Masked 自注意力中的 Q、K、V
  • 輸入:解碼器的輸入是目標序列 ( Y )(如目標語言句子)。
  • Q、K、V 的來源
    Q = Y W Q , K = Y W K , V = Y W V Q = Y W^Q, \quad K = Y W^K, \quad V = Y W^V Q=YWQ,K=YWK,V=YWV
    • Query(查詢):由目標序列 Y Y Y 計算
    • Key(鍵):由目標序列 Y Y Y 計算
    • Value(值):由目標序列 Y Y Y 計算

特點

  • Masked 機制:在計算注意力時,屏蔽未來的信息,防止看到后續詞語。
  • 作用:讓解碼器的每個詞只能關注當前及之前的詞,確保自回歸特性。

(2)交叉注意力(Cross-Attention)中的 Q、K、V
  • 輸入:交叉注意力的輸入是 解碼器的隱藏狀態編碼器的輸出
  • Q、K、V 的來源
    Q = Y W Q , K = X L W K , V = X L W V Q = Y W^Q, \quad K = X_L W^K, \quad V = X_L W^V Q=YWQ,K=XL?WK,V=XL?WV
    • Query(查詢):來自解碼器的隱藏狀態 Y Y Y
    • Key(鍵):來自編碼器的輸出 X L X_L XL?
    • Value(值):來自編碼器的輸出 X L X_L XL?

特點

  • Q 來自解碼器,K 和 V 來自編碼器,讓解碼器能夠關注編碼器的信息。
  • 作用:讓解碼器在生成目標序列時,能夠參考源語言的信息。

位置Query(Q)來源Key(K)來源Value(V)來源作用
編碼器(Encoder)輸入 (X)輸入 (X)輸入 (X)讓每個詞關注整個輸入序列
解碼器(Masked 自注意力)目標序列 (Y)目標序列 (Y)目標序列 (Y )讓解碼器的每個詞關注當前及之前的詞
解碼器(交叉注意力)目標序列 (Y)編碼器輸出 X L X_L XL?編碼器輸出 X L X_L XL?

  • 編碼器的 Q、K、V 都來自輸入 ( X ),用于捕捉全局信息。
  • 解碼器的 Masked 自注意力的 Q、K、V 都來自目標序列 Y Y Y,用于保證自回歸特性。
  • 解碼器的交叉注意力的 Q 來自解碼器,K 和 V 來自編碼器的輸出 X L X_L XL?**,用于關注源語言信息。

3.為什么注意力模型計算選用點積(Dot-Product)?

在 Transformer 的注意力機制(Self-Attention 和 Cross-Attention)中,點積(Dot-Product) 是計算 Query(查詢)和 Key(鍵)之間相似度的核心操作。主要原因包括以下幾點:


1. 計算效率高

點積計算的核心公式是:
S = Q K T S = QK^T S=QKT
其中:

  • Q Q Q(查詢): ( b a t c h , s e q _ l e n , d k ) (batch, seq\_len, d_k) (batch,seq_len,dk?)
  • K K K(鍵): ( b a t c h , s e q _ l e n , d k ) (batch, seq\_len, d_k) (batch,seq_len,dk?)

點積計算的時間復雜度為 O ( d k ) O(d_k) O(dk?),相比其他相似度計算方法(如歐幾里得距離、余弦相似度)更加高效,尤其適用于 GPU 并行計算。

對比計算復雜度:

  • 點積(Dot-Product): O ( d k ) O(d_k) O(dk?)(只需乘法和加法)
  • 歐幾里得距離(Euclidean Distance): O ( d k ) O(d_k) O(dk?)(需要平方、開方)
  • 余弦相似度(Cosine Similarity): O ( d k ) O(d_k) O(dk?)(需要歸一化)

由于 Transformer 需要處理大規模數據(如 NLP 任務中的長文本、視頻分析中的時序數據),選擇計算效率高的點積是更優的選擇。


2. 點積能夠有效衡量相似性
(1)點積的幾何解釋

點積計算:
Q i ? K j = ∑ d = 1 d k Q i d K j d Q_i \cdot K_j = \sum_{d=1}^{d_k} Q_{id} K_{jd} Qi??Kj?=d=1dk??Qid?Kjd?

  • 如果 Q Q Q K K K 的方向相同(即兩個向量相似),點積值較大。
  • 如果 Q Q Q K K K 的方向正交(即無關),點積值接近 0。
  • 如果 Q Q Q K K K 的方向相反,點積值較小(可能為負)。

這與注意力機制的需求一致:希望讓 Query 關注與自己最相關的 Key

(2)點積 vs. 余弦相似度

余弦相似度計算如下:
cos ? ( θ ) = Q ? K ∥ Q ∥ ∥ K ∥ \cos(\theta) = \frac{Q \cdot K}{\|Q\| \|K\|} cos(θ)=Q∥∥KQ?K?
雖然余弦相似度也能衡量向量的相似性,但它需要額外的歸一化操作(計算向量模長),這會增加計算成本。而點積本質上是未歸一化的余弦相似度,因此可以直接用于注意力計算。


3. 結合 Softmax 歸一化

點積計算的結果:
S = Q K T S = QK^T S=QKT
通常會經過 Softmax 歸一化
α = softmax ( Q K T d k ) \alpha = \text{softmax} \left(\frac{QK^T}{\sqrt{d_k}}\right) α=softmax(dk? ?QKT?)

  • Softmax 作用:將點積結果轉換為概率分布,使得所有注意力權重之和為 1。
  • 縮放因子 d k \sqrt{d_k} dk? ?:防止點積值過大導致梯度消失。

這種組合方式使得點積注意力(Scaled Dot-Product Attention)既高效又穩定。


4. 經驗驗證:點積注意力效果優于加性注意力

在早期的注意力機制(如 Bahdanau Attention)中,使用的是 加性注意力(Additive Attention)
score ( Q , K ) = V T tanh ? ( W q Q + W k K ) \text{score}(Q, K) = V^T \tanh(W_q Q + W_k K) score(Q,K)=VTtanh(Wq?Q+Wk?K)
但研究發現:

  • 點積注意力(Dot-Product Attention)在大規模數據上效果更好
  • 點積計算可以更好地利用矩陣運算加速(GPU 友好)
  • 加性注意力需要額外的參數 W q , W k , V W_q, W_k, V Wq?,Wk?,V,而點積注意力不需要額外參數

因此,在 Transformer 及其變體(如 BERT、GPT、ViT)中,點積注意力成為主流選擇


  • 點積計算高效,適合 GPU 并行計算(相比加性注意力更快)。
  • 點積能夠有效衡量向量相似性(與余弦相似度類似,但計算更簡單)。
  • 結合 Softmax 歸一化,使注意力機制更加穩定(避免梯度消失)。
  • 實驗驗證:點積注意力在大規模數據上效果優于加性注意力

因此,Transformer 采用點積注意力(Dot-Product Attention)作為核心計算方式,并結合 Softmax 歸一化和縮放因子 d k \sqrt{d_k} dk? ?進行優化。

4. 為什么要除以 D \sqrt{D} D ? (Scale)?

點積注意力(Dot-Product Attention) 計算中,我們使用 Query(Q)和 Key(K) 的點積來衡量相似性:
S = Q K T S = QK^T S=QKT
然后通過 Softmax 歸一化計算注意力權重:
α = softmax ( S ) V \alpha = \text{softmax}(S)V α=softmax(S)V
但是,如果不進行縮放,點積值可能會變得 過大,導致 Softmax 輸出極端化,影響模型訓練。
因此,我們 除以 ( \sqrt{D} )(D 為特征維度) 來進行縮放,最終計算方式如下:
S = Q K T D S = \frac{QK^T}{\sqrt{D}} S=D ?QKT?


1. 避免點積值過大,防止梯度消失

在高維空間(例如 D = 512 D=512 D=512 Q Q Q K K K 的元素通常服從 均值為 0,方差為 1 的正態分布(假設初始化時)。
那么,點積 S S S 的期望值和方差計算如下:

  • 點積的期望值
    E [ Q K T ] = 0 \mathbb{E}[QK^T] = 0 E[QKT]=0 $$
    因為 ( Q ) 和 ( K ) 服從均值為 0 的分布,所以它們的點積的均值仍然是 0。

  • 點積的方差
    Var ( Q K T ) = D \text{Var}(QK^T) = D Var(QKT)=D
    由于點積涉及 ( D ) 個獨立變量的乘積求和,方差會隨著 ( D ) 增大而增大。

D D D 很大時,例如 D = 512 或 1024 D = 512 或 1024 D=5121024,點積值的方差也會變得很大,導致 Softmax 計算時的指數函數 e x e^x ex的值過大,使得:

  • Softmax 輸出接近 one-hot(即某個值接近 1,其他值接近 0)。
  • 反向傳播時梯度變得很小(梯度消失),影響模型訓練。

解決方案:

  • 通過 除以 ( \sqrt{D} ),讓點積值的方差變為 1:
    Var ( Q K T D ) = 1 \text{Var} \left(\frac{QK^T}{\sqrt{D}}\right) = 1 Var(D ?QKT?)=1
  • 這樣,Softmax 輸出更加平滑,梯度不會消失,有助于穩定訓練。

2. 直觀理解

可以用一個形象的例子來理解:

  • 未縮放的點積(大值輸入 Softmax):就像一個考試成績滿分 1000 分的系統,99 分和 100 分的差距微乎其微,但 Softmax 會放大這個差距,使得 100 分的注意力遠大于 99 分。
  • 縮放后的點積(小值輸入 Softmax):就像一個滿分 100 分的考試,99 分和 100 分的差距不會被過度放大,注意力分布更加合理。

? 防止 Softmax 過度偏向單個 token(避免 one-hot 現象)。
? 保持梯度穩定,防止梯度消失,使模型更容易訓練
? 在高維空間(如 D=512)時,避免點積值過大,保證數值穩定性

因此,Transformer 采用 Scaled Dot-Product Attention,即在計算 Q K T QK^T QKT 后除以 D \sqrt{D} D ?,確保模型訓練更穩定,注意力分布更合理。

參考文獻

Datawhale大模型組隊學習地址

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71847.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71847.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71847.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

word甲烷一鍵下標

Sub 甲烷下標()甲烷下標 宏Selection.Find.ClearFormattingSelection.Find.Replacement.ClearFormattingWith Selection.Find.Text "CH4".Replacement.Text "CHguoshao4".Forward True.Wrap wdFindContinue.Format False.MatchCase False.MatchWhole…

Dify 本地部署教程

目錄 一、下載安裝包 二、修改配置 三、啟動容器 四、訪問 Dify 五、總結 本篇文章主要記錄 Dify 本地部署過程,有問題歡迎交流~ 一、下載安裝包 從 Github 倉庫下載最新穩定版軟件包,點擊下載~,當然也可以克隆倉庫或者從倉庫里直接下載zip源碼包。 目前最新版本是V…

2.1 掌握XML基礎知識

本文介紹了結構化、半結構化和非結構化數據的概念與特點。結構化數據以固定格式存儲于數據庫,便于查詢與管理,常用于金融等領域。半結構化數據如XML、JSON,具有一定的組織形式但模式不固定,適用于Web內容和日志文件。非結構化數據…

Android Studio 配置國內鏡像源

Android Studio版本號:2022.1.1 Patch 2 1、配置gradle國內鏡像,用騰訊云 鏡像源地址:https\://mirrors.cloud.tencent.com/gradle 2、配置Android SDK國內鏡像 地址:Index of /AndroidSDK/

超過 37000 臺 VMwareESXi 服務器可能受到持續攻擊威脅

近日,威脅監測平臺影子服務器基金會(The Shadowserver Foundation)發布報告,指出超 3.7 萬個互聯網暴露的威睿(VMware)ESXi 實例存在嚴重安全隱患,極易受到 CVE-2025-22224 漏洞的攻擊。該漏洞屬…

npm終端執行時報錯

終端npm執行時報錯下錯誤: 報錯了,就來百度,報錯的原因是 1、這個錯誤是因為 PowerShell 的執行策略(Execution Policy)限制了腳本的運行 2、默認情況下,Windows 系統可能會禁止運行未簽名的腳本&#x…

JVM類加載器面試題及原理

JVM只會運行二進制文件,類加載器的作用就是將字節碼文件加載到JVM中,從而讓Java程序能夠啟動起來。 1. 類加載器的種類 啟動類加載器(BootStrap ClassLoader):加載JAVA_HOME/jre/lib目錄下的庫擴展類加載器&#xff…

C語言每日一練——day_3(快速上手C語言)

引言 針對初學者,每日練習幾個題,快速上手C語言。第三天。(會連續更新) 采用在線OJ的形式 什么是在線OJ? 在線判題系統(英語:Online Judge,縮寫OJ)是一種在編程競賽中用…

用Qt手搓AI助手,挑戰24小時開發DeepSeek Assistant!

一、項目需求分析與技術選型 DeepSeekAssistant是一款基于深度求索(DeepSeek)API的智能對話助手,核心需求包括: 用戶界面友好:支持多輪對話展示數據持久化:歷史記錄存儲與檢索異步網絡通信:AP…

Linux 環境變量快速上手指南

Linux 環境變量快速上手 1. 什么是環境變量 環境變量(Environment Variables)是操作系統中用于存儲配置信息的一種機制,可以在運行時被進程讀取和使用。常見環境變量示例: PATH: 存放可執行文件搜索路徑。HOME: 當前用戶的家目錄…

萬字技術指南STM32F103C8T6 + ESP8266-01 連接 OneNet 平臺 MQTT/HTTP

此博客為一份詳細的指南,涵蓋 STM32F103C8T6 通過 ESP8266-01 連接 OneNet 平臺,并使用 MQTT/HTTP 進行數據通信的完整流程。這份文檔包括: OneNet 平臺的介紹與功能概覽在 OneNet 上創建和配置設備的方法STM32CubeIDE 的開發環境搭建ESP826…

Go本地緩存設計與實現

本地緩存是一個項目中很常見的組件。在很多人的眼中就是一個簡單的key-value的map存儲即可實現,但實際上,設計一個本地緩存需要考慮的問題遠比你想象的多,比如說,本地緩存是將數據存儲在內存,若數據量激增突破了內存限…

深入解析 JavaScript 原型與原型鏈:從原理到應用

原型和原型鏈是 JavaScript 中實現對象繼承和屬性查找的核心機制。為了更深入地理解它們,我們需要從底層原理、實現機制以及實際應用等多個角度進行分析。 1. 原型(Prototype) 1.1 什么是原型? 每個 JavaScript 對象&#xff08…

FPGA時序約束的幾種方法

一,時鐘約束 時鐘約束是最基本的一個約束,因為FPGA工具是不知道你要跑多高的頻率的,你必要要告訴工具你要跑的時鐘頻率。時鐘約束也就是經常看到的Fmax,因為Fmax是針對“最差勁路徑”,也就是說,如果該“最差勁路徑”得到好成績,那些不是最差勁的路徑的成績當然比…

Visual Studio Code打開遠程服務器項目,打開服務器Android上百G源碼,SSH免密連接方式

Visual Studio Code打開遠程服務器項目 1,Visual Studio Code拓展中,安裝遠程插件 Remote Development 2,SSH免密連接,A電腦免密連接B,配置B電腦.ssh/authorized_keys A電腦的.ssh/id_rsa.pub中的公鑰內容,…

AWS云編排詳解-Cloud Formation

作者:私語茶館 1.關鍵概念 名詞 說明 軟件: CloudFormation 描述AWS 資源、配置值和互連關系。借助集成設施即代碼加快云部署 CloudFormation Designer 拖拽式圖形化模板編輯界面。 Amazon Simple Notification Service (SNS) SNS可通過電子郵件跟蹤堆棧的創建和刪除進度,…

《PyQt5》——設計Python GUI(圖形用戶界面)實例

PyQt5 PyQt5的配置和基礎使用可以參考這篇文章:《 PyQt5》—— 創建 Python GUI(圖形用戶界面) Python GUI(圖形用戶界面)實例 本實例是設計一個通過玉米和豆粕的價格來預測生豬的價格,并顯示預測價格與實…

kali linux 打開 word

Kali Linux是一款專為網絡安全領域而設計的操作系統,它集成了大量的安全工具,幫助用戶進行網絡滲透測試和安全評估。作為一款功能強大的操作系統,Kali Linux可以滿足用戶在網絡安全領域的各種需求,包括滲透測試、漏洞分析、數字取…

hooks useModule自定義hooks (二次封裝AgGridReact ag-table)自定義表頭,自定義表頭搜索

場景業務: 多次運用AgGridReact的table 列表 思路: 運用自定義hooks進行二次封裝: 通用配置例如:傳參的參數,傳參的url,需要緩存的key這些鍵值類 定制化配置例如:需要對table 的一些定制化傳…

SpringBoot最簡單方式實現自定義異常頁面(404)

最簡單的方式實現所有自定義異常頁面(如 404、500 等)是通過 靜態資源文件 或 模板引擎 來實現。 方法 1:使用靜態資源文件(最簡單) Spring Boot 默認會在 src/main/resources/static 或 src/main/resources/public …