博客 / 詳情

返回

吳恩達深度學習課程五:自然語言處理 第二週:詞嵌入(五)GloVe 算法

此分類用於記錄吳恩達深度學習課程的學習筆記。
課程相關信息鏈接如下:

  1. 原課程視頻鏈接:[雙語字幕]吳恩達深度學習deeplearning.ai
  2. github課程資料,含課件與筆記:吳恩達深度學習教學資料
  3. 課程配套練習(中英)與答案:吳恩達深度學習課後習題與答案

本篇為第五課的第二週內容,2.8的內容以及一些相關知識的補充。


本週為第五課的第二週內容,與 CV 相對應的,這一課所有內容的中心只有一個:自然語言處理(Natural Language Processing,NLP)
應用在深度學習裏,它是專門用來進行文本與序列信息建模的模型和技術,本質上是在全連接網絡與統計語言模型基礎上的一次“結構化特化”,也是人工智能中最貼近人類思維表達方式的重要研究方向之一。
這一整節課同樣涉及大量需要反覆消化的內容,橫跨機器學習、概率統計、線性代數以及語言學直覺。
語言不像圖像那樣“直觀可見”,更多是抽象符號與上下文關係的組合,因此理解門檻反而更高
因此,我同樣會儘量補足必要的背景知識,儘可能用比喻和實例降低理解難度。
本週的內容關於詞嵌入,是一種相對於獨熱編碼,更能保留語義信息的文本編碼方式。通過詞嵌入,模型不再只是“記住”詞本身,而是能夠基於語義關係進行泛化,在一定程度上實現類似“舉一反三”的效果。詞嵌入是 NLP 領域中最重要的基礎技術之一。

本篇的內容關於 GloVe 算法,是 Word2Vec 外,另一種以“全局”思想指導的詞嵌入算法。

1. GloVe 算法思想

在前面介紹 Word2Vec 時,我們已經看到了一條非常清晰的學習路線:通過預測任務,讓模型在訓練中“順便”學到詞的向量表示。這種思路高效且直觀,但也有一個繞不開的事實——它幾乎完全依賴局部上下文
這不難理解,在 Word2Vec 中,我們每次訓練,都是使用窗口內的序列信息來學習相應的語義並更新詞向量,每次更新只使用窗口內的詞信息,詞向量是在多次局部預測中逐步學習出來的。
由此,一個新的想法產生了:如果我們不只看窗口內的幾步關係,而是把“整個語料裏,詞與詞出現過多少次”都考慮進來,會發生什麼?

GloVe 正是這一想法的產物。
在 2014 年,論文 GloVe: Global Vectors for Word Representation被髮表,論文認為詞的語義信息,本質上藴含在詞與詞的全局共現統計關係中,而詞向量的任務,就是用一個低維連續空間去重現這種統計結構。
最終,GloVe 將傳統共現統計方法的全局視角,與分佈式詞向量的表達能力結合起來,形成了一種介於“計數方法”和“預測方法”之間的折中方案。
這裏要專門説明的是,相比於傳統神經網絡,GloVe 沒有隱藏層或激活函數,更像是一條通過詞向量內積加偏置構成的線性計算流水線,但它仍然使用梯度下降來更新參數,實現對共現統計信息的擬合,我們很難用模型那一套來描述它,因此也相對較難理解。
下面就來分點展開 GloVe 算法的實現邏輯:

2. GloVe 算法的統計部分

GloVe 算法 的起手其實是傳統的共現統計方法,這一部分並不涉及模型訓練,而是對數據進行統計和處理,得到詞彙間的全局關係。
依舊分點來看這部分內容:

2.1 統計詞共現矩陣

詞共現矩陣 是傳統統計方法裏的基礎概念,顧名思義,它是用來表示詞與詞之間共現關係的矩陣

規範一下,設詞表大小為 \(V\),定義一個矩陣 \(X \in \mathbb{R}^{V \times V}\),其中:

