新闻详情

新闻详情

首页 / 资讯中心 / 详情

《动手学深度学习》word2vec 近似训练深度解析:负采样与层次 Softmax 的原理、推导与源码实现

发布时间:2026/10/1 17:35:36来源:尧图网络
《动手学深度学习》word2vec 近似训练深度解析:负采样与层次 Softmax 的原理、推导与源码实现
人工智能深度学习机器学习教程【免费下载链接】d2l-zh《动手学深度学习》面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。项目地址https://gitcode.com/GitHub_Trending/d2/d2l-zh点击查看免费下载当词典规模达到数十万甚至上百万词时word2vec 跳元模型skip-gram原始 softmax 目标函数的梯度计算代价随词典大小线性增长直接训练变得不可承受。本文以《动手学深度学习》d2l-zh中 近似训练 一章为主线系统拆解两种主流近似训练方法——负采样Negative Sampling与层次 SoftmaxHierarchical Softmax——的数学动机、完整公式推导与计算复杂度分析并结合本仓库 d2l/torch.py 中的数据集构建、噪声词采样与带掩码二元交叉熵损失的源码实现帮助读者理解「为何要近似」以及「近似如何落地」最终能够在 PTB 等大规模语料上独立完成 word2vec 的预训练与词向量应用。从问题出发全词典 softmax 的梯度灾难在 词嵌入word2vec 一章中跳元模型skip-gram用 softmax 建模给定中心词 $w_c$ 时生成上下文词 $w_o$ 的条件概率$$P(w_o \mid w_c) \frac{\text{exp}(\mathbf{u}_o^\top \mathbf{v}c)}{ \sum{i \in \mathcal{V}} \text{exp}(\mathbf{u}_i^\top \mathbf{v}_c)},$$其中 $\mathcal{V}$ 为词典词表索引集合每个词同时维护两个 $d$ 维向量用作中心词的 $\mathbf{v}_i$ 与用作上下文词的 $\mathbf{u}_i$。对应的对数损失为$$\log P(w_o \mid w_c) \mathbf{u}_o^\top \mathbf{v}c - \log\left(\sum{i \in \mathcal{V}} \text{exp}(\mathbf{u}_i^\top \mathbf{v}_c)\right).$$问题在于由于上下文词可能是词典中的任意一个词分母的求和项数等于整个词典大小$|\mathcal{V}|$。对中心词向量 $\mathbf{v}_c$ 求梯度得到$$\frac{\partial \text{log}, P(w_o \mid w_c)}{\partial \mathbf{v}_c} \mathbf{u}o - \sum{j \in \mathcal{V}} P(w_j \mid w_c) \mathbf{u}_j,$$即梯度计算同样需要对全部词典词的条件概率求和。连续词袋CBOW模型的梯度word2vec.md 中 :eqref:eq_cbow-gradient同样包含这一求和。当词典包含几十万甚至上百万个词时每步梯度的计算代价是灾难性的——这就是引入近似训练的根源。为降低上述计算复杂度本节引入两种近似训练方法负采样negative sampling与层次 Softmaxhierarchical softmax。由于跳元模型与连续词袋模型高度相似下文均以跳元模型为例阐述两种方法可同样迁移到 CBOW 上。负采样用 K 个噪声词近似整个词典从「正样本事件」到有意义的联合概率负采样修改了原始目标函数。给定中心词 $w_c$ 的上下文窗口将「上下文词 $w_o$ 确实来自该窗口」视为一个事件其概率用 sigmoid 建模$$P(D1\mid w_c, w_o) \sigma(\mathbf{u}_o^\top \mathbf{v}_c),$$其中 sigmoid 激活函数定义为$$\sigma(x) \frac{1}{1\exp(-x)}.$$若直接最大化文本序列中所有这类事件的联合概率序列长度 $T$、上下文窗口 $m$$$ \prod_{t1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(D1\mid w^{(t)}, w^{(tj)}),$$会立刻暴露出一个致命缺陷该目标只包含正样本事件因此只有当所有词向量都趋于无穷大时联合概率才会收敛到 1——这样的解毫无意义。引入噪声词目标函数的改写为了让目标函数更有意义负采样从预定义分布 $P(w)$ 中为每个上下文词 $w_o$ 采样 $K$ 个不在该上下文窗口内的噪声词 $w_k$$k1,\ldots,K$。设 $S$ 为「$w_o$ 来自 $w_c$ 的上下文窗口」这一事件$N_k$ 为「噪声词 $w_k$ 不来自该窗口」的事件并假设 $S, N_1, \ldots, N_K$ 相互独立。于是原联合概率被改写为$$ \prod_{t1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(w^{(tj)} \mid w^{(t)}),$$其中条件概率通过事件 $S, N_1, \ldots, N_K$ 近似为$$ P(w^{(tj)} \mid w^{(t)}) P(D1\mid w^{(t)}, w^{(tj)})\prod_{k1,\ w_k \sim P(w)}^K P(D0\mid w^{(t)}, w_k).$$记 $i_t$ 为时间步 $t$ 处中心词 $w^{(t)}$ 的索引$h_k$ 为噪声词 $w_k$ 的索引则对应的对数损失为$$ \begin{aligned} -\log P(w^{(tj)} \mid w^{(t)}) -\log P(D1\mid w^{(t)}, w^{(tj)}) - \sum_{k1,\ w_k \sim P(w)}^K \log P(D0\mid w^{(t)}, w_k)\ - \log, \sigma\left(\mathbf{u}{i{tj}}^\top \mathbf{v}{i_t}\right) - \sum{k1,\ 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{tj}}^\top \mathbf{v}{i_t}\right) - \sum{k1,\ w_k \sim P(w)}^K \log\sigma\left(-\mathbf{u}{h_k}^\top \mathbf{v}{i_t}\right), \end{aligned} $$其中最后一步利用了 $\sigma(-x)1-\sigma(x)$ 的恒等变换把「正样本的 sigmoid 分数」与「K 个噪声样本的负 sigmoid 分数」统一成标准的二元分类形式。复杂度与词典解耦随 K 线性增长从上式可以清楚看到每一步梯度计算的代价与词典大小 $|\mathcal{V}|$ 无关而只与噪声词数量 $K$ 线性相关。超参数 $K$ 取值越小每步梯度计算开销越小同时负例数量也直接决定了模型区分「真实上下文」与「随机噪声」的强度是负采样训练中最关键的超参数之一仓库默认取 $K5$见下文。源码佐证d2l 中噪声词的采样实现仓库 d2l/torch.py 中噪声词的采样逻辑由get_negatives实现核心代码如下d2l/torch.py#L2099-L2115def get_negatives(all_contexts, vocab, counter, K): # 索引为1、2、...索引0是词表中排除的未知标记 sampling_weights [counter[vocab.to_tokens(i)]**0.75 for i in range(1, len(vocab))] all_negatives, generator [], RandomGenerator(sampling_weights) for contexts in all_contexts: negatives [] while len(negatives) len(contexts) * K: neg generator.draw() # 噪声词不能是上下文词 if neg not in contexts: negatives.append(neg) all_negatives.append(negatives) return all_negatives可以验证文档中「从预定义分布 $P(w)$ 采样」这一抽象的工程实现要点采样分布为词频的 0.75 次幂sampling_weights counter[...] ** 0.75。这是 word2vec 论文中提出的经典经验设置对词频做了平滑避免高频词如 the被过度采样为噪声噪声词排除上下文词if neg not in contexts保证采样出的噪声词确实不在当前上下文窗口中对应文档中「不来自该窗口」的 $N_k$ 事件定义高效缓存采样RandomGenerator.draw()d2l/torch.py#L2077-L2094底层使用random.choices(population, sampling_weights, k10000)一次性批量缓存 1 万个采样结果之后逐个消费避免对每个噪声词都做一次完整加权抽样是面向大规模语料的性能优化。此外训练数据构建链路load_data_ptbd2l/torch.py#L2133-L2166会依次执行read_ptb读取 PTB 语料 →subsample按概率 $\sqrt{10^{-4} \cdot \text{num_tokens} / \text{counter}[w]}$ 对高频词随机下采样见 d2l/torch.py#L2040-L2056→get_centers_and_contexts为每个中心词生成窗口大小为随机整数1 到max_window_size的上下文词列表 →get_negatives为每个中心词生成噪声词。训练落地带掩码的二元交叉熵损失负采样的损失天然对应二元交叉熵。在 预训练 word2vec 一章中PyTorch 版本通过SigmoidBCELoss实现带掩码的二元交叉熵word2vec-pretraining.mdclass SigmoidBCELoss(nn.Module): # 带掩码的二元交叉熵损失 def forward(self, inputs, target, maskNone): out nn.functional.binary_cross_entropy_with_logits( inputs, target, weightmask, reductionnone) return out.mean(dim1)其中inputs是skip_gram前向传播输出的点积分数target为标签正样本为 1、噪声样本为 0mask用于屏蔽因**变长上下文 填充padding**引入的无意义位置。batchifyd2l/torch.py#L2117-L2131把每个样本的上下文词与噪声词拼接到同一序列并用 0 填充至批量内最大长度同时生成masks有效位为 1与labels上下文词位为 1、噪声词位为 0由此可在一次前向中同时处理正负样本。训练时还按mask.shape[1] / mask.sum(axis1)做规范化使损失仅在被掩码的有效位置上求平均。在 d2l/torch.py 的load_data_ptb默认配置batch_size512, max_window_size5, num_noise_words5下配合 Adam 优化器学习率 0.002、5 个 epoch即可在 PTB 数据集上完成跳元模型的负采样预训练训练结束后可用get_similar_tokens依据中心词向量矩阵的余弦相似度检索语义相近词例如以chip为查询词返回最相似的若干词元。层次 Softmax用二叉树把求和化为路径乘积数据结构叶子为词的二叉树作为另一种近似训练方法层次 Softmax 使用二叉树数据结构每个叶子节点代表词典 $\mathcal{V}$ 中的一个词。训练前需依据词频构建 Huffman 树高频词更靠近根节点从而缩短其路径长度。下图展示了层次 Softmax 的基本结构记 $L(w)$ 为二叉树上从根节点到代表词 $w$ 的叶子节点的路径节点数含两端$n(w,j)$ 为该路径上的第 $j$ 个节点其上下文词向量为 $\mathbf{u}_{n(w, j)}$。例如上图中 $L(w_3) 4$。概率建模沿路径的 sigmoid 连乘层次 Softmax 将跳元模型的条件概率近似为沿根到叶子路径上各非叶子节点sigmoid 的连乘$$P(w_o \mid w_c) \prod_{j1}^{L(w_o)-1} \sigma\left( [![ n(w_o, j1) \text{leftChild}(n(w_o, j)) ]!] \cdot \mathbf{u}_{n(w_o, j)}^\top \mathbf{v}_c\right),$$其中 $\text{leftChild}(n)$ 表示节点 $n$ 的左子节点若 $x$ 为真则 $[![x]!]1$否则 $[![x]!]-1$。直观理解每一步都做一次「向左走还是向右走」的二元决策向左为 sigmoid 正分数向右则取负号整条路径的概率是各步决策概率的连乘。以图例中的 $w_3$ 为例从根到 $w_3$ 的路径依次为左、右、左需要计算中心词向量 $\mathbf{v}_c$ 与路径上 3 个非叶子节点向量的点积$$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).$$关键性质概率分布自动归一化层次 Softmax 最重要的理论性质是归一化。由于 $\sigma(x)\sigma(-x) 1$对任意中心词 $w_c$词典中所有词的近似条件概率之和恒为 1$$\sum_{w \in \mathcal{V}} P(w \mid w_c) 1.$$这意味着一棵二叉树的每个内部节点都以「左子树概率 右子树概率 1」的方式对概率质量做了递归划分整个词典的概率分布天然合法无需像原始 softmax 那样显式计算归一化常数——这正是省掉全词典求和的关键。复杂度从 $|\mathcal{V}|$ 降到 $\mathcal{O}(\log_2|\mathcal{V}|)$由于二叉树结构$L(w_o)-1$ 的量级为 $\mathcal{O}(\log_2|\mathcal{V}|)$。当词典规模巨大时层次 Softmax 每步训练的计算代价相比原始 softmax全词典求和显著降低只需沿一条从根到叶子的路径做约 $\log_2|\mathcal{V}|$ 次向量点积与 sigmoid 运算而无需遍历整个词典。两种方法对比与选型小结维度负采样Negative Sampling层次 SoftmaxHierarchical Softmax核心思想用 $K$ 个负例 1 个正例构造二元分类目标用根到叶子的二叉树路径乘积近似条件概率每步计算复杂度与词典大小无关线性依赖噪声词数 $K$依赖词典大小的对数$\mathcal{O}(\log_2\mathcal{V})$概率分布无需显式归一化通过正负样本对抗拟合由 $\sigma(x)\sigma(-x)1$ 保证自动归一化采样需求需要按预定义分布 $P(w)$ 采样噪声词如词频 0.75 次幂需要按词频构建二叉树如 Huffman 树典型实践d2l 预训练章节采用$K5$配合带掩码二元交叉熵适合词典极大且需完整概率分布的场景小结负采样通过构造包含正例与负例的相互独立事件来构建损失函数每步训练计算代价随噪声词数 $K$ 线性增长层次 Softmax 则利用二叉树根节点到叶子节点的路径构建损失函数每步训练计算代价随词典大小的对数增长。两者都以「用少量运算近似全词典求和」为目标是 word2vec 从玩具模型走向大规模语料预训练的关键技术。延伸练习与思考噪声词如何采样在负采样中噪声词从预定义分布 $P(w)$ 中抽取。工程上见 d2l/torch.py 的get_negatives采用词频的 0.75 次幂作为采样权重并通过random.choices批量缓存采样结果以提高效率同时噪声词必须排除当前上下文窗口中的真实上下文词。思考为什么要对词频取 0.75 次幂而不是直接用词频这与避免高频词主导负例有关。验证归一化恒等式利用 $\sigma(x)\sigma(-x)1$ 与二叉树的递归划分结构可以归纳证明对任意 $w_c$$\sum_{w \in \mathcal{V}} P(w \mid w_c) 1$ 恒成立——这正是层次 Softmax 省去显式归一化常数的数学依据。迁移到 CBOW负采样与层次 Softmax 均可用于训练连续词袋模型。区别仅在于把「给定中心词预测上下文词」的方向反过来CBOW 用上下文词向量的平均值 $\bar{\mathbf{v}}o (\mathbf{v}{o_1} \cdots \mathbf{v}{o{2m}})/(2m)$ 与中心词向量做点积见 word2vec.md正负样本的构造、损失函数形式与复杂度分析完全同理且 CBOW 训练后通常使用上下文词向量作为词表示与跳元模型取中心词向量恰好相反。在仓库中继续深入近似训练的理论推导原文chapter_natural-language-processing-pretraining/approx-training_origin.md跳元模型与 CBOW 的完整数学定义chapter_natural-language-processing-pretraining/word2vec.md基于负采样的完整预训练实现嵌入层、skip-gram 前向、损失、训练循环、相似词检索chapter_natural-language-processing-pretraining/word2vec-pretraining.md数据构建与采样源码d2l/torch.pyread_ptb、subsample、get_centers_and_contexts、get_negatives、batchify、load_data_ptb等函数均可直接查阅MXNet、TensorFlow、PaddlePaddle 版本位于 d2l/mxnet.py、d2l/tensorflow.py、d2l/paddle.py赞分享人工智能深度学习机器学习教程【免费下载链接】d2l-zh《动手学深度学习》面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。项目地址https://gitcode.com/GitHub_Trending/d2/d2l-zh点击查看免费下载相关推荐react-native-worklets Bundle Mode 补丁应用指南为 metro 与 metro-runtime 打补丁的完整实操react native worklets Bundle Mode 补丁应用指南为 metro 与 metro runtime 打补丁的完整实操 导读 rea人工智能深度学习机器学习教程如何快速上手awesome-cC开发者必备工具集合详解如何快速上手awesome cC开发者必备工具集合详解 awesome c是一个精心策划的C语言优质资源列表专为C开发者打造的一站式工具集合。它包含了从构建Aptos Move 动态调度引擎基于 AIP-73 dispatchable_fungible_asset 框架的通用回调调度实现aptos-core dispatching 示例Aptos Move 动态调度引擎基于 AIP 73 dispatchable_fungible_asset 框架的通用回调调度实现aptos core d人工智能深度学习机器学习教程上一篇AList性能优化实战3步让你的大文件传输速度提升10倍下一篇7个实用技巧让Google Drive CLI Client与终端多窗口高效集成实现并行操作提速创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

