万盛网站建设,网架钢构公司,监理建设协会网站,布吉做棋牌网站建设目录
1.代码实现
2.知识点 1.代码实现
#导包
import math
import torch
from torch import nn
import dltools
#加载PTB数据集 #xff0c;需要把PTB数据集的文件夹放在代码上一级目录的data文件中#xff0c;不用解压
#批次大小、窗口大小、噪声词大小
batch_size, ma…目录
1.代码实现
2.知识点 1.代码实现
#导包
import math
import torch
from torch import nn
import dltools
#加载PTB数据集 需要把PTB数据集的文件夹放在代码上一级目录的data文件中不用解压
#批次大小、窗口大小、噪声词大小
batch_size, max_window_size, num_noise_words 512, 5, 5
#获取数据集迭代器、词汇表
data_iter, vocab dltools.load_data_ptb(batch_size, max_window_size, num_noise_words)
#讲解嵌入层embedding的用法此行代码无用#嵌入层
#通过嵌入层来获取skip—gram的中心词向量和上下文词向量
embed nn.Embedding(num_embeddings20, embedding_dim4)
# num_embeddings就是词表大小
# X的shape(batch_size, num_steps)
# --one_hot编码---batch_size, num_steps, num_embedding(vocab_size)
# --点乘中心词矩阵--(batch_size, num_steps, embed_size)
embed.weight.shape #讲解嵌入层embedding的用法此行代码无用 torch.Size([20, 4]) embedding层先one_hot编码再进行与embedding层的矩阵num_embeddingsembedding_dim乘法 #构造skip_gram的前向传播
def skip_gram(center, contexts_and_negatives, embed_v, embed_u):embed_v表示对中心词进行embedding层embed_u对上下文词进行embedding层 v embed_v(center) #中心词的词向量表达u embed_u(contexts_and_negatives) #上下文词的词向量表达#用中心词来预测上下文词#u_shape (batch_size, num_steps, embed_size)----(batch_size, embed_size, num_steps)进行矩阵乘法pred torch.bmm(v, u.permute(0, 2, 1)) #矩阵乘法bmm三维乘法不用管batch_size维度return pred
#假设数据
skip_gram(torch.ones((2, 1), dtypetorch.long), torch.ones((2, 4), dtypetorch.long), embed, embed) tensor([[[3.1980, 3.1980, 3.1980, 3.1980]],[[3.1980, 3.1980, 3.1980, 3.1980]]], grad_fnBmmBackward0) #假设数据
skip_gram(torch.ones((2, 1), dtypetorch.long), torch.ones((2, 4), dtypetorch.long), embed, embed).shape torch.Size([2, 1, 4]) #带掩码的二元交叉熵损失
class SigmoidBCELoss(nn.Module):def __init__(self):super().__init__() #直接继承父类的初始化属性和方法def forward(self, inputs, target, maskNone):#nn.functional.binary_cross_entropy_with_logits表示返回的不是转化后的概率是原始计算的数据结果#weightmask权重将掩码带上#reductionnone表示不将计算结果聚合算损失时默认聚合out nn.functional.binary_cross_entropy_with_logits(inputs, target, weightmask, reductionnone)return out.mean(dim1) #计算结果是二维的在索引1维度上聚合求平均
loss SigmoidBCELoss()
[[1.1, -2.2, 3.3, -4.4]] * 2 [[1.1, -2.2, 3.3, -4.4], [1.1, -2.2, 3.3, -4.4]] torch.tensor([[1.1, -2.2, 3.3, -4.4]] * 2).shape torch.Size([2, 4]) #假设数据测试
pred torch.tensor([[1.1, -2.2, 3.3, -4.4]] * 2)
label torch.tensor([[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0]])
mask torch.tensor([[1, 1, 1, 1], [1, 1, 0, 0]])
#mask每一行都有4个数值所以* mask.shape[1]4
#但是mask中的数值0表示权重是补充步长的不重要需要计算有效序列的损失平均值所以 / mask.sum(axis1)
loss(pred, label, mask) * mask.shape[1] / mask.sum(axis1) tensor([0.9352, 1.8462]) #初始化模型参数定义两个嵌入层
#一开始embed_weights会标准正态分布的数据初始化
#两个embedding层的参数不一样不能重复使用需要初始化定义两个
embed_size 100
net nn.Sequential(nn.Embedding(num_embeddingslen(vocab), embedding_dimembed_size),nn.Embedding(num_embeddingslen(vocab), embedding_dimembed_size)) #定义训练过程
def train(net, data_iter, lr, num_epochs, devicedltools.try_gpu()):#修改embedding层的初始化方法使用nn.init.xavier_uniform_初始化embed.weight权重,在NLP中不使用标准正态分布的额数据初始化权重def init_weights(m):if type(m) nn.Embedding:nn.init.xavier_uniform_(m.weight)net.apply(init_weights) net net.to(device)#设置梯度下降的优化器optimizer torch.optim.Adam(net.parameters(), lrlr)#设置绘制可视化的动图(epoch——loss)animator dltools.Animator(xlabelepoch, ylabelloss, xlim[1, num_epochs])#设置累加metric dltools.Accumulator(2) #2种数据需要累加for epoch in range(num_epochs): #遍历训练次数#设置计时器 赋值批次数量timer, num_batches dltools.Timer(), len(data_iter) #data_iter是分好批次的数据集长度就是批次数量num_batchesfor i, batch in enumerate(data_iter): #i是索引 batch是取出的一批批数据#梯度清零optimizer.zero_grad()#接收中心词 上下文词_噪声词 掩码 标记目标值 center, context_negative, mask, label [data.to(device) for data in batch]#调用skip_gram模型预测pred skip_gram(center, context_negative, embed_vnet[0], embed_unet[1])#计算损失l loss(pred.reshape(label.shape).float(), label.float(), mask) / mask.shape[1] * mask.sum(dim1)#用loss反向传播 ,loss先sum聚合变成标量合并成一个数值 只有标量才能反向传播l.sum().backward()#梯度更新optimizer.step()#累加metric.add(l.sum(), l.numel()) #l.sum()数值求和累加 l.numel()数量累加# % 取余数 # // 商向下取整#迭代到总数据量的5%的倍数时 或者 处理到最后一批数据时执行下面操作# i1是因为i是从0开始遍历的if (i 1) % (num_batches // 5) 0 or i num_batches - 1: #epoch (i1) / num_batches当前迭代次数占整个数据集的比例animator.add(epoch (i1) / num_batches, (metric[0] / metric[1]))print(floss {metric[0] / metric[1]:.3f}, f{metric[1] / timer.stop():.1f} tokens/sec on {str(device)})
lr, num_epochs 0.002, 50
train(net, data_iter, lr, num_epochs) #如果能够找到词的近义词 就说明训练的不错
def get_similar_tokens(query_token, k, embed):query_token:需要预测的词k最高相似度的词数量embedembedding层的哪一层#获取词向量权重 词向量权重*词的one_hot编码就是词向量W embed.weight.dataprint(fW的shape{W.shape})x W[vocab[query_token]] #embedding层是按照索引查表查词对应的权重--优点print(fx的shape{x.shape})#计算余弦相似度#torch.mv两个向量的点乘cos torch.mv(W, x) / torch.sqrt(torch.sum(W * W, dim1) * torch.sum(x * x) 1e-9)print(fcos的shape{cos.shape})#排序选择前k个对应的索引topk torch.topk(cos, kk1)[1].cpu().numpy().astype(int32)for i in topk[1:]: #排除query_token他本身自己与自己余弦相似度最高print(fcosine sim{float(cos[i]):.3f}:{vocab.to_tokens(i)})
get_similar_tokens(food, 3, net[0]) W的shapetorch.Size([6719, 100])
x的shapetorch.Size([100])
cos的shapetorch.Size([6719])
cosine sim0.430:feed
cosine sim0.418:precious
cosine sim0.412:drink 2.知识点