\[X_{ij} = \text{詞 } j \text{ 出現在詞 } i \text{ 上下文中的次數} \]

簡單舉個例子,假設語料只有一句話:

I like deep learning

顯然,詞表為:

\[\{\text{I},\ \text{like},\ \text{deep},\ \text{learning}\} \]

現在,設定上下文窗口大小為 1,即只考慮左右各一個詞。
我們統計各詞的共性關係如下:

  1. I 為中心:上下文只有 like
  2. like 為中心:上下文是 Ideep
  3. deep 為中心:上下文是 likelearning
  4. learning 為中心:上下文只有 deep

由此,我們可以得到完整的詞共現矩陣 \(X\)

\[X = \begin{array}{c|cccc} & \text{I} & \text{like} & \text{deep} & \text{learning} \\ \hline \text{I} & 0 & 1 & 0 & 0 \\ \text{like} & 1 & 0 & 1 & 0 \\ \text{deep} & 0 & 1 & 0 & 1 \\ \text{learning} & 0 & 0 & 1 & 0 \\ \end{array} \]

補充幾點細節:

  1. 在常見的統計設定中,通常手工設定不將詞與自身計入共現關係,因此共現矩陣的對角線往往為 0,但在真實語料中,若相同詞在窗口範圍內連續出現,則對應的對角元素也可能為非零值。
  2. 詞共現矩陣往往是高度稀疏的,大多數詞對在語料中根本不會共現。
  3. 詞共現矩陣是否對稱,取決於設計的統計方式,在對稱窗口下,這裏的 \(X\) 是對稱的,若區分左右上下文,矩陣則不一定對稱。

由此,我們就完成了 GloVe 算法在統計部分的第一步。
下一步,我們會把共現次數 \(X_{ij}\) 轉化為條件概率 \(P(j|i)\),進一步引入向量訓練的目標。

2.2 統計條件概率 \(P(j \mid i)\)

在完成共現矩陣統計後,GloVe 的下一步是把絕對共現次數轉化為條件概率,從而刻畫詞與詞之間更直觀的關係。
我們定義條件概率為:

\[P(j \mid i) = \frac{X_{ij}}{\sum_k X_{ik}} \]

其中:

  • \(X_{ij}\) 是詞 \(j\) 出現在詞 \(i\) 上下文中的次數,來自詞共現矩陣。
  • \(\sum_k X_{ik}\) 是以詞 \(i\) 為中心時,所有上下文詞出現次數的總和

最終,\(P(j \mid i)\) 表示在語料庫中,已知中心詞為 \(i\) 的前提下,上下文詞為 \(j\) 的經驗概率。

我們繼續使用上一節中的例子,根據共現矩陣:

\[X = \begin{array}{c|cccc} & \text{I} & \text{like} & \text{deep} & \text{learning} \\ \hline \text{I} & 0 & 1 & 0 & 0 \\ \text{like} & 1 & 0 & 1 & 0 \\ \text{deep} & 0 & 1 & 0 & 1 \\ \text{learning} & 0 & 0 & 1 & 0 \\ \end{array} \]

我們可以計算條件概率,例如:

  1. like 為中心:

\[\sum_k X_{\text{like},k} = 1 + 0 + 1 + 0 = 2 \]

於是:

\[P(\text{I} \mid \text{like}) = \frac{1}{2} = 0.5, \quad P(\text{deep} \mid \text{like}) = \frac{1}{2} = 0.5 \]

  1. I 為中心:

\[\sum_k X_{\text{I},k} = 0 + 1 + 0 + 0 = 1 \]

所以:

\[P(\text{like} \mid \text{I}) = 1 \]

最終,通過這種方式,我們就得到了語料庫中每個詞的上下文概率分佈。
我們整理例子的概率分佈矩陣如下:

\[P = \begin{array}{c|cccc} & \text{I} & \text{like} & \text{deep} & \text{learning} \\ \hline \text{I} & 0 & 1 & 0 & 0 \\ \text{like} & 0.5 & 0 & 0.5 & 0 \\ \text{deep} & 0 & 0.5 & 0 & 0.5 \\ \text{learning} & 0 & 0 & 1 & 0 \\ \end{array} \]

其中:

  • 行表示中心詞 \(i\)
  • 列表示上下文詞 \(j\)
  • 每個元素 \(P_{ij}\) 即為 \(P(j|i)\)

自此,我們就完成了GloVe 算法在統計部分的全部內容。
下面,就是它的建模部分。

3. GloVe 算法的模型部分

在完成統計階段後,我們得到了全局的共現信息及概率分佈。模型部分的核心任務就是:利用這些統計信息訓練出詞向量,使得詞向量能夠反映詞與詞之間的語義關係

GloVe 的核心思想可以概括為一句話:詞向量的內積應該能夠擬合詞與詞之間的共現概率
我們依舊分點來進行這部分內容:

3.1 計算概率比例

首先,GloVe 並不直接去擬合條件概率 \(P(j|i)\),而是利用概率比例刻畫語義關係。
設有中心詞 \(i\),上下文詞 \(j\)\(k\),則概率比例如下:

\[\frac{P(j \mid i)}{P(k \mid i)} \]

這並不難理解:

  • 如果比例大,説明 \(i\) 更傾向於與 \(j\) 一起出現。
  • 如果比例小,説明 \(i\) 更傾向於與 \(k\) 一起出現。

繼續使用同樣的例子,我們剛剛得到條件概率矩陣如下:

\[P = \begin{array}{c|cccc} & \text{I} & \text{like} & \text{deep} & \text{learning} \\ \hline \text{I} & 0 & 1 & 0 & 0 \\ \text{like} & 0.5 & 0 & 0.5 & 0 \\ \text{deep} & 0 & 0.5 & 0 & 0.5 \\ \text{learning} & 0 & 0 & 1 & 0 \\ \end{array} \]

對於中心詞 like,其上下文詞分別為 Ideep,則:

\[\frac{P(\text{I} \mid \text{like})}{P(\text{deep} \mid \text{like})} = \frac{0.5}{0.5} = 1 \]

這個比例表示,“like”與“I”和“deep”的關係同樣強
換句話説,如果模型想擬合這個關係,詞向量在空間中的表現應該讓 like-Ilike-deep 的內積接近。

而如果概率比例不是 1,例如假設在更大語料中統計到:

\[P(\text{I} \mid \text{like}) = 0.3, \quad P(\text{deep} \mid \text{like}) = 0.6 \]

則比例為:

\[\frac{P(\text{I} \mid \text{like})}{P(\text{deep} \mid \text{like})} = \frac{0.3}{0.6} = 0.5 \]

這個比例小於 1,説明“like”更傾向於與 deep 一起出現,與 I 的關聯較弱。模型訓練時,GloVe 就會嘗試讓詞向量 like-deep 的內積大於 like-I 的內積,以反映這種強弱關係。

這一步,我們通過比例概率實現了對語義的量化,而下一步就是 GloVe 的核心內容:

3.2 構建向量關係

在這一步,GloVe 就可以將概率比例量化的語義偏好轉化為向量空間中的相對位置,從而實現統計信息到詞向量的映射。
換句話説,我們希望通過訓練得到的詞向量,使得在向量空間中,中心詞與上下文詞的相對位置能夠反映它們在語料中的共現強弱
來看看 GloVe 實現這一步的具體邏輯:

首先,設定:

  1. 中心詞 \(i\) 的詞向量為 \(w_i \in \mathbb{R}^d\)
  2. 上下文詞 \(j,k\) 的詞向量為 \(\tilde w_j, \tilde w_k \in \mathbb{R}^d\)

GloVe 通過以下假設將概率比例與向量聯繫起來:

\[F(w_i, \tilde w_j, \tilde w_k) = \frac{P(j \mid i)}{P(k \mid i)} \]

其中函數 \(F\) 的含義是:用向量操作去表示概率比例,模型的目標就是擬合這個函數 \(F\)

也就是説,我們的目標是:

\[\frac{P(j \mid i)}{P(k \mid i)} \approx {\text{模型預測的某個函數值}}{} \]

但是,直接擬合比例本身有幾個問題

  1. 比例範圍廣:條件概率 \(P(j|i)\) 屬於 \([0,1]\),兩個概率比值可能非常大或非常小(比如 \(0.001/0.5 = 0.002\)),直接擬合容易數值不穩定。
  2. 向量空間線性映射困難:我們希望用向量內積(\(w_i^\top \tilde w_j\))表示關係,但向量內積是線性且可正可負,而概率比總是正且變化範圍大,直接用內積去擬合會很不直觀,也容易數值不穩定。

所以我們需要一個橋樑函數,把比例轉換成更適合線性建模的形式。

3.3 轉換概率比例

在這裏,GloVe 選擇了 對數函數,把比例變成 內積差

\[\log \frac{P(j \mid i)}{P(k \mid i)} =\log P(j|i) - \log P(k|i) \approx (w_i^\top \tilde w_j + b_i + \tilde b_j) - (w_i^\top \tilde w_k + b_i + \tilde b_k) \]

我們來詳細解釋一下這步推導的邏輯:

  1. 對數的作用:
    對數函數可以把原本範圍很廣的正數概率比壓縮到數值更穩定的區間,並且把乘法關係轉化為加法關係。數值範圍收斂,更利於模型學習,同時便於線性處理。
  2. 對映射的影響
    取了對數之後,原本的比例關係就轉化為“加減法”的形式,而向量內積本身就是線性可加的操作(\(w_i^\top \tilde w_j\) 是實數線性組合)。對數後的比例差可以直接用 線性模型(內積加偏置)來擬合,保證概率比越大,內積差越大;概率比越小,內積差越小。
  3. 偏置項的作用
    偏置項 \(b_i, \tilde b_j\) 用於捕捉詞自身的出現頻率差異
    高頻詞往往在語料中出現次數多,直接用向量內積可能被整體頻率影響而偏離比例。
    偏置項可以單獨調整每個詞的基準水平,讓向量內積專注於詞與詞之間的相對關係,而不受詞頻本身干擾。

最終,我們通過公式實現了這樣的作用:

\[\text{概率比例(統計信息)} \xrightarrow{\log} \text{線性可加的形式} \xrightarrow{\text{內積+偏置}} \text{向量表示擬合目標} \]

回到例子,假設在某大語料中統計到:

\[P(\text{I} \mid \text{like}) = 0.3, \quad P(\text{deep} \mid \text{like}) = 0.6 \]

則:

\[\log \frac{P(\text{I} \mid \text{like})}{P(\text{deep} \mid \text{like})} = \log 0.5 \approx -0.693 \]

因此,模型希望通過訓練得到的向量,使得:

\[(w_\text{like}^\top \tilde w_\text{I} + b_\text{like} + \tilde b_\text{I}) - (w_\text{like}^\top \tilde w_\text{deep} + b_\text{like} + \tilde b_\text{deep}) \approx -0.693 \]

這樣,訓練後,詞向量在空間中,“like” 會更靠近 “deep”,遠離 “I”,以反映概率比例。

下面就是最後一步了:

3.4 構建損失函數並訓練

在完成概率比例到向量內積映射後,GloVe 還需要一個可優化的損失函數來讓訓練可執行。
這一步的思想是:讓向量內積(加偏置)儘量逼近對數共現概率,同時對高頻和低頻詞對做合理的權衡。

GloVe 的損失函數定義為:

\[J = \sum_{i,j=1}^{V} f(X_{ij}) \left( w_i^\top \tilde w_j + b_i + \tilde b_j - \log X_{ij} \right)^2 \]

看起來很複雜,實際上也不簡單,我們詳細解釋一下各部分含義:

  1. 權重函數 \(f(X_{ij})\)
    為了平衡高頻和低頻詞對的影響,GloVe 引入了一個加權函數:

    \[ f(x) = \begin{cases} \left(\dfrac{x}{x_\text{max}}\right)^\alpha, & x < x_\text{max} \\ 1, & x \ge x_\text{max} \end{cases} \]

    這裏 \(x_\text{max}\) 是閾值,\(\alpha\) 通常取 \(0.75\)
    這是為了讓高頻詞對不會主導訓練,低頻詞對仍有一定權重。

  2. \(w_i^\top \tilde w_j + b_i + \tilde b_j\) :模型預測的對數共現次數,即詞向量加偏置的線性組合。

  3. \(\log X_{ij}\) :對應統計信息的對數共現次數,是我們希望模型逼近的目標。

  4. 平方誤差 \((\cdot)^2\) :衡量預測值與目標值之間的差距,使模型通過梯度下降最小化誤差。

這裏就可以解釋我們在本週第一篇中留下的問題:詞向量的長度受什麼影響?
因為高頻詞在語料中出現次數多,因此它的共現矩陣行/列上的元素整體偏大,經過訓練後,模型為了儘量逼近 \(\log X_{ij}\),會使得這些高頻詞的向量內積整體偏大,從而對應的向量長度也相對較長。
也就是説,詞向量的長度與詞頻正相關,但本身沒有其他明確的語義解釋,只是統計特性導致的結果。

同時,在這裏你可能會有一個問題:我們剛剛引入了概率比例和內積差的關係,為什麼損失函數裏都沒有用到?
實際上,對某個中心詞 \(i\),任意兩個上下文詞 \(j,k\),若你看損失梯度,會發現:
在優化過程中,梯度會自然調整 \(w_i\),讓 共現次數更多、概率大的詞對應內積更大,共現次數更少、概率小的詞對應內積更小
換句話説,比例關係會通過梯度自動體現出來,不需要顯式算比值,並且這樣還避免了顯式計算所有詞對之間的概率比造成的計算開銷。

還是用我們的例子,假設在大語料中:

中心詞 上下文詞 共現次數 \(X_{ij}\)
like I 3
like deep 6

則訓練目標:

  1. like-I
    • 目標 \(\log X_{\text{like,I}} = \log 3 \approx 1.099\)
    • 模型希望 \(w_\text{like}^\top \tilde w_\text{I} + b_\text{like} + \tilde b_\text{I} \approx 1.099\)
  2. like-deep
    • 目標 \(\log X_{\text{like,deep}} = \log 6 \approx 1.792\)
    • 模型希望 \(w_\text{like}^\top \tilde w_\text{deep} + b_\text{like} + \tilde b_\text{deep} \approx 1.792\)
  3. 權重函數 \(f(X_{ij})\) 可以調節兩者在訓練中的影響,使模型更穩健。

訓練時,GloVe 會遍歷所有有共現的詞對,計算加權平方誤差,利用梯度下降優化 \(w_i, \tilde w_j, b_i, \tilde b_j\),直到誤差收斂。
最後,你會發現,GloVe 的整個傳播過程同時在維護兩個詞向量矩陣:

  1. 中心詞向量 \(w_i\)
  2. 上下文詞向量 \(\tilde w_j\)
    而通常,我們將兩者相加或平均作為最終詞向量:

\[v_i = w_i + \tilde w_i \]

這樣得到的 \(v_i\) 便同時存在作為中心詞和上下文詞的語義距離,刻畫了詞與詞之間的全局共現關係。

4. 總結

因為 GloVe 相比起來較為複雜,這裏我們不再表格整理概念了,而是整體梳理一遍其傳播過程
image

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.