首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用预先训练过的单词嵌入-如何为未知/ OOV令牌创建向量?

使用预先训练过的单词嵌入-如何为未知/ OOV令牌创建向量?
EN

Stack Overflow用户
提问于 2018-11-15 09:26:29
回答 1查看 3K关注 0票数 4

我不想把预训练嵌入添加到模型中。但是,似乎没有词汇外(OOV)标记的重新定义。不存在看不见的文字的矢量。

那么我该怎么处理我遇到的OOV-令牌呢?我有一些想法,但似乎没有一个很好:

  • 我可以为这个令牌创建一个随机向量,但理想情况下,我希望该向量在现有模型的逻辑范围内。如果我只是随机地创建它,恐怕这个向量可能会非常类似于一个非常频繁的词,比如' the ','for','that‘等等,这不是我的意思。
  • 还是应该用普通的零来初始化向量呢?
  • 另一个想法是将令牌平均于其他现有向量。但是平均在什么向量上呢?所有的?这似乎也不是很有说服力。
  • 我还想试着训练这个向量。但是,如果我想在训练期间冻结其馀的嵌入,这就不太方便了。

(一个通用的解决方案是值得赞赏的,但我想补充一下,我正在使用PyTorch --以防PyTorch已经为这个问题提供了一个方便的解决方案。)

,那么,创建这样一个向量的好的 easy 策略是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-16 00:44:48

有多种方法可以处理它。我想我不能引用关于哪个更好的参考资料。

不可训练选项

  1. 随机向量作为嵌入
  2. 对于OOV,你可以使用全零矢量。
  3. 您可以使用所有嵌入向量的平均值,这样可以避免脱离实际分布的风险。
  4. 此外,嵌入通常伴随着在培训期间学到的“灌篮”向量,您可以使用它。

可训练选项

您可以为OOV声明一个单独的嵌入向量,并使其可训练,使其他嵌入保持固定。您可能必须重写嵌入查找的前向方法。您可以声明一个新的可训练的Variable,在前面的传递中,使用这个向量作为OOV的嵌入,而不是进行查找。

关于执行部分的评论:

我不知道三种不可训练的方法中哪一种可能更好,我也不确定是否有一些工作要做。但是方法4)应该工作得更好。

对于可训练选项,您可以创建一个新的嵌入层如下所示。

代码语言:javascript
复制
class Embeddings_new(torch.nn.Module): 
    def __init__(self, dim, vocab): 
        super().__init__() 
        self.embedding = torch.nn.Embedding(vocab, dim) 
        self.embedding.weight.requires_grad = False
        # vector for oov 
        self.oov = torch.nn.Parameter(data=torch.rand(1,dim)) 
        self.oov_index = -1 
        self.dim = dim 

    def forward(self, arr): 
        N = arr.shape[0] 
        mask =  (arr==self.oov_index).long() 
        mask_ = mask.unsqueeze(dim=1).float() 
        embed =(1-mask_)*self.embedding((1-mask)*arr) + mask_*(self.oov.expand((N,self.dim))) 
        return embed 

用法:

代码语言:javascript
复制
model = Embeddings_new(10,20000)    
out = model.forward(torch.tensor([-1,-1, 100, 1, 0]))
# dummy loss
loss = torch.sum(a**2)
loss.backward()
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53316174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档