当前位置: 首页 > news >正文

网站开发需要哪些技术宿州网站建设零聚思放心

网站开发需要哪些技术,宿州网站建设零聚思放心,信息聚合网站怎么做,吉林分销网站建设word2vec的实例实现 实现词嵌入word2vec中的跳字模型和近似训练中的负采样以及二次采样#xff08;subsampling#xff09;#xff0c;在语料库上训练词嵌入模型的实现。 首先导入实验所需的包或模块。 import collections import math import random import sys import …word2vec的实例实现 实现词嵌入word2vec中的跳字模型和近似训练中的负采样以及二次采样subsampling在语料库上训练词嵌入模型的实现。 首先导入实验所需的包或模块。 import collections import math import random import sys import time import os import numpy as np import torch from torch import nn import torch.utils.data as Data import osprint(torch.__version__)处理数据集 PTBPenn Tree Bank是一个常用的小型语料库 。它采样自《华尔街日报》的文章包括训练集、验证集和测试集。我们将在PTB训练集上训练词嵌入模型。该数据集的每一行作为一个句子。句子中的每个词由空格隔开。 assert ptb.train.txt in os.listdir(../ref/data/ptb)with open(../ref/data/ptb/ptb.train.txt, r) as f:lines f.readlines()# st是sentence的缩写raw_dataset [st.split() for st in lines]# sentences: %d % len(raw_dataset) # 输出 # sentences: 42068输出 # sentences: 42068对于数据集的前5个句子打印每个句子的词数和前5个词。这个数据集中句尾符为生僻词全用“表示数字则被替换成了N”。 for st in raw_dataset[:5]:print(# tokens:, len(st), st[:5])# tokens: 24 [aer, banknote, berlitz, calloway, centrust] # tokens: 15 [pierre, unk, N, years, old] # tokens: 11 [mr., unk, is, chairman, of] # tokens: 23 [rudolph, unk, N, years, old] # tokens: 34 [a, form, of, asbestos, once]建立词语索引 只保留在数据集中至少出现5次的词。 # tk是token的缩写 counter collections.Counter([tk for st in raw_dataset for tk in st]) counter dict(filter(lambda x: x[1] 5, counter.items()))然后将词映射到整数索引。 idx_to_token [tk for tk, _ in counter.items()] token_to_idx {tk: idx for idx, tk in enumerate(idx_to_token)} dataset [[token_to_idx[tk] for tk in st if tk in token_to_idx]for st in raw_dataset] num_tokens sum([len(st) for st in dataset]) # tokens: %d % num_tokens # 输出 # tokens: 887100二次采样 文本数据中一般会出现一些高频词如英文中的“the”“a”和“in”。通常来说在一个背景窗口中一个词如“chip”和较低频词如“microprocessor”同时出现比和较高频词如“the”同时出现对训练词嵌入模型更有益。因此训练词嵌入模型时可以对词进行二次采样 [2]。 具体来说数据集中每个被索引词wiw_iwi​将有一定概率被丢弃该丢弃概率为 P(wi)max⁡(1−tf(wi),0)P(w_i) \max\left(1 - \sqrt{\frac{t}{f(w_i)}}, 0\right)P(wi​)max(1−f(wi​)t​​,0) 其中 f(wi)f(w_i)f(wi​) 是数据集中词wiw_iwi​的个数与总词数之比常数ttt是一个超参数实验中设为10−410^{-4}10−4。可见只有当f(wi)tf(w_i) tf(wi​)t时我们才有可能在二次采样中丢弃词wiw_iwi​并且越高频的词被丢弃的概率越大。 def discard(idx):return random.uniform(0, 1) 1 - math.sqrt(1e-4 / counter[idx_to_token[idx]] * num_tokens) #概率丢弃subsampled_dataset [[tk for tk in st if not discard(tk)] for st in dataset] # tokens: %d % sum([len(st) for st in subsampled_dataset]) # # tokens: 375875二次采样后去掉了一半左右的词。下面比较一个词在二次采样前后出现在数据集中的次数。可见高频词“the”的采样率不足1/20。 def compare_counts(token):return # %s: before%d, after%d % (token, sum([st.count(token_to_idx[token]) for st in dataset]), sum([st.count(token_to_idx[token]) for st in subsampled_dataset]))compare_counts(the) # # the: before50770, after2013低频词“join”则完整地保留了下来。 compare_counts(join) # # join: before45, after45提取中心词和背景词 我们将与中心词距离不超过背景窗口大小的词作为它的背景词。下面定义函数提取出所有中心词和它们的背景词。它每次在整数1和max_window_size最大背景窗口之间随机均匀采样一个整数作为背景窗口大小。 def get_centers_and_contexts(dataset, max_window_size):centers, contexts [], []for st in dataset:if len(st) 2: # 每个句子至少要有2个词才可能组成一对“中心词-背景词”continuecenters stfor center_i in range(len(st)):window_size random.randint(1, max_window_size)indices list(range(max(0, center_i - window_size),min(len(st), center_i 1 window_size)))indices.remove(center_i) # 将中心词排除在背景词之外contexts.append([st[idx] for idx in indices])return centers, contexts创建一个人工数据集其中含有词数分别为7和3的两个句子。设最大背景窗口为2打印所有中心词和它们的背景词。 tiny_dataset [list(range(7)), list(range(7, 10))] print(dataset, tiny_dataset) for center, context in zip(*get_centers_and_contexts(tiny_dataset, 2)):print(center, center, has contexts, context)输出 dataset [[0, 1, 2, 3, 4, 5, 6], [7, 8, 9]] center 0 has contexts [1] center 1 has contexts [0, 2] center 2 has contexts [0, 1, 3, 4] center 3 has contexts [2, 4] center 4 has contexts [3, 5] center 5 has contexts [3, 4, 6] center 6 has contexts [5] center 7 has contexts [8, 9] center 8 has contexts [7, 9] center 9 has contexts [8]设最大背景窗口大小为5。提取数据集中所有的中心词及其背景词。 all_centers, all_contexts get_centers_and_contexts(subsampled_dataset, 5)使用负采样来进行近似训练。对于一对中心词和背景词我们随机采样KKK个噪声词实验中设K5K5K5。根据word2vec论文的建议噪声词采样概率P(w)P(w)P(w)设为www词频与总词频之比的0.75次方 def get_negatives(all_contexts, sampling_weights, K):all_negatives, neg_candidates, i [], [], 0population list(range(len(sampling_weights)))for contexts in all_contexts:negatives []while len(negatives) len(contexts) * K: #K negative for one backgroundif i len(neg_candidates):# 根据每个词的权重sampling_weights随机生成k个词的索引作为噪声词。# 为了高效计算可以将k设得稍大一点i, neg_candidates 0, random.choices(population, sampling_weights, kint(1e5)) #参数weights设置相对权重它的值是一个列表设置之后每一个成员被抽取到的概率就被确定了。neg, i neg_candidates[i], i 1# 噪声词不能是背景词if neg not in set(contexts):negatives.append(neg) #select negative from 10**5 candidatesall_negatives.append(negatives) return all_negativessampling_weights [counter[w]**0.75 for w in idx_to_token] all_negatives get_negatives(all_contexts, sampling_weights, 5)这里展示一下K与背景词数量、干扰词数量的关系 K 5 print( {} * len of ({}) len of({}).format(K, all_contexts[0], all_negatives[0]))读取数据 从数据集中提取所有中心词all_centers以及每个中心词对应的背景词all_contexts和噪声词all_negatives。我们先定义一个Dataset类。 class MyDataset(torch.utils.data.Dataset):def __init__(self, centers, contexts, negatives):assert len(centers) len(contexts) len(negatives)#trigger for exceptionself.centers centersself.contexts contextsself.negatives negativesdef __getitem__(self, index):return (self.centers[index], self.contexts[index], self.negatives[index])def __len__(self):return len(self.centers)通过随机小批量来读取它们。在一个小批量数据中第iii个样本包括一个中心词以及它所对应的nin_ini​个背景词和mim_imi​个噪声词。 由于每个样本的背景窗口大小可能不一样其中背景词与噪声词个数之和nimin_im_ini​mi​也会不同。在构造小批量时我们将每个样本的背景词和噪声词连结在一起并添加填充项0直至连结后的长度相同即长度均为max⁡inimi\max_i n_im_imaxi​ni​mi​max_len变量。为了避免填充项对损失函数计算的影响我们构造了掩码变量masks其每一个元素分别与连结后的背景词和噪声词contexts_negatives中的元素一一对应。当contexts_negatives变量中的某个元素为填充项时相同位置的掩码变量masks中的元素取0否则取1。为了区分正类和负类我们还需要将contexts_negatives变量中的背景词和噪声词区分开来。依据掩码变量的构造思路我们只需创建与contexts_negatives变量形状相同的标签变量labels并将与背景词正类对应的元素设1其余清0。 下面我们实现这个小批量读取函数batchify。它的小批量输入data是一个长度为批量大小的列表其中每个元素分别包含中心词center、背景词context和噪声词negative。该函数返回的小批量数据符合我们需要的格式例如包含了掩码变量。 def batchify(data):用作DataLoader的参数collate_fn: 输入是个长为batchsize的list, list中的每个元素都是Dataset类调用__getitem__得到的结果max_len max(len(c) len(n) for _, c, n in data)centers, contexts_negatives, masks, labels [], [], [], []for center, context, negative in data:cur_len len(context) len(negative)centers [center]contexts_negatives [context negative [0] * (max_len - cur_len)]masks [[1] * cur_len [0] * (max_len - cur_len)]labels [[1] * len(context) [0] * (max_len - len(context))]return (torch.tensor(centers).view(-1, 1), torch.tensor(contexts_negatives),torch.tensor(masks), torch.tensor(labels))用刚刚定义的batchify函数指定DataLoader实例中小批量的读取方式然后打印读取的第一个批量中各个变量的形状。 batch_size 512 num_workers 0 if sys.platform.startswith(win32) else 4dataset MyDataset(all_centers, all_contexts, all_negatives) data_iter Data.DataLoader(dataset, batch_size, shuffleTrue, #set a dataset forcollate_fnbatchify, num_workersnum_workers) for batch in data_iter:for name, data in zip([centers, contexts_negatives, masks,labels], batch):print(name, shape:, data.shape)break 输出 centers shape: torch.Size([512, 1]) contexts_negatives shape: torch.Size([512, 60]) masks shape: torch.Size([512, 60]) labels shape: torch.Size([512, 60])跳字模型 通过使用嵌入层和小批量乘法来实现跳字模型。它们也常常用于实现其他自然语言处理的应用。 嵌入层 获取词嵌入的层称为嵌入层在PyTorch中可以通过创建nn.Embedding实例得到。嵌入层的权重是一个矩阵其行数为词典大小num_embeddings列数为每个词向量的维度embedding_dim。我们设词典大小为20词向量的维度为4。 embed nn.Embedding(num_embeddings20, embedding_dim4) embed.weight输出 Parameter containing: tensor([[ 1.4661, -0.0863, -0.7256, -0.4591],[-0.1848, 0.1527, -0.9891, 1.3739],[ 1.6892, -0.8399, -0.1476, -0.6153],[ 1.6853, -0.0610, 1.8559, 0.6242],[-1.5009, 0.2730, -0.3688, 0.5599],[-1.3175, 0.9324, 0.0477, 0.6728],[ 0.0316, 0.9806, -0.6857, 1.2622],[-1.4576, -0.9973, -0.1076, 0.0197],[-1.4366, -0.8724, -0.0563, 1.2543],[-1.5040, 0.4426, -0.6406, 0.0243],[-1.4785, 1.2112, -0.2328, 1.2140],[-2.2098, -0.3141, 0.3318, -1.0206],[ 1.2869, 0.9700, 2.3408, 0.2634],[-0.7229, -0.1446, 0.5023, 1.4011],[ 0.5258, 0.7519, 0.5948, 1.2724],[-0.4999, -1.9596, -1.9181, 1.3039],[-0.5907, 0.0956, -1.3246, -0.1742],[-1.0380, -0.1586, -0.8281, 0.1813],[ 0.7077, 0.4264, 1.7595, 1.1582],[-0.5711, 0.0796, 0.7719, -0.5790]], requires_gradTrue)嵌入层的输入为词的索引。输入一个词的索引iii嵌入层返回权重矩阵的第iii行作为它的词向量。下面我们将形状为(2, 3)的索引输入进嵌入层由于词向量的维度为4我们得到形状为(2, 3, 4)的词向量。 x torch.tensor([[1, 2, 3], [4, 5, 6]], dtypetorch.long) embed(x)输出 tensor([[[-0.1848, 0.1527, -0.9891, 1.3739],[ 1.6892, -0.8399, -0.1476, -0.6153],[ 1.6853, -0.0610, 1.8559, 0.6242]],[[-1.5009, 0.2730, -0.3688, 0.5599],[-1.3175, 0.9324, 0.0477, 0.6728],[ 0.0316, 0.9806, -0.6857, 1.2622]]], grad_fnEmbeddingBackward)小批量乘法 可以使用小批量乘法运算bmm对两个小批量中的矩阵一一做乘法。 假设第一个小批量中包含nnn个形状为a×ba\times ba×b的矩阵X1,…,Xn\boldsymbol{X}_1, \ldots, \boldsymbol{X}_nX1​,…,Xn​第二个小批量中包含nnn个形状为b×cb\times cb×c的矩阵Y1,…,Yn\boldsymbol{Y}_1, \ldots, \boldsymbol{Y}_nY1​,…,Yn​。这两个小批量的矩阵乘法输出为nnn个形状为a×ca\times ca×c的矩阵X1Y1,…,XnYn\boldsymbol{X}_1\boldsymbol{Y}_1, \ldots, \boldsymbol{X}_n\boldsymbol{Y}_nX1​Y1​,…,Xn​Yn​。 因此给定两个形状分别为(nnn, aaa, bbb)和(nnn, bbb, ccc)的Tensor小批量乘法输出的形状为(nnn, aaa, ccc)。 X torch.ones((2, 1, 4)) Y torch.ones((2, 4, 6)) torch.bmm(X, Y).shape输出 X torch.ones((2, 1, 4)) Y torch.ones((2, 4, 6)) torch.bmm(X, Y).shape跳字模型前向计算 在前向计算中跳字模型的输入包含中心词索引center以及连结的背景词与噪声词索引contexts_and_negatives。其中center变量的形状为(批量大小, 1)而contexts_and_negatives变量的形状为(批量大小, max_len)。这两个变量先通过词嵌入层分别由词索引变换为词向量再通过小批量乘法得到形状为(批量大小, 1, max_len)的输出。输出中的每个元素是中心词向量与背景词向量或噪声词向量的内积。 def skip_gram(center, contexts_and_negatives, embed_v, embed_u):v embed_v(center)#(batch_size, 1)u embed_u(contexts_and_negatives)#(batch_size, max_len)pred torch.bmm(v, u.permute(0, 2, 1))return pred简单说一下Tensor.permute的作用 permute就是更改Tensor的维度下面的例子将Tensor的二、三维度做了交换 #help x torch.randn(2, 3, 5) print(x) x.permute(0,2,1)输出 tensor([[[ 0.4602, 0.1497, -0.4955, -0.6957, 0.0581],[-0.5020, -0.6797, -0.6404, 2.0036, 0.5790],[-0.0533, -0.4460, -0.2509, 0.1712, -1.3488]],[[-0.3313, 0.7201, 0.2478, -1.6327, -0.4580],[ 0.5060, -0.1724, 2.7267, 0.1494, -0.3988],[-1.8063, -0.5025, -0.3524, 0.4211, 1.5029]]]) tensor([[[ 0.4602, -0.5020, -0.0533],[ 0.1497, -0.6797, -0.4460],[-0.4955, -0.6404, -0.2509],[-0.6957, 2.0036, 0.1712],[ 0.0581, 0.5790, -1.3488]],[[-0.3313, 0.5060, -1.8063],[ 0.7201, -0.1724, -0.5025],[ 0.2478, 2.7267, -0.3524],[-1.6327, 0.1494, 0.4211],[-0.4580, -0.3988, 1.5029]]])训练模型 定义二元交叉熵损失函数 根据负采样中损失函数的定义我们可以使用二元交叉熵损失函数 −log⁡P(w(tj)∣w(t))−log⁡P(D1∣w(t),w(tj))−∑k1,wk∼P(w)Klog⁡P(D0∣w(t),wk)−log⁡σ(uitj⊤vit)−∑k1,wk∼P(w)Klog⁡(1−σ(uhk⊤vit))−log⁡σ(uitj⊤vit)−∑k1,wk∼P(w)Klog⁡σ(−uhk⊤vit).\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(\boldsymbol{u}_{i_{tj}}^\top \boldsymbol{v}_{i_t}\right) - \sum{k1,\ w_k \sim P(w)}^K \log\left(1-\sigma\left(\boldsymbol{u}_{h_k}^\top \boldsymbol{v}_{i_t}\right)\right)\\\ - \log \sigma\left(\boldsymbol{u}_{i_{tj}}^\top \boldsymbol{v}_{i_t}\right) - \sum{k1,\ w_k \sim P(w)}^K \log\sigma\left(-\boldsymbol{u}_{h_k}^\top \boldsymbol{v}_{i_t}\right). \end{aligned} −logP(w(tj)∣w(t)) ​−logP(D1∣w(t),w(tj))−k1, wk​∼P(w)∑K​logP(D0∣w(t),wk​) −logσ(uitj​⊤​vit​​)−∑k1, wk​∼P(w)Klog(1−σ(uhk​⊤​vit​​))−logσ(uitj​⊤​vit​​)−∑k1, wk​∼P(w)Klogσ(−uhk​⊤​vit​​).​ 下面定义SigmoidBinaryCrossEntropyLoss。 class SigmoidBinaryCrossEntropyLoss(nn.Module):def __init__(self): # none mean sumsuper(SigmoidBinaryCrossEntropyLoss, self).__init__()def forward(self, inputs, targets, maskNone):input – Tensor shape: (batch_size, len)target – Tensor of the same shape as inputinputs, targets, mask inputs.float(), targets.float(), mask.float()res nn.functional.binary_cross_entropy_with_logits(inputs, targets, reductionnone, weightmask)return res.mean(dim1)loss SigmoidBinaryCrossEntropyLoss()我们可以通过掩码变量指定小批量中参与损失函数计算的部分预测值和标签 当掩码为1时相应位置的预测值和标签将参与损失函数的计算当掩码为0时相应位置的预测值和标签则不参与损失函数的计算。 我们之前提到掩码变量可用于避免填充项对损失函数计算的影响。 pred torch.tensor([[1.5, 0.3, -1, 2], [1.1, -0.6, 2.2, 0.4]]) # 标签变量label中的1和0分别代表背景词和噪声词 label torch.tensor([[1, 0, 0, 0], [1, 1, 0, 0]]) mask torch.tensor([[1, 1, 1, 1], [1, 1, 1, 0]]) # 掩码变量 loss(pred, label, mask) * mask.shape[1] / mask.float().sum(dim1)输出 tensor([0.8740, 1.2100])下面将从零开始实现二元交叉熵损失函数的计算并根据掩码变量mask计算掩码为1的预测值和标签的损失。 def sigmd(x):return - math.log(1 / (1 math.exp(-x)))print(%.4f % ((sigmd(1.5) sigmd(-0.3) sigmd(1) sigmd(-2)) / 4)) # 注意1-sigmoid(x) sigmoid(-x) print(%.4f % ((sigmd(1.1) sigmd(-0.6) sigmd(-2.2)) / 3))输出 0.8740 1.2100发现结果和使用pytorch内置函数是一样的 初始化模型参数 分别构造中心词和背景词的嵌入层并将超参数词向量维度embed_size设置成100。 embed_size 100 net nn.Sequential(nn.Embedding(num_embeddingslen(idx_to_token), embedding_dimembed_size),nn.Embedding(num_embeddingslen(idx_to_token), embedding_dimembed_size) )定义训练函数 由于填充项的存在与之前的训练函数相比损失函数的计算稍有不同 def train(net, lr, num_epochs):device torch.device(cuda if torch.cuda.is_available() else cpu)print(train on, device)net net.to(device)optimizer torch.optim.Adam(net.parameters(), lrlr)for epoch in range(num_epochs):start, l_sum, n time.time(), 0.0, 0for batch in data_iter:center, context_negative, mask, label [d.to(device) for d in batch]pred skip_gram(center, context_negative, net[0], net[1])# 使用掩码变量mask来避免填充项对损失函数计算的影响l (loss(pred.view(label.shape), label, mask) *mask.shape[1] / mask.float().sum(dim1)).mean() # 一个batch的平均lossoptimizer.zero_grad()l.backward()optimizer.step()l_sum l.cpu().item()n 1print(epoch %d, loss %.2f, time %.2fs% (epoch 1, l_sum / n, time.time() - start)) train(net, 0.01, 10)输出 train on cuda epoch 1, loss 1.97, time 7.79s epoch 2, loss 0.63, time 7.28s epoch 3, loss 0.45, time 7.43s epoch 4, loss 0.40, time 7.62s epoch 5, loss 0.37, time 7.46s epoch 6, loss 0.35, time 7.39s epoch 7, loss 0.34, time 7.64s epoch 8, loss 0.33, time 7.60s epoch 9, loss 0.32, time 7.34s epoch 10, loss 0.32, time 7.38s应用词嵌入模型 根据两个词向量的余弦相似度表示词与词之间在语义上的相似度 def get_similar_tokens(query_token, k, embed):W embed.weight.datax W[token_to_idx[query_token]]# 添加的1e-9是为了数值稳定性cos torch.matmul(W, x) / (torch.sum(W * W, dim1) * torch.sum(x * x) 1e-9).sqrt() #词向量之间的关联性_, topk torch.topk(cos, kk1)topk topk.cpu().numpy()for i in topk[1:]: # 除去输入词print(cosine sim%.3f: %s % (cos[i], (idx_to_token[i])))get_similar_tokens(news, 10, net[0])输出 cosine sim0.424: hoffman cosine sim0.398: daughter cosine sim0.396: tokyo cosine sim0.394: attributed cosine sim0.376: slew cosine sim0.373: steps cosine sim0.370: pleased cosine sim0.369: daily cosine sim0.362: reviewing cosine sim0.361: wednesday输出了与”news“最相关的10个词按照相关度排序
http://www.pierceye.com/news/10368/