macOS 安装 JDK8 全流程:架构选择、JAVA_HOME 配置与 IDE 对接 2026/10/1 18:19:58

macOS 安装 JDK8 全流程:架构选择、JAVA_HOME 配置与 IDE 对接

Mac 上装 JDK8 这件事,乍看是最没技术含量的活儿,但我这几年帮同事收拾过的烂摊子,十个里有三四个都出在这一步:环境变量写进了不生效的文件、装完 IDEA 死活认不到、M 系列芯片上糊里糊涂跑了 x86 的包,编译慢到怀疑人…

阅读更多 →
从B站裸辞考进市委办公厅:逃离大厂背后的成本与选择 2026/10/1 18:19:58

从B站裸辞考进市委办公厅:逃离大厂背后的成本与选择

在朋友圈看到一条转帖,说的是一个在B站工作的年轻人,攒了几年钱之后突然辞职回家备考,最后考进了市委办公厅。说实话,第一眼的反应是“有点东西”,第二眼就是“扎心”——评论区里那些转发语,几乎原封不动写…

阅读更多 →
C++11 lambda与std::function包装器:从原理到工程落地全解析 2026/10/1 18:19:58

C++11 lambda与std::function包装器:从原理到工程落地全解析

1. 为什么“lambda 包装器”是C11绕不开的组合 如果你在C项目里待过一两年,肯定遇到过这样的场景:排序算法需要传入比较规则,线程要执行一段任务逻辑,界面层要给业务层注册一个回调……在C11之前,这些需求要么写一堆函…

