词嵌入进阶

在“Word2Vec的实现”一节中,我们在小规模数据集上训练了一个 Word2Vec 词嵌入模型,并通过词向量的余弦相似度搜索近义词。虽然 Word2Vec 已经能够成功地将离散的单词转换为连续的词向量,并能一定程度上地保存词与词之间的近似关系,但 Word2Vec 模型仍不是完美的,它还可以被进一步地改进:

  1. 子词嵌入(subword embedding):FastText 以固定大小的 n-gram 形式将单词更细致地表示为了子词的集合,而 BPE (byte pair encoding) 算法则能根据语料库的统计信息,自动且动态地生成高频子词的集合;
  2. GloVe 全局向量的词嵌入: 通过等价转换 Word2Vec 模型的条件概率公式,我们可以得到一个全局的损失函数表达,并在此基础上进一步优化模型。

实际中,我们常常在大规模的语料上训练这些词嵌入模型,并将预训练得到的词向量应用到下游的自然语言处理任务中。本节就将以 GloVe 模型为例,演示如何用预训练好的词向量来求近义词和类比词。

GloVe 全局向量的词嵌入

GloVe 模型

先简单回顾以下 Word2Vec 的损失函数(以 Skip-Gram 模型为例,不考虑负采样近似):

$$

-\sum_{t=1}^T\sum_{-m\le j\le m,j\ne 0} \log P(w^{(t+j)}\mid w^{(t)})

$$

其中

$$

P(w_j\mid w_i) = \frac{\exp(\boldsymbol{u}_j\top\boldsymbol{v}_i)}{\sum_{k\in\mathcal{V}}\exp(\boldsymbol{u}_k\top\boldsymbol{v}_i)}

$$

wiw_iwi 为中心词,wjw_jwj 为背景词时 Skip-Gram 模型所假设的条件概率计算公式,我们将其简写为 qijq_{ij}qij

注意到此时我们的损失函数中包含两个求和符号,它们分别枚举了语料库中的每个中心词和其对应的每个背景词。实际上我们还可以采用另一种计数方式,那就是直接枚举每个词分别作为中心词和背景词的情况:

$$

-\sum_{i\in\mathcal{V}}\sum_{j\in\mathcal{V}} x_{ij}\log q_{ij}

$$

其中 xijx_{ij}xij 表示整个数据集中 wjw_jwj 作为 wiw_iwi 的背景词的次数总和。

我们还可以将该式进一步地改写为交叉熵 (cross-entropy) 的形式如下:

$$

-\sum_{i\in\mathcal{V}}x_i\sum_{j\in\mathcal{V}}p_{ij} \log q_{ij}

$$

其中 xix_ixiwiw_iwi 的背景词窗大小总和,pij=xij/xip_{ij}=x_{ij}/x_ipij=xij/xiwjw_jwjwiw_iwi 的背景词窗中所占的比例。

从这里可以看出,我们的词嵌入方法实际上就是想让模型学出 wjw_jwj 有多大概率是 wiw_iwi 的背景词,而真实的标签则是语料库上的统计数据。同时,语料库中的每个词根据 xix_ixi 的不同,在损失函数中所占的比重也不同。

注意到目前为止,我们只是改写了 Skip-Gram 模型损失函数的表面形式,还没有对模型做任何实质上的改动。而在 Word2Vec 之后提出的 GloVe 模型,则是在之前的基础上做出了以下几点改动:

  1. 使用非概率分布的变量 pij′=xijp'_{ij}=x_{ij}pij=xijq′ij=exp⁡(uj⊤vi)q′_{ij}=\exp(\boldsymbol{u}^\top_j\boldsymbol{v}_i)qij=exp(ujvi),并对它们取对数;
  2. 为每个词 wiw_iwi 增加两个标量模型参数:中心词偏差项 bib_ibi 和背景词偏差项 cic_ici,松弛了概率定义中的规范性;
  3. 将每个损失项的权重 xix_ixi 替换成函数 h(xij)h(x_{ij})h(xij),权重函数 h(x)h(x)h(x) 是值域在 [0,1][0,1][0,1] 上的单调递增函数,松弛了中心词重要性与 xix_ixi 线性相关的隐含假设;
  4. 用平方损失函数替代了交叉熵损失函数。

综上,我们获得了 GloVe 模型的损失函数表达式:

$$

