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

自然語言處理的關鍵技術:從詞嵌入到 Transformer
詞嵌入:讓電腦理解人類語言的第一步
電腦只懂得處理二進制訊號(0和1),本質上無法直接理解人類的語言與文字。那麼,我們如何讓機器理解文字的含義呢?答案是透過數值表示法。
如上圖所示,我們通過編碼器(Encoder)將文字轉換成一系列數字,這些數字就是電腦能夠處理的信息。
數字背後的意義
這些數字究竟代表什麼?它們最重要的功能是計算相似度,讓電腦能夠通過數學函式理解文字中隱含的意義。
以上圖為例,從人類角度來看,「我愛喝拿鐵」和「美式咖啡超讚」這兩句話雖然不完全相同,但確實存在一定的相似度:
- 「我愛喝」隱含著讚美的意思
- 「拿鐵」和「美式咖啡」都是相近的飲品類別
理想情況下,當我們將這兩句話通過編碼器轉換成數字向量(稱為「詞嵌入」或「Embedding」)後,這兩組數字應該彼此接近。
相似度的計算方法
那麼,如何計算這種相似度呢?
首先,我們可以使用直線距離公式:
$$ 距離 = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} $$距離越小,表示兩個詞嵌入越相似,意味著語義越接近。但這種方法存在一個問題:距離是無界的,難以判斷「300」這樣的距離值究竟意味著相近還是相遠。
因此,我們採用一種範圍在 -1~1
之間的度量方式:餘弦相似度(Cosine Similarity):
這個公式的結果範圍是:
- 1:兩個向量完全相同(方向一致)
- 0:兩個向量正交(不相關)
- -1:兩個向量方向相反
從上圖可以看出,「balls」和「kick」這兩個詞的餘弦夾角很小,表示它們在語義空間中非常接近。同理,我們期望「我愛喝拿鐵」和「美式咖啡超讚」的詞嵌入也應該被映射到相近的位置。
高維詞向量的世界
實際應用中,兩個維度遠遠不足以表達語言的複雜性。現代詞嵌入模型(如BERT)通常使用數百維的向量(如512維)來表示文字。
詞嵌入模型的訓練目標,就是學習如何將輸入的文字準確映射到這個高維空間的適當位置,使得語義相似的詞或句子在空間中彼此接近。
Transformer 模型:突破詞嵌入的限制
為什麼需要 Transformer?
傳統詞嵌入方法存在一個關鍵問題:無法處理一詞多義的情況。考慮以下兩個例子:
- 「我愛吃蘋果」
- 「iPhone16好好用,我好愛蘋果」
在傳統詞嵌入模型中,這兩個句子中的「蘋果」會被賦予相同的向量表示,因為模型無法識別上下文。結果,無論「蘋果」指的是水果還是科技公司,它們都被映射到同一個位置。
如上圖所示,「蘋果手機」中的「蘋果」本應與「手機」更接近,但在傳統模型中卻與食物的「蘋果」更相似。
解決方案?—— Attention is all you need!
Attention 機制的魔力
Transformer 模型的核心是注意力(Attention)機制,它能夠根據上下文動態調整詞的表示。
通過 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)時,我們可以期待得到更符合人類直覺的相似度計算結果。