阅读更多 →
JSP物业管理系统毕设实战:Servlet/JSP/MySQL核心代码与答辩要点解析 2026/10/1 18:19:57

JSP物业管理系统毕设实战:Servlet/JSP/MySQL核心代码与答辩要点解析

简介:一套基于JavaWeb/JSP的住宅小区物业管理系统毕业设计实战资源,面向计算机相关专业毕业生与课程设计学习者,也适合需要参考传统JavaWeb项目结构的开发者。系统围绕住宅小区日常物业管理设计,涵盖业主信息、房屋信息、费用收缴…

阅读更多 →
Unity新版Navigation系统原理与NavMeshSurface参数详解 2026/10/1 18:19:57

Unity新版Navigation系统原理与NavMeshSurface参数详解

1. 为什么新版 Navigation 不再是“点一下烘焙就完事”——从 Unity 2019.4 到 2022 的底层逻辑重写你有没有试过在 Unity 2022 LTS 里拖进一个 NavMeshSurface,点击 Bake,然后发现角色原地打转、卡在墙角、穿模飞天,甚至 Agent 根本不移动&a…

阅读更多 →
HowToCook 菜谱实战:豆豉鲮鱼油麦菜的快手小炒完整做法与原理解析 2026/10/1 18:19:51

HowToCook 菜谱实战:豆豉鲮鱼油麦菜的快手小炒完整做法与原理解析

文档教程 【免费下载链接】HowToCook Programmers guide about how to cook at home. 项目地址: https://gitcode.com/GitHub_Trending/ho/HowToCook 点击查看 免费下载 豆豉鲮鱼油麦菜是 HowToCook 仓库中一道典型的粤式罐头菜肴小炒,以油麦菜的清脆搭…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