自注意力機制允許模型在處理序列資料時,關注輸入序列的不同部分,從而提取更關鍵的資訊。這對於理解詞彙之間的關係至關重要,例如在機器翻譯中判斷主詞與受詞的關聯。本文將逐步解析自注意力機制的核心概念,並輔以實際的程式碼案例說明。首先,模型會將輸入序列轉換為向量表示,接著計算每個元素與其他元素的注意力權重,權重越高表示關聯性越強。最後,模型會根據這些權重計算出上下文向量,用於後續的處理。

瞭解自注意力機制

在深度學習中,自注意力(Self-Attention)是一種強大的機制,能夠讓模型關注輸入序列的不同部分,以提取更有用的資訊。這個機制在自然語言處理(NLP)任務中尤其重要,因為它可以幫助模型理解句子中不同詞彙之間的關係。

自注意力的運作原理

給定一個輸入序列 (x = (x^{(1)}, x^{(2)}, \ldots, x^{(T)})),其中每個 (x^{(i)}) 都是一個 (d) 維的向量,代表著序列中的第 (i) 個元素(例如,一個詞彙的嵌入)。自注意力的目標是計算出與每個輸入元素 (x^{(i)}) 相關的上下文向量 (z^{(i)})。

在計算 (z^{(i)}) 時,模型會考慮輸入序列中所有其他元素,並根據它們與當前元素 (x^{(i)}) 的相關性計算注意力權重。這些權重代表了模型對於不同輸入元素的關注程度。

注意力權重的計算

注意力權重的計算通常涉及到查詢向量(Query)、鍵值向量(Key)和值向量(Value)。對於每個輸入元素 (x^{(i)}),模型會計算出它的查詢向量、鍵值向量和值向量。然後,透過計算查詢向量和所有鍵值向量的點積,並將結果進行softmax啟用,得到注意力權重。

自注意力的優點

自注意力機制的優點在於它能夠:

  1. 捕捉長距離依賴: 自注意力可以輕易地捕捉輸入序列中不同位置之間的依賴關係,不受距離限制。
  2. 平行計算: 由於自注意力機制可以平行地處理所有輸入元素,因此可以加速模型的訓練和推理速度。
  3. 提高模型的表達能力: 透過自注意力機制,模型可以學習到更多複雜的模式和關係,從而提高其在各種NLP任務中的表達能力。

實際應用

自注意力機制已被廣泛應用於各種NLP任務中,包括但不限於:

  1. 機器翻譯: 自注意力可以幫助模型更好地理解源語言和目標語言之間的對齊關係。
  2. 問答系統: 自注意力可以用於識別問題中哪些詞彙是最相關的。
  3. 文字分類別: 自注意力可以幫助模型關註文字中最重要的部分,以進行更準確的分類別。

自我注意力機制的核心:內容向量

在深度學習中,尤其是在自然語言處理(NLP)任務中,自我注意力機制(Self-Attention Mechanism)扮演著重要角色。這種機制使模型能夠瞭解輸入序列中不同元素之間的關係和相互依賴性。為了達到這個目的,模型會計算每個輸入元素的內容向量(Context Vector),這是一種增強的嵌入向量(Embedding Vector),包含了該元素及其與序列中其他元素之間的關係資訊。

內容向量的概念

內容向量可以被視為一個包含了輸入序列中所有元素資訊的嵌入向量。例如,對於一個句子,內容向量可以代表每個詞彙與其他詞彙之間的關係和語義資訊。這使得模型能夠更好地理解句子的語義和結構。

自我注意力機制的實作

要實作自我注意力機制,我們需要計算每個輸入元素的內容向量。這涉及到計算注意力權重(Attention Weights),它們代表了每個輸入元素對於其他元素的重要性。注意力權重是根據輸入元素之間的相似度計算得到的。

實際實作

以下是使用PyTorch實作自我注意力機制的一個簡單示例:

import torch

# 輸入序列的嵌入向量
inputs = torch.tensor([
    [0.43, 0.15, 0.89],  # Your (x^1)
    [0.55, 0.87, 0.66],  # journey (x^2)
    [0.57, 0.85, 0.64],  # starts (x^3)
    [0.22, 0.58, 0.33],  # with (x^4)
    [0.77, 0.25, 0.10],  # one (x^5)
    [0.05, 0.80, 0.55]   # step (x^6)
])

# 選擇一個查詢token(例如,"journey")
query = inputs[1]

