
【作者主页】Francek Chen
【专栏介绍】⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重要的技术特征是具有自动提取特征的能力。神经网络算法、算力和数据是开展深度学习的三要素。深度学习在计算机视觉、自然语言处理、多模态数据分析、科学探索等领域都取得了很多成果。本专栏介绍基于PyTorch的深度学习算法实现。
【GitCode】专栏资源保存在我的GitCode仓库:https://gitcode.com/Morse_Chen/PyTorch_deep_learning。
文章目录
回想一下我们在词嵌入(word2vec)中的讨论。跳元模型的主要思想是使用softmax运算来计算基于给定的中心词 w c w_c wc生成上下文字 w o w_o wo的条件概率,对应的对数损失在式(7)给出。
由于softmax操作的性质,上下文词可以是词表 V \mathcal{V} V中的任意项,式(7)包含与整个词表大小一样多的项的求和。因此,式(8)中跳元模型的梯度计算和式(15)中的连续词袋模型的梯度计算都包含求和。不幸的是,在一个词典上(通常有几十万或数百万个单词)求和的梯度的计算成本是巨大的!
为了降低上述计算复杂度,本节将介绍两种近似训练方法:负采样 和分层softmax。由于跳元模型和连续词袋模型的相似性,我们将以跳元模型为例来描述这两种近似训练方法。
一、负采样
负采样修改了原目标函数。给定中心词 w c w_c wc的上下文窗口,任意上下文词 w o w_o wo来自该上下文窗口的被认为是由下式建模概率的事件:
P ( D = 1 ∣ w c , w o ) = σ ( u o ⊤ v c ) (1) P(D=1\mid w_c, w_o) = \sigma(\mathbf{u}_o^\top \mathbf{v}_c) \tag{1} P(D=1∣wc,wo)=σ(uo⊤vc)(1) 其中 σ \sigma σ使用了sigmoid激活函数的定义:
σ ( x ) = 1 1 + exp  ( − x ) (2) \sigma(x) = \frac{1}{1+\exp(-x)} \tag{2} σ(x)=1+exp(−x)1(2)
让我们从最大化文本序列中所有这些事件的联合概率开始训练词嵌入。具体而言,给定长度为 T T T的文本序列,以 w ( t ) w^{(t)} w(t)表示时间步 t t t的词,并使上下文窗口为 m m m,考虑最大化联合概率:
∏ t = 1 T ∏ − m ≤ j ≤ m , j ≠ 0 P ( D = 1 ∣ w ( t ) , w ( t + j ) ) (3) \prod_{t=1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(D=1\mid w^{(t)}, w^{(t+j)}) \tag{3} t=1∏T−m≤j≤m, j=0∏P(D=1∣w(t),w(t+j))(3)
然而,式(3)只考虑那些正样本的事件。仅当所有词向量都等于无穷大时,式(3)中的联合概率才最大化为1。当然,这样的结果毫无意义。为了使目标函数更有意义,负采样添加从预定义分布中采样的负样本。
用 S S S表示上下文词 w o w_o wo来自中心词 w c w_c wc的上下文窗口的事件。对于这个涉及 w o w_o wo的事件,从预定义分布 P ( w ) P(w) P(w)中采样 K K K个不是来自这个上下文窗口噪声词 。用 N k N_k Nk表示噪声词 w k w_k wk( k = 1 , ... , K k=1, \ldots, K k=1,...,K)不是来自 w c w_c wc的上下文窗口的事件。假设正例和负例 S , N 1 , ... , N K S, N_1, \ldots, N_K S,N1,...,NK的这些事件是相互独立的。负采样将式(3)中的联合概率(仅涉及正例)重写为
∏ t = 1 T ∏ − m ≤ j ≤ m , j ≠ 0 P ( w ( t + j ) ∣ w ( t ) ) (4) \prod_{t=1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(w^{(t+j)} \mid w^{(t)}) \tag{4} t=1∏T−m≤j≤m, j=0∏P(w(t+j)∣w(t))(4)
通过事件 S , N 1 , ... , N K S, N_1, \ldots, N_K S,N1,...,NK近似条件概率:
P ( w ( t + j ) ∣ w ( t ) ) = P ( D = 1 ∣ w ( t ) , w ( t + j ) ) ∏ k = 1 , w k ∼ P ( w ) K P ( D = 0 ∣ w ( t ) , w k ) (5) P(w^{(t+j)} \mid w^{(t)}) =P(D=1\mid w^{(t)}, w^{(t+j)})\prod_{k=1,\ w_k \sim P(w)}^K P(D=0\mid w^{(t)}, w_k) \tag{5} P(w(t+j)∣w(t))=P(D=1∣w(t),w(t+j))k=1, wk∼P(w)∏KP(D=0∣w(t),wk)(5)
分别用 i t i_t it和 h k h_k hk表示词 w ( t ) w^{(t)} w(t)和噪声词 w k w_k wk在文本序列的时间步 t t t处的索引。式(5)中关于条件概率的对数损失为:
− log  P ( w ( t + j ) ∣ w ( t ) ) = − log  P ( D = 1 ∣ w ( t ) , w ( t + j ) ) − ∑ k = 1 , w k ∼ P ( w ) K log  P ( D = 0 ∣ w ( t ) , w k ) = − log    σ ( u i t + j ⊤ v i t ) − ∑ k = 1 , w k ∼ P ( w ) K log  ( 1 − σ ( u h k ⊤ v i t ) ) = − log    σ ( u i t + j ⊤ v i t ) − ∑ k = 1 , w k ∼ P ( w ) K log  σ ( − u h k ⊤ v i t ) (6) \begin{aligned} -\log P(w^{(t+j)} \mid w^{(t)}) =& -\log P(D=1\mid w^{(t)}, w^{(t+j)}) - \sum_{k=1,\ w_k \sim P(w)}^K \log P(D=0\mid w^{(t)}, w_k)\\ =&- \log\, \sigma\left(\mathbf{u}{i{t+j}}^\top \mathbf{v}{i_t}\right) - \sum{k=1,\ w_k \sim P(w)}^K \log\left(1-\sigma\left(\mathbf{u}{h_k}^\top \mathbf{v}{i_t}\right)\right)\\ =&- \log\, \sigma\left(\mathbf{u}{i{t+j}}^\top \mathbf{v}{i_t}\right) - \sum{k=1,\ w_k \sim P(w)}^K \log\sigma\left(-\mathbf{u}{h_k}^\top \mathbf{v}{i_t}\right) \end{aligned} \tag{6} −logP(w(t+j)∣w(t))===−logP(D=1∣w(t),w(t+j))−k=1, wk∼P(w)∑KlogP(D=0∣w(t),wk)−logσ(uit+j⊤vit)−k=1, wk∼P(w)∑Klog(1−σ(uhk⊤vit))−logσ(uit+j⊤vit)−k=1, wk∼P(w)∑Klogσ(−uhk⊤vit)(6)
我们可以看到,现在每个训练步的梯度计算成本与词表大小无关,而是线性依赖于 K K K。当将超参数 K K K设置为较小的值时,在负采样的每个训练步处的梯度的计算成本较小。
二、层序Softmax
作为另一种近似训练方法,层序Softmax (hierarchical softmax)使用二叉树(图1中说明的数据结构),其中树的每个叶节点表示词表 V \mathcal{V} V中的一个词。

图1 用于近似训练的分层softmax,其中树的每个叶节点表示词表中的一个词
用 L ( w ) L(w) L(w)表示二叉树中表示字 w w w的从根节点到叶节点的路径上的节点数(包括两端)。设 n ( w , j ) n(w,j) n(w,j)为该路径上的 j t h j^\mathrm{th} jth节点,其上下文字向量为 u n ( w , j ) \mathbf{u}{n(w, j)} un(w,j)。例如,图1中的 L ( w 3 ) = 4 L(w_3) = 4 L(w3)=4。分层softmax将词嵌入(word2vec)中的式(4)中的条件概率近似为
P ( w o ∣ w c ) = ∏ j = 1 L ( w o ) − 1 σ ( [   [ n ( w o , j + 1 ) = leftChild ( n ( w o , j ) ) ]   ] ⋅ u n ( w o , j ) ⊤ v c ) (7) P(w_o \mid w_c) = \prod{j=1}^{L(w_o)-1} \sigma\left( [\![ n(w_o, j+1) = \text{leftChild}(n(w_o, j)) ]\!] \cdot \mathbf{u}_{n(w_o, j)}^\top \mathbf{v}_c\right) \tag{7} P(wo∣wc)=j=1∏L(wo)−1σ([[n(wo,j+1)=leftChild(n(wo,j))]]⋅un(wo,j)⊤vc)(7) 其中函数 σ \sigma σ在式(2)中定义, leftChild ( n ) \text{leftChild}(n) leftChild(n)是节点 n n n的左子节点:如果 x x x为真, [   [ x ]   ] = 1 [\![x]\!] = 1 [[x]]=1;否则 [   [ x ]   ] = − 1 [\![x]\!] = -1 [[x]]=−1。
为了说明,让我们计算图1中给定词 w c w_c wc生成词 w 3 w_3 w3的条件概率。这需要 w c w_c wc的词向量 v c \mathbf{v}c vc和从根到 w 3 w_3 w3的路径(图1中加粗的路径)上的非叶节点向量之间的点积,该路径依次向左、向右和向左遍历:
P ( w 3 ∣ w c ) = σ ( u n ( w 3 , 1 ) ⊤ v c ) ⋅ σ ( − u n ( w 3 , 2 ) ⊤ v c ) ⋅ σ ( u n ( w 3 , 3 ) ⊤ v c ) (8) P(w_3 \mid w_c) = \sigma(\mathbf{u}{n(w_3, 1)}^\top \mathbf{v}c) \cdot \sigma(-\mathbf{u}{n(w_3, 2)}^\top \mathbf{v}c) \cdot \sigma(\mathbf{u}{n(w_3, 3)}^\top \mathbf{v}c) \tag{8} P(w3∣wc)=σ(un(w3,1)⊤vc)⋅σ(−un(w3,2)⊤vc)⋅σ(un(w3,3)⊤vc)(8) 由 σ ( x ) + σ ( − x ) = 1 \sigma(x)+\sigma(-x) = 1 σ(x)+σ(−x)=1,它认为基于任意词 w c w_c wc生成词表 V \mathcal{V} V中所有词的条件概率总和为1:
∑ w ∈ V P ( w ∣ w c ) = 1 (9) \sum{w \in \mathcal{V}} P(w \mid w_c) = 1 \tag{9} w∈V∑P(w∣wc)=1(9)
幸运的是,由于二叉树结构, L ( w o ) − 1 L(w_o)-1 L(wo)−1大约与 O ( log 2 ∣ V ∣ ) \mathcal{O}(\text{log}_2|\mathcal{V}|) O(log2∣V∣)是一个数量级。当词表大小 V \mathcal{V} V很大时,与没有近似训练的相比,使用分层softmax的每个训练步的计算代价显著降低。
小结
- 负采样通过考虑相互独立的事件来构造损失函数,这些事件同时涉及正例和负例。训练的计算量与每一步的噪声词数成线性关系。
- 分层softmax使用二叉树中从根节点到叶节点的路径构造损失函数。训练的计算成本取决于词表大小的对数。