目錄

(RAG技術指南-3)自然語言處理的關鍵技術:從詞嵌入到 Transformer

自然語言處理的關鍵技術:從詞嵌入到 Transformer

詞嵌入:讓電腦理解人類語言的第一步

電腦只懂得處理二進制訊號(0和1),本質上無法直接理解人類的語言與文字。那麼,我們如何讓機器理解文字的含義呢?答案是透過數值表示法

https://imgur.com/WzBYrof.png

如上圖所示,我們通過編碼器(Encoder)將文字轉換成一系列數字,這些數字就是電腦能夠處理的信息。

數字背後的意義

這些數字究竟代表什麼?它們最重要的功能是計算相似度,讓電腦能夠通過數學函式理解文字中隱含的意義。

https://imgur.com/QqMGdV7.png

以上圖為例,從人類角度來看,「我愛喝拿鐵」和「美式咖啡超讚」這兩句話雖然不完全相同,但確實存在一定的相似度:

  • 「我愛喝」隱含著讚美的意思
  • 「拿鐵」和「美式咖啡」都是相近的飲品類別

理想情況下,當我們將這兩句話通過編碼器轉換成數字向量(稱為「詞嵌入」或「Embedding」)後,這兩組數字應該彼此接近。

相似度的計算方法

那麼,如何計算這種相似度呢?

首先,我們可以使用直線距離公式:

$$ 距離 = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} $$

距離越小,表示兩個詞嵌入越相似,意味著語義越接近。但這種方法存在一個問題:距離是無界的,難以判斷「300」這樣的距離值究竟意味著相近還是相遠。

因此,我們採用一種範圍在 -1~1 之間的度量方式:餘弦相似度(Cosine Similarity):

$$ Cosine \ Similarity = \frac{x_1 \cdot x_2 + y_1 \cdot y_2}{\sqrt{x_1^2 + y_1^2} \cdot \sqrt{x_2^2 + y_2^2}} $$

這個公式的結果範圍是:

  • 1:兩個向量完全相同(方向一致)
  • 0:兩個向量正交(不相關)
  • -1:兩個向量方向相反

https://imgur.com/9c3ISa6.png

從上圖可以看出,「balls」和「kick」這兩個詞的餘弦夾角很小,表示它們在語義空間中非常接近。同理,我們期望「我愛喝拿鐵」和「美式咖啡超讚」的詞嵌入也應該被映射到相近的位置。

高維詞向量的世界

實際應用中,兩個維度遠遠不足以表達語言的複雜性。現代詞嵌入模型(如BERT)通常使用數百維的向量(如512維)來表示文字。

https://imgur.com/QXiEnth.png

詞嵌入模型的訓練目標,就是學習如何將輸入的文字準確映射到這個高維空間的適當位置,使得語義相似的詞或句子在空間中彼此接近。

Transformer 模型:突破詞嵌入的限制

為什麼需要 Transformer?

傳統詞嵌入方法存在一個關鍵問題:無法處理一詞多義的情況。考慮以下兩個例子:

  • 「我愛吃蘋果」
  • 「iPhone16好好用,我好愛蘋果」

在傳統詞嵌入模型中,這兩個句子中的「蘋果」會被賦予相同的向量表示,因為模型無法識別上下文。結果,無論「蘋果」指的是水果還是科技公司,它們都被映射到同一個位置。

https://imgur.com/0g046Ot.png

如上圖所示,「蘋果手機」中的「蘋果」本應與「手機」更接近,但在傳統模型中卻與食物的「蘋果」更相似。

解決方案?—— Attention is all you need!

Attention 機制的魔力

Transformer 模型的核心是注意力(Attention)機制,它能夠根據上下文動態調整詞的表示。

https://imgur.com/egEQSgs.png

通過 Attention 機制,「蘋果手機」中的「蘋果」現在與「手機」更接近,而與食物的「蘋果」更遠。這正是我們期望的結果!

在實際應用中,每種語言都有許多複雜的語義現象,這就是為什麼我們選擇基於 Attention 機制的 Transformer 架構作為編碼器的基礎。在後續討論中,我們將把這類編碼器統稱為「密集檢索器」(Dense Retriever)。

實際應用:簡單的相似度計算示例

以下是一個簡單的程式碼示例,展示如何計算句子之間的相似度:

# 計算相似度.py
sentenceA = "我愛蘋果手機"
sentenceB = "我愛吃蘋果"
sentenceC = "我覺得 iphone 很好用"

embeddingA = Encoder.encode(sentenceA)
embeddingB = Encoder.encode(sentenceB)
embeddingC = Encoder.encode(sentenceC)

# 使用餘弦相似度計算
ab_similarity = cosine_similarity(embeddingA, embeddingB)
ac_similarity = cosine_similarity(embeddingA, embeddingC)

if ab_similarity > ac_similarity:
    print(f"{sentenceA}{sentenceB} 比較像")
else:
    print(f"{sentenceA}{sentenceC} 比較像")

根據所選的編碼器不同(如 Word2Vec 或 BERT),結果也會有所不同。使用考慮上下文的 Transformer 模型(如 BERT)時,我們可以期待得到更符合人類直覺的相似度計算結果。