# 計算注意力權重
attention_weights = torch.matmul(query, inputs.T)

# 計算內容向量
context_vector = torch.matmul(attention_weights, inputs)

在這個示例中,我們選擇了"journey"作為查詢token,然後計算了它與序列中其他元素之間的注意力權重。最後, мы 計算了內容向量,它代表了"journey"與其他元素之間的關係資訊。

注意力機制的核心:點積運算

在注意力機制中,計算注意力權重的過程中,我們會遇到點積運算(dot product)。點積運算是兩個向量之間的一種運算,結果是一個標量值。下面,我們將透過具體的例子來理解點積運算。

點積運算的定義

給定兩個向量 ( \mathbf{a} = (a_1, a_2, \ldots, a_n) ) 和 ( \mathbf{b} = (b_1, b_2, \ldots, b_n) ),它們的點積定義為: [ \mathbf{a} \cdot \mathbf{b} = a_1b_1 + a_2b_2 + \ldots + a_nb_n ]

點積運算的實作

在 PyTorch 中,我們可以使用 torch.dot() 函式來計算兩個向量的點積。下面是一個示例:

import torch

# 定義兩個向量
x = torch.tensor([1, 2, 3])
y = torch.tensor([4, 5, 6])

# 計算點積
dot_product = torch.dot(x, y)

print(dot_product)

這個示例將輸出點積的結果。

注意力權重的計算

在注意力機制中,注意力權重的計算通常涉及到查詢向量(query)和鍵值向量(key)的點積運算。假設我們有一個查詢向量 ( \mathbf{q} ) 和一個鍵值向量 ( \mathbf{k} ),那麼注意力權重可以透過以下公式計算: [ \text{Attention Weight} = \frac{\mathbf{q} \cdot \mathbf{k}}{\sqrt{d}} ] 其中,( d ) 是向量維度。

示例程式碼

下面是一個示例程式碼,展示瞭如何計算注意力權重:

import torch

# 定義查詢向量和鍵值向量
query = torch.tensor([1, 2, 3])
key = torch.tensor([4, 5, 6])

# 計算注意力權重
attention_weight = torch.dot(query, key) / math.sqrt(len(query))

print(attention_weight)

這個示例將輸出注意力權重的結果。

圖表翻譯:注意力機制的運作過程

在圖 3.8 中,我們可以看到注意力機制的運作過程。首先,選擇第二個輸入元素 x(2) 作為查詢(query)。然後,計算查詢 x(2) 與所有其他輸入元素之間的注意力得分 ω。這些注意力得分是透過查詢與每個輸入元素之間的點積計算得到的。

內容解密:注意力機制的實作

在實作注意力機制時,我們需要計算查詢與每個輸入元素之間的注意力得分。這可以透過以下步驟實作:

  1. 選擇一個輸入元素作為查詢(query)。
  2. 計算查詢與所有其他輸入元素之間的注意力得分 ω
  3. 使用這些注意力得分計算"context vector" z

以下是計算注意力得分 ω 的具體步驟:

  • 對於每個輸入元素 x(i),計算查詢 x(2)x(i) 之間的點積。
  • 將點積結果除以一個縮放因子(例如,輸入元素的維度)。
  • 對結果應用softmax函式,以得到最終的注意力得分 ω

程式碼實作

import numpy as np

def compute_attention_scores(query, inputs):
    # 計算查詢與每個輸入元素之間的點積
    dot_products = np.dot(inputs, query)
    
    # 將點積結果除以一個縮放因子
    scaled_dot_products = dot_products / np.sqrt(inputs.shape[1])
    
    # 對結果應用softmax函式
    attention_scores = np.softmax(scaled_dot_products)
    
    return attention_scores

# 示例輸入
inputs = np.array([[0.4, 0.1, 0.8], [0.5, 0.8, 0.6], [0.9, 1.4, 1.4]])
query = inputs[1]  # 選擇第二個輸入元素作為查詢

# 計算注意力得分
attention_scores = compute_attention_scores(query, inputs)

print(attention_scores)

圖表示

  flowchart TD
    A[選擇查詢] --> B[計算點積]
    B --> C[縮放點積]
    C --> D[應用softmax函式]
    D --> E[計算context vector]

圖表翻譯

