深入解析以太网供电(PoE)技术:从标准演进到高效设计

核心内容摘要

RVC模型Java面试八股文精讲:核心原理与优化策略
造相-Z-Image与Unity集成:游戏资产自动化生成流水线

代码动态生成技术

目录

先明确核心目标

逐段拆解代码的每一步都藏着知识点第一步导入依赖库做好准备工作第二步语料预处理——把原始文本变成模型能“看懂”的数据第三步生成训练数据——构建“上下文-中心词”样本对第四步辅助函数——将上下文转换为模型可输入的张量第五步设备选择——优先GPU加速提升训练效率第六步核心环节——用PyTorch定义CBOW模型

__init__方法模型层定义

forward方法前向传播逻辑第七步模型初始化与训练——从参数优化到模型收敛第八步模型验证与词嵌入提取——让训练成果落地

模型预测

词嵌入提取

词嵌入保存与加载

运行结果预期与作业

预期运行结果

运行结果部分截图​编辑

作业

1和

2是核心理解

先明确核心目标在看代码之前我们先理清核心任务避免“盲目看代码、不懂其意义”以一段关于“计算过程”的英文语料为训练数据设定上下文窗口大小为2即中心词左右各2个词作为上下文用PyTorch搭建简易CBOW模型通过“上下文预测中心词”的辅助任务训练模型学习词语的语义关联训练完成后从模型中提取词嵌入向量将其保存为npz文件方便后续复用比如文本分类、语义匹配等任务用训练好的模型做简单预测验证模型的训练效果。

简单说这份代码的核心就是“用PyTorch实战CBOW最终得到可用的词嵌入”全程贴合工业界基础建模流程没有多余的复杂操作新手也能轻松跟上。

逐段拆解代码的每一步都藏着知识点接下来我们跟着代码的执行顺序逐段拆解每一段代码都配上详细解读让每一行代码都有迹可循、有理可依。

第一步导入依赖库做好准备工作代码开头先导入需要的库都是PyTorch建模的“标配”无需额外安装复杂依赖import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import numpy as np from tqdm import tqdm解读torch相关库PyTorch的核心库用于搭建模型、定义损失函数、优化器等numpy用于后续词嵌入向量的保存与加载处理数值计算tqdm用于显示训练进度条直观观察训练过程提升开发体验实战中常用小技巧。

第二步语料预处理——把原始文本变成模型能“看懂”的数据任何NLP任务的第一步都是预处理计算机无法直接处理字符串必须将其转换为整数索引这一步就是完成“原始文本→索引数据”的转换context_size2#上下文大小 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() vocabset(raw_text) vocab_sizelen(vocab) print(长度,vocab_size) word_to_idx {word:i for i,word in enumerate(vocab)} idx_to_word {i:word for i,word in enumerate(vocab)}解读context_size2设定上下文窗口大小为2意味着每个中心词的上下文由“左边2个词右边2个词”组成共4个词raw_text.split()将原始文本按空格拆分得到单词列表英文文本最简单高效的分词方式中文需用jieba等专门分词工具vocabset(raw_text)对单词列表去重构建词汇表——词汇表是所有不重复单词的集合vocab_size就是词汇表大小后续模型的输入输出维度都围绕它展开word_to_idx与idx_to_word构建“单词→索引”和“索引→单词”的映射字典这是NLP建模的基础操作——将字符串单词转换为唯一整数索引模型才能进行后续计算。

第三步生成训练数据——构建“上下文-中心词”样本对CBOW模型的核心任务是“用上下文预测中心词”因此需要将预处理后的单词列表转换为模型需要的“上下文-中心词”样本对data[] for i in range(context_size,len(raw_text)-context_size): context( [raw_text[i-(2-j)] for j in range(context_size)] [raw_text[ij1] for j in range(context_size)] ) targetraw_text[i] data.append((context,target))解读循环范围range(context_size, len(raw_text)-context_size)——避免越界开头前2个词和结尾后2个词无法满足“左右各2个上下文词”的要求直接跳过上下文构建用列表推导式简洁获取上下文——左边取[i-2, i-1]右边取[i1, i2]拼接后得到4个词的上下文对应中心词raw_text[i]data列表最终存储的是(上下文单词列表, 中心词)对比如data[0]就是第一个中心词对应的上下文和目标词这是模型的核心训练样本。

