PyTorch在NLP任务中使用预训练词向量
在使用pytorch或tensorflow等神经网络框架进行nlp任务的处理时,可以通过对应的Embedding层做词向量的处理,更多的时候,使用预训练好的词向量会带来更优的性能。下面分别介绍使用gensim和torchtext两种加载预训练词向量的方法。
1.使用gensim加载预训练词向量
对于如下这样一段语料
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()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
构建词表,此过程也可使用Keras或torchtext来简化完成,完整代码见文末仓库。
# 给每个单词编码,也就是用数字来表示每个单词,这样才能够传入word embeding得到词向量。
vocab = set(test_sentence) # 通过set将重复的单词去掉
word_to_idx = {word: i+1 for i, word in enumerate(vocab)}
# 定义了一个unknown的词,也就是说没有出现在训练集里的词,我们都叫做unknown,词向量就定义为0。
word_to_idx['<unk>'] = 0
idx_to_word = {i+1: word for i, word in enumerate(vocab)}
idx_to_word[0] = '<unk>'
1
2
3
4
5
6
7
使用gensim加载已训练好的word2vec词向量,此处用的是glove已训练好的词向量,下载链接:https://pan.baidu.com/s/1i5XmTA9 因为glove词向量和word2vec词向量格式略有不同,先使用gensim的scripts.glove2word2vec方法将glove词向量转化为word2vec词向量的格式。转化方式很简单,如下:
from gensim.test.utils import datapath, get_tmpfile
from gensim.models import KeyedVectors
# 已有的glove词向量
glove_file = datapath('test_glove.txt')
# 指定转化为word2vec格式后文件的位置
tmp_file = get_tmpfile("test_word2vec.txt")
from gensim.scripts.glove2word2vec import glove2word2vec
glove2word2vec(glove_file, tmp_file)
1
2
3
4
5
6
7
8
去词向量文件中查表,得到词表中单词对应的权重weight。在词向量文件中没匹配到的单词则继续保留全0向量。
# 使用gensim载入word2vec词向量
wvmodel = gensim.models.KeyedVectors.load_word2vec_format('/Users/wyw/Documents/vectors/word2vec/word2vec.6B.100d.txt', binary=False, encoding='utf-8')
vocab_size = len(vocab) + 1
embed_size = 100
weight = torch.zeros(vocab_size, embed_size)
for i in range(len(wvmodel.index2word)):
try:
index = word_to_idx[wvmodel.index2word[i]]
except:
continue
weight[index, :] = torch.from_numpy(wvmodel.get_vector(
idx_to_word[word_to_idx[wvmodel.index2word[i]]]))
1
2
3
4
5
6
7
8
9
10
11
12
13
得到weight权重后,即可在PyTorch的Embedding层中就可以指定预训练的词向量。
embedding = nn.Embedding.from_pretrained(weight)
# requires_grad指定是否在训练过程中对词向量的权重进行微调
self.embedding.weight.requires_grad = True
1
2
3
完整代码见我的github仓库:https://github.com/atnlp/torchtext-summary 下的Language-Model.ipynb文件
2.使用torchtext加载预训练的词向量
下面介绍如何在torchtext中使用预训练的词向量,进而传送给神经网络模型进行训练。关于torchtext更完整的用法见我另一篇博客:TorchText用法示例及完整代码
使用torchtext默认支持的预训练词向量
默认情况下,会自动下载对应的预训练词向量文件到当前文件夹下的.vector_cache目录下,.vector_cache为默认的词向量文件和缓存文件的目录。
from torchtext.vocab import GloVe
from torchtext import data
TEXT = data.Field(sequential=True)
# 以下两种指定预训练词向量的方式等效
# TEXT.build_vocab(train, vectors="glove.6B.200d")
TEXT.build_vocab(train, vectors=GloVe(name='6B', dim=300))
# 在这种情况下,会默认下载glove.6B.zip文件,进而解压出glove.6B.50d.txt, glove.6B.100d.txt, glove.6B.200d.txt, glove.6B.300d.txt这四个文件,因此我们可以事先将glove.6B.zip或glove.6B.200d.txt放在.vector_cache文件夹下(若不存在,则手动创建)。
1
2
3
4
5
6
7
指定预训练词向量和缓存文件所在目录
上述使用预训练词向量文件的方式存在一大问题,即我们每做一个nlp任务时,建立词表时都需要在对应的.vector_cache文件夹中下载预训练词向量文件,如何解决这一问题?我们可以使用torchtext.vocab.Vectors中的name和cachae参数指定预训练的词向量文件和缓存文件的所在目录。因此我们也可以使用自己用word2vec等工具训练出的词向量文件,只需将词向量文件放在name指定的目录中即可。
通过name参数可以指定预训练的词向量文件所在的目录
默认情况下预训练词向量文件和缓存文件的目录位置都为当前目录下的 .vector_cache目录,虽然通过name参数指定了预训练词向量文件存在的目录,但是因为缓存文件的目录没有特殊指定,此时在当前目录下仍然需要存在 .vector_cache 目录。
# glove.6B.200d.txt为预先下载好的预训练词向量文件
if not os.path.exists(.vector_cache):
os.mkdir(.vector_cache)
vectors = Vectors(name='myvector/glove/glove.6B.200d.txt')
TEXT.build_vocab(train, vectors=vectors)
1
2
3
4
5
通过cache参数指定缓存目录
# 更进一步的,可以在指定name的同时同时指定缓存文件所在目录,而不是使用默认的.vector_cache目录
cache = '.vector_cache'
if not os.path.exists(cache):
os.mkdir(cache)
vectors = Vectors(name='myvector/glove/glove.6B.200d.txt', cache=cache)
TEXT.build_vocab(train, vectors=vectors)
1
2
3
4
5
6
在模型中指定Embedding层的权重
在使用预训练好的词向量时,我们需要在神经网络模型的Embedding层中明确地传递嵌入矩阵的初始权重。权重包含在词汇表的vectors属性中。以Pytorch搭建的Embedding层为例:
# 通过pytorch创建的Embedding层
embedding = nn.Embedding(2000, 256)
# 指定嵌入矩阵的初始权重
weight_matrix = TEXT.vocab.vectors
embedding.weight.data.copy_(weight_matrix )
1
2
3
4
5
一个比较完整的示例
import torch
from torchtext import data
from torchtext import datasets
from torchtext.vocab import GloVe
import numpy as np
def load_data(opt):
# use torchtext to load data, no need to download dataset
print("loading {} dataset".format(opt.dataset))
# set up fields
text = data.Field(lower=True, include_lengths=True, batch_first=True, fix_length=opt.max_seq_len)
label = data.Field(sequential=False)
# make splits for data
train, test = datasets.IMDB.splits(text, label)
# build the vocabulary
text.build_vocab(train, vectors=GloVe(name='6B', dim=300))
label.build_vocab(train)
# print vocab information
print('len(TEXT.vocab)', len(text.vocab))
print('TEXT.vocab.vectors.size()', text.vocab.vectors.size())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
完整代码见我的GitHub仓库:https://github.com/atnlp/torchtext-summary
关于torchtext的其他用法见我的博客:http://www.nlpuser.com/pytorch/2018/10/30/useTorchText/
个人原创,未经允许不得转载。
---------------------
作者:nlpuser
来源:CSDN
原文:https://blog.csdn.net/nlpuser/article/details/83627709
版权声明:本文为博主原创文章,转载请附上博文链接!
PyTorch在NLP任务中使用预训练词向量的更多相关文章
- pytorch中如何使用预训练词向量
不涉及具体代码,只是记录一下自己的疑惑. 我们知道对于在pytorch中,我们通过构建一个词向量矩阵对象.这个时候对象矩阵是随机初始化的,然后我们的输入是单词的数值表达,也就是一些索引.那么我们会根据 ...
- 文本分类实战(一)—— word2vec预训练词向量
1 大纲概述 文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类.总共有以下系列: word2vec预训练词向量 te ...
- tensorflow如何正确加载预训练词向量
使用预训练词向量和随机初始化词向量的差异还是挺大的,现在说一说我使用预训练词向量的流程. 一.构建本语料的词汇表,作为我的基础词汇 二.遍历该词汇表,从预训练词向量中提取出该词对应的词向量 三.初始化 ...
- word2vec预训练词向量
NLP中的Word2Vec讲解 word2vec是Google开源的一款用于词向量计算 的工具,可以很好的度量词与词之间的相似性: word2vec建模是指用CBoW模型或Skip-gram模型来计算 ...
- DNN模型训练词向量原理
转自:https://blog.csdn.net/fendouaini/article/details/79821852 1 词向量 在NLP里,最细的粒度是词语,由词语再组成句子,段落,文章.所以处 ...
- 词表征 3:GloVe、fastText、评价词向量、重新训练词向量
原文地址:https://www.jianshu.com/p/ca2272addeb0 (四)GloVe GloVe本质是加权最小二乘回归模型,引入了共现概率矩阵. 1.基本思想 GloVe模型的目标 ...
- 文本分布式表示(二):用tensorflow和word2vec训练词向量
看了几天word2vec的理论,终于是懂了一些.理论部分我推荐以下几篇教程,有博客也有视频: 1.<word2vec中的数学原理>:http://www.cnblogs.com/pegho ...
- 基于word2vec训练词向量(二)
转自:http://www.tensorflownews.com/2018/04/19/word2vec2/ 一.基于Hierarchical Softmax的word2vec模型的缺点 上篇说了Hi ...
- 基于word2vec训练词向量(一)
转自:https://blog.csdn.net/fendouaini/article/details/79905328 1.回顾DNN训练词向量 上次说到了通过DNN模型训练词获得词向量,这次来讲解 ...
随机推荐
- ubuntu上安装与卸载deb文件(转载)
转自:http://blog.csdn.net/nkguohao/article/details/8951082 版权声明:本文为博主原创文章,未经博主允许不得转载. 通过deb包安装软件: sudo ...
- POJ1182【种类并查集】
思路: ---来源百度 0表示它与根结点为同类, 1表示它吃根结点, 2表示它被根结点吃. 判断两个点a, b的关系,我们令p = Find(a), q = Find(b),即p, q分别为a, b子 ...
- 慕课笔记-Java入门第三季
1.自定义异常 自定义异常必须继承Exception类或者其子类. 2.字符串 String对象创建后则不能被修改,是不可变的,所谓的修改其实是创建了新的对象. 多次创建的字符常量,Java编译程序只 ...
- [題解]BZOJ_1260_塗色
簡單的區間dp,結果竟然寫掛了......還掛的很徹底......狗屎 如果區間左右端點相等,那麼不需要在多花一次去刷,對 f [ i+1 ] [ j ],f [ i ] [ j-1 ]取個min, ...
- C# 基础之索引器
当一个类有数组成员时,索引器将大大简化对类中数组成员的访问 索引器类似于属性有get与set访问器 列如: 使用: 总结:从以上代码可以看出索引器也是对私有字段进行访问的方式,但此时的私有字段是数组类 ...
- [软件工程基础]PhyLab 需求与功能分析改进文档
NABCD 模型 Need 需求 根据 Default 的需求文档,物理实验网站对于北航大二学生完成物理实验有较大的帮助,反馈较好.由于在 2016-2017 春季学期,网站数据库因为不明原因被删除了 ...
- Linux —— 压缩命令
压缩与解压命令 .zip格式 压缩文件: zip 压缩文件名 原文件名 (压缩目录添加 -r) 解压缩文件/目录: unzip .zip压缩包 .gz格式 压缩文件: gzip 原文件名称 压缩文件为 ...
- Php对象及对象特性篇
前言 以前写C++最多,大二课上学过Java.现在也差不多还给老师了.现在决定针对php重新梳理一遍,夯实基础,设计模式学起来应该会更加得心应手吧. 介绍 对象作为数据和功能代码的集合,是程序开发和代 ...
- 【aspnetcore】模拟中间件处理请求的管道
几个核心对象: ApplicationBuilder 就是startup->Configure方法的第一个参数,请求(HttpContext) 就是由这个类来处理的 HttpContext 这个 ...
- centos6.7版本下配置ssh密钥登录
需要提前说明的是我使用的系统是centos6.7的版本. 1.我使用的是Putty登录 #ssh-keygen (生成公钥和私钥的命令) 回车之后会提示密钥要存放的目录,默认的目录是当前目录下的.ss ...