[NLP复习笔记] 基于负采样的 Skip-gram 及 SGD 训练公式推导
1. one-hot 向量
我們先了解一下 \(\text{one-hot}\) 向量。\(\text{one-hot}\) 編碼是表示分類變量的常見方法,尤其在數(shù)據(jù)預(yù)處理和機器學(xué)習(xí)的特征工程中。一個 \(\text{one-hot}\) 向量是一個其中只有一個元素是 1,其余為 0 的向量。
假設(shè)存在一個單詞集合:\(\{\text{marisa, reimu, renko, hearn}\}\),可以將這些單詞進行索引映射:
\[\begin{split} \text{marisa} \rightarrow 0 \\ \text{reimu} \rightarrow 1 \\ \text{renko} \rightarrow 2 \\ \text{hearn} \rightarrow 3 \end{split} \]那么,這些單詞經(jīng)過 \(\text{one-hot}\) 編碼的向量如下:
\[\begin{split} & \text{marisa}: [1, 0, 0, 0] \\ & \text{reimu}: [0, 1, 0, 0] \\ & \text{renko}: [0, 0, 1, 0] \\ & \text{hearn}: [0, 0, 0, 1] \end{split} \]顯然,每個位置被看作一個特征,這個特征只能是 1(存在)或者 0(不存在)。
但是,對于包含大量唯一詞匯的大型語料庫而言, \(\text{one-hot}\) 編碼會產(chǎn)生 極大的稀疏矩陣,每一個單詞對應(yīng)的詞向量都是 \(|V|\) 維的,使得 維度很高,導(dǎo)致計算效率低下。
而且 \(\text{one-hot}\) 編碼的詞向量之間都是等距的,每個詞語的向量與其他詞語的向量都是正交的關(guān)系,這意味著它們 不攜帶任何詞語間的相似性信息。
\(\text{one-hot}\) 編碼現(xiàn)在依然有比較廣泛的應(yīng)用,但在一些自然語言處理問題中,為了避免上述的限制,會采用更加高級的技術(shù),就比如 \(\text{Word2Vec}\)。
2. Word2Vec
2.1 Word2Vec 介紹
\(\text{Word2Vec}\) 模型通過訓(xùn)練神經(jīng)網(wǎng)絡(luò),為每個單詞構(gòu)建一個密集且連續(xù)的向量。這些向量被稱為 詞嵌入(word embeddings),它們捕捉大量關(guān)于單詞的語義和句法信息。每個單詞在多維空間中被表示為一個向量,向量中的每個維度代表詞義的不同方面,具體每個維度代表什么并不是人為定義的,而是通過 模型學(xué)習(xí)得到 的。
例如,經(jīng)過訓(xùn)練后,單詞 \(\text{marisa}\) 最終對應(yīng)的詞向量是 一個 \(d\) 維的向量,有可能是如下的形式:
\[vec_{\text{marisa}} = \begin{bmatrix} 0.1 \\ 1.5 \\ \vdots \\ 0.7 \end{bmatrix} \]\(vec\) 就是 目標(biāo)單詞的詞向量。這里的維度 \(d\) 是 人為設(shè)定的一個超參數(shù),表示我們需要將單詞映射到一個 \(d\) 維的向量空間,決定了 詞向量的特征數(shù)量,也就是我們想要 得到的詞向量的大小。
通過 \(\text{Word2Vec}\) 得到的詞向量 擁有相似上下文的詞在空間中的位置,能夠捕捉單詞之間的語義關(guān)系。
從維度上,提取的 \(d\) 個維度特征,可以一定程度上避免維度過高的情況;從語義上,攜帶上下文信息,可以表示出近義詞的相似性。
2.2 Skip-gram 與 CBOW
\(\text{Word2Vec}\) 模型包括輸入層、隱藏層和輸出層。模型框架根據(jù)輸入輸出的不同,主要包括 \(\text{Skip-gram}\) 和 \(\text{CBOW}\) 兩種模型。
\(\text{Skip-gram}\) 模型: 用一個詞語作為輸入,來預(yù)測其上下文。模型的目標(biāo)是 最大化在給定目標(biāo)單詞的情況下上下文單詞出現(xiàn)的概率,也就是 計算其他單詞出現(xiàn)在目標(biāo)單詞周圍的概率。
\(\text{CBOW}\) 模型: 用一個詞語的上下文作為輸入,來預(yù)測這個詞語。模型的目標(biāo)是最大化上下文單詞出現(xiàn)時目標(biāo)單詞的條件概率。
本篇文章將會介紹基于 \(\text{Negative Sampling}\) 的 \(\text{Skip-gram}\) 模型。(\(\text{Negative Sampling}\) 也就是 負(fù)采樣,是 \(\text{Word2Vec}\) 模型訓(xùn)練的加速策略之一)
3. 基于 Negative Sampling 的 Skip-gram
3.1 Skip-gram 模型
\(\text{Skip-gram}\) 模型輸入層 \(x\) 只有一個單詞,輸出層 \(y\) 為多個單詞,其基本結(jié)構(gòu)如下:
下面的 \(d\) 對應(yīng)圖中的 \(N\)。
-
輸入層 \(x\):一個 \(1 \times V\) 的 \(\text{one-hot}\) 向量,\(V\) 為詞匯表大小。表示一個單詞,也是我們的 目標(biāo)詞。
-
\(W\) 矩陣:輸入層到隱藏層之間 \(V \times d\) 的參數(shù)矩陣,包含了模型使用的所有詞向量,目的是為了將輸入層的 \(\text{one-hot}\) 向量映射到嵌入向量空間,也就是 \(d\) 維空間。
-
隱藏層 \(h\):一個 \(1 \times d\) 的特征向量,其實也就是當(dāng)前的 目標(biāo)詞對應(yīng)的詞向量 。
-
\(W^{'}\) 矩陣:隱藏層到輸出層之間的 \(d \times V\) 的參數(shù)矩陣,用來將隱藏層的表示轉(zhuǎn)換到輸出空間。也表示了所有單詞的詞向量,將于 目標(biāo)詞詞向量做內(nèi)積。
-
輸出層 \(o\):一個 \(1 \times V\) 的向量。經(jīng)過 \(h \times W^{'}\) 后(做內(nèi)積之后)產(chǎn)生一個相似度向量,向量中 每個元素 表示詞匯表 每個單詞 的 在目標(biāo)詞上下文出現(xiàn) 的 原始概率。最后要經(jīng)過一個 激活層 得到 真實概率。對于 多分類 問題,常常采用 \(\text{softmax}\) 函數(shù);對于 二分類 問題,則一般采用 \(\text{sigmoid}\) 函數(shù)。(注意,這里的輸出層并非圖中最終的輸出,只是一個概率的分布)
PS: 在后面的問題中,將會采用 \(\text{sigmoid}\) 函數(shù)。
- 輸出單詞 \(y\):\(C\) 個單詞的 \(\text{one-hot}\) 向量,其中 \(C\) 表示采用的 上下文窗口的大小。根據(jù)輸出層 \(o\) 的概率分布,選取 前 \(C\) 大概率 的單詞作為最終預(yù)測的 目標(biāo)詞 \(x\) 的上下文單詞 \(y\)。
下圖是一個上下文窗口典型示例:
3.2 Negative Sampling
傳統(tǒng)的神經(jīng)語言模型需要在每一步對全詞匯表進行運算,而 \(\text{Negative Sampling}\)(負(fù)采樣)只在更新權(quán)重時考慮一個小的負(fù)樣本集合,也就是隨機選擇一個負(fù)單詞集合(也就是若干非上下文的單詞組成的一個子集)。這樣,目標(biāo)就轉(zhuǎn)化為 最大化正樣本的概率,同時最小化負(fù)樣本的概率。
由此我們可以得到如下定義:
-
樣本概率
\[P(+ | w, c) = \sigma (c \cdot w) \]其中 \(w\) 表示 目標(biāo)詞對應(yīng)的詞向量,\(c\) 表示 目標(biāo)詞的上下文對應(yīng)的詞向量。
\(\sigma\) 表示 \(\text{sigmoid}\) 函數(shù),\(c \cdot w\) 是兩個詞向量的內(nèi)積。
-
正樣本似然函數(shù)
\[\prod P(+ | w, c_{\text{pos}}) \] -
負(fù)樣本似然函數(shù)
\[\prod P(- | w, c_{\text{neg}}) \]
我們需要最大化正樣本的概率,同時最小化負(fù)樣本的概率,所以,可以轉(zhuǎn)化為最大化下式:
\[\prod P(+ | w, c_{\text{pos}}) \prod (1 - P(- | w, c_{\text{neg}})) \]為了計算方便,我們可以取對數(shù),得到對數(shù)似然函數(shù):
\[\mathcal{L} = \text{log}(\prod P(+ | w, c_{\text{pos}}) \prod (1 - P(- | w, c_{\text{neg}}))) \]為了后續(xù)方便訓(xùn)練,我們可以變成最小化如下形式 (在前面加一個負(fù)號):
\[L = - \text{log}(\prod P(+ | w, c_{\text{pos}}) \prod (1 - P(- | w, c_{\text{neg}}))) \]由 \(\text{sigmoid}\) 函數(shù) \(f(x) = \frac{1}{1 + e^{-x}}\) 得:
\[\begin{split} L &= - \text{log}(\prod \sigma (c_{\text{pos}} \cdot w) \prod \sigma(- c_{\text{neg}} \cdot w)) \\\\ &= - \left [ \sum \text{log} \; \sigma(c_{\text{pos}} \cdot w) + \sum \text{log} \; \sigma(- c_{\text{neg}} \cdot w) \right ] \end{split} \]一般情況下使用 \(\text{SGD}\) (隨機梯度下降法)來進行學(xué)習(xí),故只需要知道對一個正樣本 \((w, c_{\text{pos}})\) 的目標(biāo)函數(shù)。假設(shè)我們隨機選取 \(k\) 個負(fù)樣本單詞作為負(fù)采樣集合,則有如下形式:
\[L = - \left [ \text{log} \; \sigma(c_{\text{pos}} \cdot w) + \sum_{i=1}^k \text{log} \; \sigma(- c_{\text{neg}_{i}} \cdot w) \right ] \]這就是我們最終要 最小化得目標(biāo)函數(shù) \(L\) 。
3.3 參數(shù)求導(dǎo)
我們最終需要得到最優(yōu)的 \(c_\text{pos}\) 、\(c_{\text{neg}}\) 以及 \(w\) 參數(shù),由 \(\text{SGD}\) 算法(應(yīng)該沒有人不懂這個算法吧),我們要分別對這些參數(shù)求導(dǎo)。
目標(biāo)函數(shù)中有 \(\text{sigmoid}\) 函數(shù),故在求導(dǎo)之前,我們先看一下 \(\text{sigmoid}\) 函數(shù)的求導(dǎo),以便后續(xù)化簡。
\(\text{sigmoid}\) 函數(shù)如下:
\[\sigma(x) = \frac{1}{1 + e^{-x}} \]我們先對其進行變形,得:
\[\begin{split} \sigma(x) &= \frac{1}{1 + e^{-x}} \\\\ &= \frac{e^x}{e^x + 1} \\\\ &= 1 - (e^x + 1)^{-1} \end{split} \]由此可得 \(\text{sigmoid}\) 的導(dǎo)數(shù)如下:
\[\begin{split} \frac{\textozvdkddzhkzd \sigma}{\textozvdkddzhkzd x} &= (e^x + 1)^{-2} e^x \\\\ &= [e^x(1 + e^{-x})]^{-2} e^x \\\\ &= (1 + e^{-x})^{-2} e^{-2x} e^x \\\\ &= (1 + e^{-x})^{-1} \cdot \frac{e^{-x}}{1 + e^{-x}} \\\\ &= \sigma(x) \cdot (1 - \sigma(x)) \end{split} \]我們可以再看下 \(\sigma(-x)\) 的導(dǎo)數(shù)。顯然 \(\text{sigmoid}\) 函數(shù)滿足 \(\sigma(-x) = 1 - \sigma(x)\),所以\(\sigma(-x)\) 的導(dǎo)數(shù)就很簡單了,就是 \(-\sigma(x) \cdot (1 - \sigma(x))\)
后面再對各個參數(shù)求導(dǎo)就比較清晰易懂了,具體過程如下(對數(shù)看作取 \(\text{ln}\) 函數(shù)):
-
對 \(c_{\text{pos}}\) 求導(dǎo)
這里使用了 鏈?zhǔn)角髮?dǎo)法則。
\[\begin{split} \frac{\partial L}{\partial c_{\text{pos}}} &= \frac{\partial}{\partial c_{\text{pos}}}(- \left [ \text{log} \; \sigma(c_{\text{pos}} \cdot w) + \sum_{i=1}^k \text{log} \; \sigma(- c_{\text{neg}_i} \cdot w) \right ]) \\\\ &= - \frac{\partial L}{\partial \sigma(c_{\text{pos}} \cdot w)} \frac{\partial \sigma(c_{\text{pos}} \cdot w)}{\partial c_{\text{pos}}} \end{split} \]其中前半部分為:
\[\frac{\partial L}{\partial \sigma(c_{\text{pos}} \cdot w)} = \frac{1}{\sigma(c_{\text{pos}} \cdot w)} \]后半部分為:
\[\frac{\partial \sigma(c_{\text{pos}} \cdot w)}{\partial c_{\text{pos}}} = \sigma(c_{\text{pos}} \cdot w) \cdot (1 - \sigma(c_{\text{pos}} \cdot w))\;w \]最后結(jié)合起來得到 \(\frac{\partial L}{\partial c_{\text{pos}}}\)(記得最全面有一個負(fù)號) :
\[\begin{split} \frac{\partial L}{\partial c_{\text{pos}}} &= - \frac{1}{\sigma(c_{\text{pos}} \cdot w)} \; \sigma(c_{\text{pos}} \cdot w) \; (1 - \sigma(c_{\text{pos}} \cdot w)) \; w \\\\ &= \left [ \sigma(c_{\text{pos}} \cdot w) - 1 \right] w \end{split} \]
-
對 \(c_{\text{neg}}\) 求導(dǎo)
使用 鏈?zhǔn)角髮?dǎo)法則
\[\begin{split} \frac{\partial L}{\partial c_{\text{neg}}} &= \frac{\partial}{\partial c_{\text{neg}}}(- \left [ \text{log} \; \sigma(c_{\text{pos}} \cdot w) + \sum_{i=1}^k \text{log} \; \sigma(- c_{\text{neg}_i} \cdot w) \right ]) \\\\ &= - \sum_{i=1}^k \frac{\partial L}{\partial \sigma(- c_{\text{neg}_i} \cdot w)} \frac{\partial \sigma(- c_{\text{neg}_i} \cdot w)}{\partial c_{\text{neg}_i}} \end{split} \]前半部分為:
\[\frac{\partial L}{\partial \sigma(- c_{\text{neg}_i} \cdot w)} = \frac{1}{\sigma(- c_{\text{neg}_i} \cdot w)} \]后半部分為:
\[\begin{split} \frac{\partial \sigma(- c_{\text{neg}_i} \cdot w)}{\partial c_{\text{neg}_i}} &= -\sigma(c_{\text{neg}_i} \cdot w) \; (1 - \sigma(c_{\text{neg}_i} \cdot w)) \; w \end{split} \]由于 \(\sigma(-x) = 1 - \sigma(x)\),我們可以把 \((1 - \sigma(c_{\text{neg}_i} \cdot w))\) 換成 \(\sigma(- c_{\text{neg}_i} \cdot w)\) 便于后續(xù)化簡:
\[\frac{\partial \sigma(- c_{\text{neg}_i} \cdot w)}{\partial c_{\text{neg}_i}} = - \sigma(c_{\text{neg}_i} \cdot w) \; \sigma(- c_{\text{neg}_i} \cdot w) \; w \]將兩個部分結(jié)合起來,得到 \(\frac{\partial L}{\partial c_{\text{neg}}}\)(記得最全面有一個負(fù)號):
\[\begin{split} \frac{\partial L}{\partial c_{\text{neg}}} &= - \sum_{i=1}^k \frac{1}{\sigma(- c_{\text{neg}_i} \cdot w)} \; \left [ - \sigma(c_{\text{neg}_i} \cdot w) \; \sigma(- c_{\text{neg}_i} \cdot w) \; w \right ] \\\\ &= \sum_{i=1}^k \frac{1}{\sigma(- c_{\text{neg}_i} \cdot w)} \; \left [ \sigma(c_{\text{neg}_i} \cdot w) \; \sigma(- c_{\text{neg}_i} \cdot w) \; w \right ] \\\\ &= \sum_{i=1}^k \sigma(c_{\text{neg}_i} \cdot w) \; w \\\\ &= [\sigma(c_{\text{neg}} \cdot w)] \; w \end{split} \]
-
對 \(w\) 求導(dǎo)
對前面兩個參數(shù)進行求導(dǎo)后,對 \(w\) 求導(dǎo)就方便多了。
\[\frac{\partial L}{\partial w} = - \left [ \frac{\partial}{\partial w}(\text{log} \; \sigma(c_{\text{pos}} \cdot w)) + \frac{\partial}{\partial w}(\sum_{i=1}^k \text{log} \; \sigma(- c_{\text{neg}_i} \cdot w)) \right ] \]對于前半部分,由
\[\frac{\partial}{\partial w} \sigma(c_{\text{pos}} \cdot w) = \sigma(c_{\text{pos}} \cdot w) \; (1 - \sigma(c_{\text{pos}} \cdot w)) \; c_{\text{pos}} \]可得
\[\begin{split} \frac{\partial}{\partial w}(\text{log} \; \sigma(c_{\text{pos}} \cdot w)) &= \frac{1}{\sigma(c_{\text{pos}} \cdot w)} \sigma(c_{\text{pos}} \cdot w) \; (1 - \sigma(c_{\text{pos}} \cdot w)) \; c_{\text{pos}} \\\\ &= [1 - \sigma(c_{\text{pos}} \cdot w)] \; c_{\text{pos}} \end{split} \]對于后半部分,由
\[\frac{\partial}{\partial w} \sigma(- c_{\text{neg}_i} \cdot w) = \sigma(- c_{\text{neg}_i} \cdot w) \; (1 - \sigma(- c_{\text{neg}_i} \cdot w) \; (-c_{\text{neg}_i}) \]得
\[\begin{split} \frac{\partial}{\partial w}(\text{log} \; \sigma(-c_{\text{neg}_i} \cdot w)) &= \frac{1}{\sigma(-c_{\text{neg}_i}\cdot w)} \sigma(- c_{\text{neg}_i} \cdot w) \; (1 - \sigma(- c_{\text{neg}_i} \cdot w) \; (-c_{\text{neg}_i}) \\\\ &= - [1 - \sigma(c_{\text{neg}_i} \cdot w)] \; c_{\text{neg}_i} \\\\ &= - [\sigma(c_{\text{neg}_i}\cdot w)] \; c_{\text{neg}_i} \end{split} \]最后結(jié)合起來,得到 \(\frac{\partial L}{\partial w}\)(記得最全面有一個負(fù)號):
\[\frac{\partial L}{\partial w} = [ \sigma(c_{\text{pos}} \cdot w) - 1] \; c_{\text{pos}} + \sum_{i=1}^k [\sigma(c_{\text{neg}_i}\cdot w)] \; c_{\text{neg}_i} \]
以上就是對參數(shù)求導(dǎo)的全部推導(dǎo)過程。
3.4 SGD 更新公式
將上面的導(dǎo)數(shù)套用到 \(\text{SGD}\) 更新公式就可以了。最后簡單寫一下更新公式:
\[c_{\text{pos}}^{t + 1} = c_{\text{pos}}^{t} - \eta \left [ \sigma(c_{\text{pos}}^t \cdot w^t) - 1 \right] w^t \] \[c_{\text{neg}}^{t + 1} = c_{\text{neg}}^{t} - \eta \left [ \sigma(c_{\text{neg}}^t \cdot w^t) \right] w^t \] \[w^{t + 1} = w^t - \eta \left ( [ \sigma(c_{\text{pos}} \cdot w) - 1] \; c_{\text{pos}} + \sum_{i=1}^k [\sigma(c_{\text{neg}_i}\cdot w)] \; c_{\text{neg}_i} \right ) \]經(jīng)過不斷迭代更新后,最后得到最優(yōu)的 \(c_\text{pos}\) 、\(c_{\text{neg}}\) 以及 \(w\) 參數(shù),也就是最終的 上下文詞向量 \(c\) 和 目標(biāo)詞對應(yīng)的詞向量 \(w\) 。
最后,通常會將兩個詞向量進行相加,來表述單詞。例如第 \(i\) 個單詞就可以表示為 \(w_i + c_i\) 。
參考
【詞向量基礎(chǔ)】:one-hot
全面理解word2vec
Word2Vec介紹:直觀理解skip-gram模型
深入淺出Word2Vec原理解析
[NLP] 秒懂詞向量Word2vec的本質(zhì)
sigmoid函數(shù)求導(dǎo)-只要四步
總結(jié)
以上是生活随笔為你收集整理的[NLP复习笔记] 基于负采样的 Skip-gram 及 SGD 训练公式推导的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一文搞懂什么是阻塞IO、信号驱动IO、R
- 下一篇: 首次引入大模型!Bert-vits2-E