\sum_{i\in\mathcal{V}}\sum_{j\in\mathcal{V}} h(x_{ij}) (\boldsymbol{u}^\top_j\boldsymbol{v}i+b_i+c_j-\log x{ij})^2

$$

由于这些非零 xijx_{ij}xij 是预先基于整个数据集计算得到的,包含了数据集的全局统计信息,因此 GloVe 模型的命名取“全局向量”(Global Vectors)之意。

载入预训练的 GloVe 向量

GloVe 官方 提供了多种规格的预训练词向量,语料库分别采用了维基百科、CommonCrawl和推特等,语料库中词语总数也涵盖了从60亿到8,400亿的不同规模,同时还提供了多种词向量维度供下游模型使用。

torchtext.vocab 中已经支持了 GloVe, FastText, CharNGram 等常用的预训练词向量,我们可以通过声明 torchtext.vocab.GloVe 类的实例来加载预训练好的 GloVe 词向量。

import torch
import torchtext.vocab as vocabprint([key for key in vocab.pretrained_aliases.keys() if "glove" in key])
cache_dir = "/home/kesci/input/GloVe6B5429"
glove = vocab.GloVe(name='6B', dim=50, cache=cache_dir)
print("一共包含%d个词。" % len(glove.stoi))
print(glove.stoi['beautiful'], glove.itos[3366])

求近义词和类比词

求近义词

由于词向量空间中的余弦相似性可以衡量词语含义的相似性(为什么?),我们可以通过寻找空间中的 k 近邻,来查询单词的近义词。

def knn(W, x, k):'''@params:W: 所有向量的集合x: 给定向量k: 查询的数量@outputs:topk: 余弦相似性最大k个的下标[...]: 余弦相似度'''cos = torch.matmul(W, x.view((-1,))) / ((torch.sum(W * W, dim=1) + 1e-9).sqrt() * torch.sum(x * x).sqrt())_, topk = torch.topk(cos, k=k)topk = topk.cpu().numpy()return topk, [cos[i].item() for i in topk]def get_similar_tokens(query_token, k, embed):'''@params:query_token: 给定的单词k: 所需近义词的个数embed: 预训练词向量'''topk, cos = knn(embed.vectors,embed.vectors[embed.stoi[query_token]], k+1)for i, c in zip(topk[1:], cos[1:]):  # 除去输入词print('cosine sim=%.3f: %s' % (c, (embed.itos[i])))get_similar_tokens('chip', 3, glove)
get_similar_tokens('baby', 3, glove)
get_similar_tokens('beautiful', 3, glove)

求类比词

除了求近义词以外,我们还可以使用预训练词向量求词与词之间的类比关系,例如“man”之于“woman”相当于“son”之于“daughter”。求类比词问题可以定义为:对于类比关系中的4个词“aaa 之于 bbb 相当于 ccc 之于 ddd”,给定前3个词 a,b,ca,b,ca,b,cddd。求类比词的思路是,搜索与 vec(c)+vec(b)−vec(a)\text{vec}(c)+\text{vec}(b)−\text{vec}(a)vec(c)+vec(b)vec(a) 的结果向量最相似的词向量,其中 vec(w)\text{vec}(w)vec(w)www 的词向量。

def get_analogy(token_a, token_b, token_c, embed):'''@params:token_a: 词atoken_b: 词btoken_c: 词cembed: 预训练词向量@outputs:res: 类比词d'''vecs = [embed.vectors[embed.stoi[t]] for t in [token_a, token_b, token_c]]x = vecs[1] - vecs[0] + vecs[2]topk, cos = knn(embed.vectors, x, 1)res = embed.itos[topk[0]]return resget_analogy('man', 'woman', 'son', glove)
get_analogy('beijing', 'china', 'tokyo', glove)
get_analogy('bad', 'worst', 'big', glove)
get_analogy('do', 'did', 'go', glove)