此圖表示了注意力機制的運作過程。首先,選擇一個輸入元素作為查詢(query)。然後,計算查詢與所有其他輸入元素之間的點積。接下來,將點積結果除以一個縮放因子。然後,對結果應用softmax函式,以得到最終的注意力得分 ω。最後,使用這些注意力得分計算"context vector" z

3.3 使用自我注意力機制關注輸入的不同部分

在下一步驟中,如圖 3.9 所示,我們對先前計算的每個注意力評分進行歸一化。歸一化的主要目標是獲得注意力權重,使其總和等於 1。這種歸一化是一種有用的約定,對於解釋和維持大語言模型(LLM)的訓練穩定性非常重要。以下是實作此歸一化步驟的一種直接方法:

attn_weights_2_tmp = attn_scores_2 / attn_scores_2.sum()

印出結果顯示,注意力權重現在總和為 1:

注意力權重:tensor([0.1455, 0.2278, 0.2249, 0.1285, 0.1077, 0.1656])
總和:tensor(1.0000)

在實踐中,更常見和可取的做法是使用 softmax 函式進行歸一化。這種方法更好地處理極端值,並提供更有利的梯度屬性在訓練期間。

除了將點積運算視為一個數學工具,結合兩個向量以產生一個標量值外,點積也是相似度的衡量標準,因為它量化了兩個向量的對齊程度:點積越高,表示向量之間的對齊程度或相似度越高。在自我注意力機制的背景下,點積決定了序列中每個元素對其他元素的注意程度:點積越高,相似度和注意力評分越高。

我們在前一步驟中計算了這些注意力評分。現在,我們歸一化注意力評分以獲得注意力權重 α。

圖 3.9 顯示了計算注意力評分 ω 的過程,以及如何歸一化它們以獲得注意力權重 α。

以下是使用 softmax 函式進行歸一化的基本實作:

import torch
import torch.nn.functional as F

attn_scores_2 = torch.tensor([0.4, 0.1, 0.8, 0.5, 0.8, 0.6])
attn_weights_2 = F.softmax(attn_scores_2, dim=0)
print(attn_weights_2)

這將輸出歸一化的注意力權重,總和為 1。

圖表翻譯:

  graph LR
    A[注意力評分] -->|歸一化|> B[注意力權重]
    B -->|softmax|> C[歸一化注意力權重]
    C -->|總和=1|> D[最終注意力權重]

這個圖表顯示了注意力評分如何被歸一化為注意力權重,並使用 softmax 函式進行歸一化,以確保總和為 1。

softmax 函式的實作與應用

在深度學習中,softmax 函式是一種常用的啟用函式,尤其是在處理多分類別問題時。它的主要功能是將輸入的向量轉換為一個機率分佈,確保所有元素之和為 1,並且所有元素都為非負數。

softmax 函式的定義

softmax 函式的定義如下: [ \text{softmax}(x) = \frac{\exp(x_i)}{\sum_{j=1}^{n} \exp(x_j)} ] 其中,( x_i ) 是輸入向量的第 ( i ) 個元素,( n ) 是輸入向量的維度。

softmax 函式的實作

以下是使用 PyTorch 實作的 softmax 函式:

import torch

def softmax_naive(x):
    return torch.exp(x) / torch.exp(x).sum(dim=0)

這個實作直接按照 softmax 函式的定義進行計算,但是它可能會遇到數值不穩定性的問題,例如當輸入值太大或太小時。

PyTorch 的 softmax 函式

PyTorch 提供了一個內建的 softmax 函式,該函式已經被最佳化過以避免數值不穩定性的問題:

attn_weights_2 = torch.softmax(attn_scores_2, dim=0)

這個函式可以確保輸出的結果是正確的,並且避免了數值不穩定性的問題。

計算注意力權重

使用 softmax 函式,可以計算出注意力權重,如下所示:

attn_weights_2_naive = softmax_naive(attn_scores_2)
print("注意力權重:", attn_weights_2_naive)
print("總和:", attn_weights_2_naive.sum())

輸出的結果如下:

注意力權重: tensor([0.1385, 0.2379, 0.2333, 0.1240, 0.1082, 0.1581])
總和: tensor(1.)

這表明注意力權重已經被正確地計算出來,並且總和為 1。

計算 context vector

最終,可以使用注意力權重計算出 context vector,如下所示:

query = inputs[1]
context_vec_2 = torch.zeros(query.shape)

這個 context vector 是輸入向量的加權和,權重由注意力權重決定。

3.3 注意力機制:關注輸入的不同部分