相关文章:

  • 专业建站推广网络公司网页制作与网站建设的题
  • 医院网站建设公司价格低南京高端网站开发
  • wordpress多语言企业网站软件设计师培训机构
  • 免费做公益网站网站建设创新
  • 企业网站模板 优帮云做网站怎么弄
  • dede小视频网站源码网络营销网站建设ppt
  • 烟台 o2o平台带动做网站行业上海传媒公司总裁李健
  • 综合购物网站建站长沙百姓网
  • 公司网站总感觉少点什么找什么人做东莞建筑设计院排名
  • 商城网站功能介绍网站怎么做推广和宣传
  • 口碑好的盐城网站建设广州天河区房价2022年最新房价
  • 龙川县建设网站asp做网站优点
  • 杭州网站建设 seo西安教育平台网站建设
  • 中国芗城区城乡建设局网站dede门户网站模板下载
  • 网站站点管理在哪里做网站推广的好处
  • 桂林北站怎么去阳朔外贸网站建设 泰州
  • 2003网站的建设介绍小说的网站模板下载
  • 如何做网站策划win2003网站建设
  • 艺美网站建设徐州建站方案
  • 宁阳网站定制制作营业执照图片手机软件
  • 网站开发常用js函数制作企业宣传册用什么软件
  • 泰州专业制作网站网站制作实例
  • 如何建设网站平台做网站 每月赚 钱
  • 免费手机做网站北京代建网站
  • 福建省龙岩市建设培训中心网站网络规划设计师教程第2版pdf下载
  • 一个网站的制作特点代运营公司怎么找客户
  • 用front page2003做网站的导航条客户要做网站建设话术
  • 合肥市住房和建设局网站仙桃城市建设投资公司网站
  • 成都网站建设是什么意思智慧团建网页版登录入口
  • 嘉兴网站制作计划银川网站建设