《动手学深度学习》组队学习打卡Task7——词嵌入进阶相关推荐

  1. 动手学深度学习打卡之二。

    第二次打卡内容(2月15日-18日) Task03:过拟合.欠拟合及其解决方案:梯度消失.梯度爆炸:循环神经网络进阶(1天) Task04:机器翻译及相关技术:注意力机制与Seq2seq模型:Tran ...

  2. 资源 | 李沐等人开源中文书《动手学深度学习》预览版上线

    来源:机器之心 本文约2000字,建议阅读10分钟. 本文为大家介绍了一本交互式深度学习书籍. 近日,由 Aston Zhang.李沐等人所著图书<动手学深度学习>放出了在线预览版,以供读 ...

  3. 动手学深度学习需要这些数学基础知识

    https://www.toutiao.com/a6716993354439066124/ 本附录总结了本书中涉及的有关线性代数.微分和概率的基础知识.为避免赘述本书未涉及的数学背景知识,本节中的少数 ...

  4. 《动手学深度学习》PyTorch版GitHub资源

    之前,偶然间看到过这个PyTorch版<动手学深度学习>,当时留意了一下,后来,着手学习pytorch,发现找不到这个资源了.今天又看到了,赶紧保存下来. <动手学深度学习>P ...

  5. 【深度学习】李沐《动手学深度学习》的PyTorch实现已完成

    这个项目是中文版<动手学深度学习>中的代码进行整理,用Pytorch实现,是目前全网最全的Pytorch版本. 项目作者:吴振宇博士 简介   Dive-Into-Deep-Learnin ...

  6. 送10本今年最火的《动手学深度学习》

    点击我爱计算机视觉标星,更快获取CVML新技术 52CV曾经多次介绍FlyAI机器学习竞赛平台,不少粉丝也曾在FlyAI拿到现金奖励. 本次52CV & FlyAI联合送书,CV君查找了两天, ...

  7. 《动手学深度学习》TF2.0 实现

    本项目将<动手学深度学习> 原书中MXNet代码实现改为TensorFlow2.0实现.经过我的导师咨询李沐老师,这个项目的实施已得到李沐老师的同意.原书作者:阿斯顿·张.李沐.扎卡里 C ...

  8. 364 页 PyTorch 版《动手学深度学习》分享(全中文,支持 Jupyter 运行)

    1 前言 最近有朋友留言要求分享一下李沐老师的<动手学深度学习>,小汤本着一直坚持的"好资源大家一起分享,共同学习,共同进步"的初衷,于是便去找了资料,而且还是中文版的 ...

  9. 【动手学深度学习】(task123)注意力机制剖析

    note 将注意力汇聚的输出计算可以作为值的加权平均,选择不同的注意力评分函数会带来不同的注意力汇聚操作. 当查询和键是不同长度的矢量时,可以使用可加性注意力评分函数.当它们的长度相同时,使用缩放的& ...

最新文章

  1. vue中props的双向绑定
  2. 面试那点小事,你从未见过的spring boot面试集锦(附详细答案)
  3. 关于子网划分—为什么全0全1子网号不能使用
  4. PS效果教程——冒充手绘效果
  5. spring和activemq的结合(五)
  6. arcgis api for javascript创建webmap
  7. mongodb聚合查询优化_【MongoDB】MongoDB 性能优化 - BI查询聚合
  8. Struts2笔记——15.Spring的事务
  9. OpenCv之Canny边界检测(笔记13)
  10. 一次sendmsg的改造过程
  11. python深度学习库tensorflow——实现FC卷积神经网络识别mnist手写体
  12. iOS底层探索之类的结构(中):bits
  13. php影院影城源码,99影院源码 影视网站程序源码/附教程
  14. oracle修改dbf文件,如何修改Oracle的dbf文件位置
  15. typecho添加html5视频播放器,DPlayer-Typecho视频播放插件
  16. UTC相关的时区转换
  17. Corg.quartz.JobPersistenceException: Couldn‘t retrieve trigger
  18. linux 内存block读取6,Linux硬盘 和文件系统维护
  19. SQL server 将不等于hit的全部删除
  20. excel下拉表格复制公式不自动递增

热门文章

  1. python:字典生成式
  2. 张家俊:关于ChatGPT八个技术问题的猜想
  3. latex公式括号内换行
  4. python制作查询软件_python 制作本地应用搜索工具
  5. sklearn 逻辑回归中的参数的详解'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'
  6. 空间域图像增强:卷积和空间域滤波
  7. 微信小程序实现会议邀请函海报、表格布局等
  8. 虹软人脸识别 SDK 使用 Unity Android C# Java多语言开发 2021-09-06
  9. 飞鸽传书(Ipmessage)软件的实现原理
  10. 如何快速落地数据分析平台 大数据在他趣的应用实践