赞
踩
词嵌入是稠密向量。如何在计算机中表示一个单词呢?存储它的ascii字符表示形式,但这只能表明词是什么,它并没有说明其含义(可以从其词缀或大写字母中得出其词性,但是不多)。在什么意义上组合这些表示形式,通常需要神经网络的稠密表示。如何从高维空间变成低维空间?
独热编码的表示形式如下:
句子中词所在位置为1,非句子中词的位置为0;
这种表示法有两个缺点:
1)维度大
2) 单词之间相互独立
我们如何解决这个问题?也就是说,我们如何实际编码单词中的语义相似性?也许我们想到了一些语义属性。例如,我们看到数学家和物理学家都可以运行,因此也许我们为这些单词的“能够运行”语义属性评分很高。考虑其他一些属性,并想象您会在这些属性上给一些常见的单词打分。
如果每个属性都是一个维,则可以给每个单词一个向量,如下所示:
然后,通过执行以下操作,可以得出这些词之间的相似度:
尽管通过长度进行归一化比较常见:
在开始工作示例和练习之前,先简要介绍一下如何在Pytorch和深度学习编程中使用嵌入。类似于我们在制作单热向量时为每个单词定义唯一索引的方式,我们也需要在使用嵌入时为每个单词定义索引。这些将成为查找表的关键字。也就是说,嵌入存储为|V|×D矩阵,其中 D是嵌入的维数,因此单词分配索引 i将其嵌入存储在 i矩阵的第th行。在我的所有代码中,从单词到索引的映射都是一个名为word_to_ix的字典。
允许您使用嵌入的模块是torch.nn.Embedding,它带有两个参数:词汇量和嵌入的维数。
要在该表中建立索引,必须使用torch.LongTensor(因为索引是整数,而不是浮点数)。
回想一下,在n元语法模型中,给出了一系列单词 w,我们要计算
wi 是序列的第i个词
在此示例中,我们将在一些训练示例中计算损失函数,并使用反向传播更新参数。
- #ngram语言模型
- context_size=2 #上下文大小
- embedding_dim=10 #词向量维度
- test_sentence = """When forty winters shall besiege thy brow,
- And dig deep trenches in thy beauty's field,
- Thy youth's proud livery so gazed on now,
- Will be a totter'd weed of small worth held:
- Then being asked, where all thy beauty lies,
- Where all the treasure of thy lusty days;
- To say, within thine own deep sunken eyes,
- Were an all-eating shame, and thriftless praise.
- How much more praise deserv'd thy beauty's use,
- If thou couldst answer 'This fair child of mine
- Shall sum my count, and make my old excuse,'
- Proving his beauty by succession thine!
- This were to be new made when thou art old,
- And see thy blood warm when thou feel'st it cold.""".split()
- #构建三元组
- trigrams=[([test_sentence[i],test_sentence[i+1]],test_sentence[i+2]) for i in range(len(test_sentence)-2)]
-
- #构建词典
- vocab=set(test_sentence)
- word_to_ix={word :i for i ,word in enumerate(vocab)}
-
- class Ngram(nn.Module):
- def __init__(self,vocab_size,embedding_dim,context_size):
- super(Ngram,self).__init__()
- self.embeddings=nn.Embedding(vocab_size,embedding_dim) #定义embedding
- self.lin1=nn.Linear(context_size*embedding_dim,128) #定义隐含层
- self.lin2=nn.Linear(128,vocab_size) #获取vocab_size个词向量
-
- def forward(self,inputs):
- embeds=self.embeddings(inputs).view(1,-1) #定义词向量 1*(context_size*embedding_dim)
- #print("embeds:",embeds.size())
- out=F.relu(self.lin1(embeds)) #vocab_size*embedding_dim
- out=self.lin2(out) #embedding_dim*128
- prob=F.log_softmax(out,dim=1) #每个词的概率
- return prob
-
- losses=[]
- loss_function=nn.NLLLoss()
- model=Ngram(len(vocab),embedding_dim,context_size)
- opt=optim.SGD(model.parameters(),lr=0.001)
-
- for epoch in range(10):
- total_loss=0
- for ctx,target in trigrams:
- #1、准备输入模型的三元组
- #print("ctx:",ctx)
- ctx_ids=[]
- for w in ctx:
- ctx_ids.append(word_to_ix[w])
-
- ctx_ids = torch.tensor(ctx_ids, dtype=torch.long)
- #2、梯度置0
- model.zero_grad()
- #3、获取log_probs
- log_probs=model(ctx_ids)
- #4、计算损失函数
- loss=loss_function(log_probs,torch.tensor([word_to_ix[target]], dtype=torch.long))
- #5、反向传播更新梯度
- loss.backward()
- opt.step()
- total_loss+=loss.item()
- losses.append(total_loss)
- print(losses)
NLP深度学习中经常使用连续词袋模型(CBOW)。在给定目标词之前和之后的几个词的上下文中,它是一种试图预测词的模型。这与语言建模不同,因为CBOW不是顺序的,并且不一定是概率性的。通常,CBOW用于快速训练单词嵌入,而这些嵌入用于初始化一些更复杂模型的嵌入。通常,这称为预训练嵌入。它几乎总是可以将性能提高百分之几。
CBOW模型如下。给定目标词wi和 N 两侧的上下文窗口 wi−1,…,wi−N和 wi+1,…,wi+N,将所有上下文词统称为 C,CBOW试图最小化
qw是单词的嵌入 w
- #CBOW语言模型
- #构建上下文窗口
- cbows=[]
- context_size=2
- print(ctxs)
- for i in range(context_size,len(ctxs)-context_size):
- ctx=ctxs[i-context_size:i+context_size+1]
- ctx.pop(context_size)
- target=ctxs[i]
- cbows.append((ctx,target))
- print(cbows[:2])
-
- class CBOW(nn.Module):
- def __init__(self,vocab_size,embedding_dim):
- super(CBOW,self).__init__()
- self.embeddings=nn.Embedding(vocab_size,embedding_dim) #定义embedding
- self.lin1=nn.Linear(embedding_dim,128) #定义隐含层
- self.lin2=nn.Linear(128,vocab_size) #获取vocab_size个词向量
-
- def forward(self,inputs):
- embeds=self.embeddings(inputs) #定义词向量 1*(context_size*embedding_dim)
- #print("embeds:",embeds.size())
- embeds=torch.sum(embeds,0).view(1,-1) #0:按照列求和;1:按照行求和
- #print("embeds:",embeds.size())
- out=F.relu(self.lin1(embeds)) #vocab_size*embedding_dim
- out=self.lin2(out) #embedding_dim*128
- prob=F.log_softmax(out,dim=1) #每个词的概率
- return prob
-
- losses=[]
- loss_function=nn.NLLLoss()
- model=CBOW(len(vocab),embedding_dim)
- opt=optim.SGD(model.parameters(),lr=0.001)
-
- for epoch in range(10):
- total_loss=0
- for ctx,target in cbows:
- #1、准备输入模型的三元组
- #print("ctx:",ctx)
- ctx_ids=[]
- for w in ctx:
- ctx_ids.append(word_to_ix[w])
-
- ctx_ids = torch.tensor(ctx_ids, dtype=torch.long)
- #2、梯度置0
- model.zero_grad()
- #3、获取log_probs
- log_probs=model(ctx_ids)
- #4、计算损失函数
- loss=loss_function(log_probs,torch.tensor([word_to_ix[target]], dtype=torch.long))
- #5、反向传播更新梯度
- loss.backward()
- opt.step()
- total_loss+=loss.item()
- losses.append(total_loss)
- print(losses)
参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。