第四步辅助函数——将上下文转换为模型可输入的张量模型输入需要是PyTorch张量而非列表因此定义一个辅助函数将上下文单词列表转换为长整型张量def make_context_vector(context,word_to_idx): idxs[word_to_idx[w] for w in context] return torch.tensor(idxs,dtypetorch.long)解读先将上下文单词列表通过word_to_idx字典转换为整数索引列表转换为torch.tensor且dtypetorch.long——这是nn.Embedding层词嵌入层要求的输入类型必须是长整型不能用默认的浮点型测试print(make_context_vector(data[0][0], word_to_idx))可打印第一个上下文的索引张量验证转换是否成功。

第五步设备选择——优先GPU加速提升训练效率实战中GPU能大幅提升训练速度尤其是语料量较大时这一步实现“优先使用GPU无GPU则用CPU”前提是之前配置了cuda我们在深度学习的初始就将讲诉了配置方法。

devicecuda if torch.cuda.is_available() else cpu print(device)解读torch.cuda.is_available()判断当前环境是否有可用的GPU后续模型和数据都需要通过.to(device)迁移到指定设备上保证计算在同一设备进行避免报错。

第六步核心环节——用PyTorch定义CBOW模型这是代码的灵魂部分借助PyTorch的nn.Module无需手动管理权重矩阵就能快速搭建CBOW模型class CBOW(nn.Module): def __init__(self,vocab_size,embedding_dim): super(CBOW,self).__init__() self.embeddingsnn.Embedding(vocab_size,embedding_dim) self.projnn.Linear(embedding_dim,

self.outnn.Linear(128,vocab_size) def forward(self,inputs): embedssum(self.embeddings(inputs)).view(1,-

outF.relu(self.proj(embeds)) outself.out(out) nll_probF.log_softmax(out,dim

return nll_prob解读重点

__init__方法模型层定义super(CBOW, self).__init__()继承nn.ModulePyTorch所有神经网络模型的基类获得框架提供的参数管理、模式切换等功能self.embeddingsnn.Embedding(vocab_size, embedding_dim)词嵌入核心层对应我们手动实现CBOW时的W1矩阵词汇表大小×词嵌入维度作用是将整数索引映射为低维连续的词嵌入向量权重会在训练中自动优化无需手动初始化这里我们输入的索引向量是一个数值在embedding层内部会拆解成49维度vocab_size)大小的独热编码然后通过矩阵运算转化为10维度的目标词向量。

这也就是词嵌入的过程词嵌入就是指将高维的词向量独热编码压缩成低纬度的、用较少的维度来表示的向量这个较少的向量维度每一维度都可以理解成一种特征通过不同的特征描述原来的词汇。

这就解决了独热编码没有语义相关性维度灾难的问题在我们得到的低纬度词嵌入向量是含有语义的比如篮球和乒乓球具有相关语义在词嵌入向量的空间中坐标应该比较接近。

self.projnn.Linear(embedding_dim,

额外添加的线性投影层隐藏层将词嵌入维度后续设定为10映射到128维——比基础CBOW多了这一步能让模型学习更复杂的语义关联提升词嵌入质量self.outnn.Linear(128, vocab_size)输出层将128维的隐藏层输出映射回词汇表大小维度得到每个单词的预测得分。

forward方法前向传播逻辑embedssum(self.embeddings(inputs)).view(1,-

CBOW的核心操作self.embeddings(inputs)将输入的4个上下文索引转换为4个embedding_dim维的词嵌入向量输出形状[4, 10]sum(...)对4个词嵌入向量求和等价于求平均不影响概率排序简化计算得到1个10维向量view(1,-

将10维向量重塑为[1, 10]的二维张量——线性层要求输入是“批次维度×特征维度”这里批次大小为1单样本训练。

outF.relu(self.proj(embeds))将聚合后的词嵌入输入投影层通过ReLU激活函数引入非线性让模型能学习更复杂的关系outself.out(out)将隐藏层输出映射到词汇表维度得到每个单词的原始预测得分nll_probF.log_softmax(out, dim

将原始得分转换为“概率分布的对数值”配合后续NLLLoss损失函数计算损失避免数值溢出。

第七步模型初始化与训练——从参数优化到模型收敛这是PyTorch模型训练的标准流程完整实现了“初始化→循环训练→梯度更新”还加入了进度条显示贴合实战modelCBOW(vocab_size,

.to(device) optimizeroptim.Adam(model.parameters(),lr

0.

print(model) losses[] loss_functionnn.NLLLoss() model.train() for epoch in tqdm(range(

): total_loss0 for context,target in data: context_vectormake_context_vector(context,word_to_idx).to(device) target torch.tensor([word_to_idx[target]]).to(device) train_predictmodel(context_vector) lossloss_function(train_predict,target) optimizer.zero_grad() loss.backward() optimizer.step() total_lossloss.item() losses.append(total_loss) print(losses)解读模型初始化modelCBOW(vocab_size,

.to(device)——词嵌入维度设定为10实战中常用50/100并将模型迁移到指定设备优化器optim.Adam——目前最常用的优化器之一自适应调整学习率收敛更快更稳定lr

001是经典初始学习率损失函数nn.NLLLoss负对数似然损失——专门配合log_softmax使用等价于交叉熵损失计算预测结果与真实目标的差距model.train()将模型切换到训练模式虽无Dropout等层但养成习惯后续复杂模型必备训练循环重点epoch100训练100轮轮数可根据损失收敛情况调整单样本训练遍历每个“上下文-中心词”对将上下文向量和目标词都迁移到指定设备前向传播train_predictmodel(context_vector)得到模型预测结果梯度更新三步曲缺一不可optimizer.zero_grad()清空上一轮的梯度避免梯度累积导致参数更新异常loss.backward()反向传播计算所有可训练参数词嵌入层、线性层权重的梯度optimizer.step()根据梯度更新模型参数让模型不断逼近最优解。

losses记录每轮累计总损失后续可通过绘制损失曲线观察模型是否收敛损失持续下降并平稳说明模型在有效学习。

第八步模型验证与词嵌入提取——让训练成果落地训练完成后不是结束而是要验证模型效果、提取词嵌入并保存让模型产生实际价值# 模型预测 context[People,create,to,direct] context_vectormake_context_vector(context,word_to_idx).to(device) model.eval() predictmodel(context_vector) max_idxpredict.argmax(

print(idx_to_word[max_idx.item()]) # 提取词嵌入权重 print(cbow embedding weight: ,model.embeddings.weight) Wmodel.embeddings.weight.cpu().detach().numpy() # 构建词→词向量字典 word_2_vec{} for word in word_to_idx.keys(): word_2_vec[word]W[word_to_idx[word],:] print(结束) # 保存与加载词向量 np.savez(cbow.npz,file1W) datanp.load(cbow.npz) print(data[file1])解读

模型预测model.eval()将模型切换到评估模式禁用训练模式下的特殊行为保证预测结果稳定predict.argmax(

找到预测概率最大的索引log_softmax输出中值越大概率越高idx_to_word[max_idx.item()]将索引转换为对应单词——这里上下文是[People,create,to,direct]真实中心词是programs训练到位的话模型能准确预测。

词嵌入提取model.embeddings.weight这就是我们要的词嵌入矩阵对应手动实现中的W1形状为[vocab_size, 10]每一行是一个单词的10维词嵌入向量cpu().detach().numpy()张量转Numpy数组的标准操作detach()脱离计算图避免后续操作影响模型梯度评估阶段无需计算梯度cpu()将GPU上的张量迁移到CPUNumpy不支持GPU张量numpy()转换为Numpy数组方便后续保存和使用。

word_2_vec字典构建“单词→词嵌入向量”的映射后续使用时可直接通过单词获取对应的词向量。

词嵌入保存与加载np.savez(cbow.npz, file1W)将词嵌入矩阵保存为npz格式Numpy压缩格式占用空间小方便后续复用无需重新训练np.load(cbow.npz)加载保存的词向量data[file1]就是之前保存的词嵌入矩阵可直接用于其他NLP任务。

运行结果预期与作业

预期运行结果运行这份代码后你会看到这些关键输出证明代码运行正常首先打印词汇表大小约50个左右和设备类型cuda或cpu训练过程中tqdm进度条推进每轮打印总损失损失会持续下降最终趋于平稳预测阶段输出一个单词大概率是programs验证模型预测效果最后打印词嵌入矩阵和加载后的npz文件内容形状为[vocab_size, 10]证明词向量保存、加载成功。

运行结果部分截图显然我们得到了正确的预测program

作业修改代码使得基于前面四个词预测下一个词。

雪白扔子视频大全高清免费观看-雪白扔子视频大全高清免费观看应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123