在前面的章節中,我們瞭解瞭如何計算單個輸入的注意力權重和上下文向量。現在,我們將推廣這個過程,以同時計算所有輸入的注意力權重和上下文向量。

3.3.2 計算所有輸入標記的注意力權重

到目前為止,我們已經計算了第二個輸入標記的注意力權重和上下文向量,如圖 3.11 中的高亮行所示。現在,讓我們擴充套件這個計算,以計算所有輸入標記的注意力權重和上下文向量。

import torch

# 定義輸入向量
inputs = torch.tensor([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]])

# 定義注意力權重
attn_weights = torch.tensor([[0.4, 0.1, 0.8], [0.5, 0.8, 0.6], [0.8, 0.5, 0.6]])

# 初始化上下文向量
context_vecs = torch.zeros(3, 3)

# 計算上下文向量
for i, x_i in enumerate(inputs):
    context_vecs[i] = torch.sum(attn_weights[i] * x_i, dim=0)

print(context_vecs)

內容解密:

在上面的程式碼中,我們首先定義了輸入向量 inputs 和注意力權重 attn_weights。然後,我們初始化了上下文向量 context_vecs,並使用迴圈計算每個輸入標記的上下文向量。最終,我們列印預出了所有輸入標記的上下文向量。

圖表翻譯:

  flowchart TD
    A[輸入向量] --> B[注意力權重]
    B --> C[上下文向量]
    C --> D[計算上下文向量]
    D --> E[列印結果]

在這個流程圖中,我們可以看到輸入向量、注意力權重和上下文向量之間的關係。首先,我們計算注意力權重,然後使用這些權重計算上下文向量。最終,我們列印預出了所有輸入標記的上下文向量。

玄貓的深度學習之旅:注意力機制的實作

在深度學習中,注意力機制(Attention Mechanism)是一種重要的技術,用於處理序列資料,如語言翻譯、語音識別等。在這篇文章中,我們將探討注意力機制的實作,特別是如何計算注意力權重和.context向量。

注意力權重的計算

注意力權重是根據輸入向量和查詢向量之間的相關性計算得出。假設我們有兩個輸入向量 x^(1) 和 x^(2),以及一個查詢向量 q。首先,我們需要計算注意力分數(Attention Score),它代表了查詢向量和輸入向量之間的相關性。

內容解密:

import numpy as np

def attention_score(q, x):
    # 計算注意力分數
    score = np.dot(q, x) / np.linalg.norm(q) / np.linalg.norm(x)
    return score

然後,我們需要將注意力分數正規化,以得到注意力權重。這通常是透過 softmax 函式實作的。

內容解密:

import numpy as np

def softmax(scores):
    # 正規化注意力分數
    weights = np.exp(scores) / np.sum(np.exp(scores))
    return weights

Context 向量的計算

一旦我們得到注意力權重,就可以計算 context 向量了。context 向量是所有輸入向量的加權和,權重就是注意力權重。

內容解密:

import numpy as np

def context_vector(weights, inputs):
    # 計算 context 向量
    context = np.sum(weights[:, np.newaxis] * inputs, axis=0)
    return context

圖表翻譯:

  graph LR
    A[查詢向量 q] --> B[注意力分數計算]
    B --> C[注意力權重計算]
    C --> D[Context 向量計算]
    D --> E[最終輸出]

圖表翻譯:

上述圖表展示了注意力機制的實作流程。首先,計算查詢向量和輸入向量之間的注意力分數,然後正規化分數得到注意力權重,最後計算 context 向量。這個過程可以重複多次,以得到最終的輸出。

從技術架構視角來看,自注意力機制為深度學習模型提供了一種強大的上下文理解能力。透過計算注意力權重,模型能有效捕捉輸入序列中各元素間的關聯性,進而生成更具代表性的上下文向量。然而,點積運算作為注意力機制核心,其計算複雜度會隨著序列長度增加而顯著提升,這也限制了自注意力機制在處理超長序列時的效率。目前一些最佳化策略,例如引入線性注意力機制或使用稀疏注意力,都在嘗試降低計算成本的同時保持模型的效能。玄貓認為,未來隨著硬體效能的提升和演算法的持續最佳化,自注意力機制將在更多領域展現其巨大的應用潛力,尤其是在需要深度語義理解的場景,例如自然語言理解、影像識別等。對於追求高效能的開發者,建議關注這些新興的注意力機制變體,並根據實際應用場景選擇最佳方案。