NLP 入门|PyTorch 从零实现 Word2Vec 之 CBOW 模型

张开发
2026/4/11 3:33:51 15 分钟阅读

分享文章

NLP 入门|PyTorch 从零实现 Word2Vec 之 CBOW 模型
在深度学习与自然语言处理NLP中如何让机器 “看懂” 人类语言是一切任务的起点。传统方法依赖 One‑Hot 编码极易造成维度灾难与语义缺失而词嵌入Word Embedding凭借低维、稠密、可表达语义的优势成为现代 NLP 的标配基础技术。Google 在 2013 年提出的Word2Vec是训练词向量最经典、最高效的算法包含CBOW与Skip‑Gram两种核心模型。本篇博客将严格按照课堂 PPT 知识点从语言向量化原理讲起深入 CBOW 模型结构与训练流程最后使用PyTorch 从零手写 CBOW 完整代码实现词向量训练、预测、提取与保存理论 代码一一对应零基础也能轻松上手。一、本章核心内容语言向量化从 One‑Hot 到词嵌入 Embedding解决稀疏与维度灾难Word2Vec 原理CBOW上下文→中心词模型结构与训练步骤深度学习训练损失函数、前向 / 反向传播、参数更新实战项目PyTorch 实现 CBOW训练词向量并完成预测任务二、核心理论1. 为什么要用词嵌入One‑Hot 编码向量稀疏、维度爆炸、无语义关联词嵌入高维稀疏 → 低维稠密常用维度 100/200/300语义相近的词向量空间距离更近2. CBOW 模型核心思想以上下文单词预测中心目标词训练过程中自动学习到的嵌入层权重就是我们需要的词向量。3. CBOW 训练流程PPT上下文 One‑Hot 输入矩阵映射得到低维向量向量求和 / 平均全连接 Softmax 输出概率计算损失、反向传播更新矩阵最终保留W 矩阵作为词向量三、项目实战PyTorch 实现 CBOW 词向量训练1. 项目说明任务训练 CBOW 模型学习文本词向量输入上下文单词输出预测中心词 生成稠密词向量框架PyTorch设备自动支持 CUDA/MPS/CPU2. 完整代码import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from tqdm import tqdm, trange import numpy as np # 1. 超参数设置 CONTEXT_SIZE 2 # 上下文窗口左右各取2个词对应PPT窗口设置 # 2. 语料库与词汇表 raw_text We are about to study the idea of a computational process. Computational processes are abstract beings that inhabit computers. As they evolve, processes manipulate other abstract things called data. The evolution of a process is directed by a pattern of rules called a program. People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells..split() vocab set(raw_text) vocab_size len(vocab) # 单词 ↔ 索引 映射 word_to_idx {word: i for i, word in enumerate(vocab)} idx_to_word {i: word for i, word in enumerate(vocab)} # 3. 构建训练数据上下文目标词 data [] for i in range(CONTEXT_SIZE, len(raw_text) - CONTEXT_SIZE): # 左2个 右2个 上下文 context ( [raw_text[i - (2-j)] for j in range(CONTEXT_SIZE)] [raw_text[i j 1] for j in range(CONTEXT_SIZE)] ) target raw_text[i] # 中心词标签 data.append((context, target)) # 4. 转换为模型可读取的张量 def make_context_vector(context, word_to_ix): idxs [word_to_ix[w] for w in context] return torch.tensor(idxs, dtypetorch.long) # 示例输出 print(示例上下文索引, make_context_vector(data[0][0], word_to_idx)) # 5. 自动选择训练设备 device cuda if torch.cuda.is_available() else mps if torch.backends.mps.is_available() else cpu print(训练设备, device) # 6. 定义CBOW模型对应PPT网络结构 class CBOW(nn.Module): def __init__(self, vocab_size, embedding_dim): super(CBOW, self).__init__() # 词嵌入层对应PPT W矩阵 self.embeddings nn.Embedding(vocab_size, embedding_dim) # 投影层 self.proj nn.Linear(embedding_dim, 128) # 输出层对应PPT W’矩阵 self.output nn.Linear(128, vocab_size) def forward(self, inputs): # 对上下文词向量求和CBOW核心操作 embds sum(self.embeddings(inputs)).view(1, -1) out F.relu(self.proj(embds)) out self.output(out) # 对数Softmax配合NLLLoss计算损失 nll_prob F.log_softmax(out, dim-1) return nll_prob # 7. 模型初始化 model CBOW(vocab_size, 10).to(device) optimizer optim.Adam(model.parameters(), lr0.001) loss_function nn.NLLLoss() # 多分类损失对应PPT损失函数 losses [] # 8. 模型训练 model.train() for epoch in tqdm(range(200)): total_loss 0 for context, target in data: context_vector make_context_vector(context, word_to_idx).to(device) target torch.tensor([word_to_idx[target]]).to(device) # 前向传播 train_predict model(context_vector) loss loss_function(train_predict, target) # 反向传播 更新参数 optimizer.zero_grad() loss.backward() optimizer.step() total_loss loss.item() losses.append(total_loss) # 9. 模型测试预测中心词 context [People, create, to, direct] context_vector make_context_vector(context, word_to_idx).to(device) model.eval() with torch.no_grad(): predict model(context_vector) max_idx predict.argmax(1).item() print(上下文, context) print(模型预测中心词, idx_to_word[max_idx]) # 10. 提取并保存词向量PPT重点 W model.embeddings.weight.cpu().detach().numpy() # 构建单词→词向量字典 word_2_vec {} for word in word_to_idx.keys(): word_2_vec[word] W[word_to_idx[word]] # 保存为npz方便后续项目使用 np.savez(word2vec实现.npz, file_1W) load_data np.load(word2vec实现.npz) print(保存内容, load_data.files) print( 词向量训练与保存完成 )

更多文章