Pytorch transformers tokenizer 分词器词汇表添加新的词语和embedding

这篇具有很好参考价值的文章主要介绍了Pytorch transformers tokenizer 分词器词汇表添加新的词语和embedding。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目标:

在NLP领域,基于公开语料的预训练模型,在专业领域迁移时,会遇到专业领域词汇不在词汇表的问题,本文介绍如何添加专有名词到预训练模型。

例如,在bert预训练模型中,并不包含财经词汇,比如‘市盈率’等财务指标词汇,本文将介绍:

  • 如何把专业名词添加到词汇表中
  • 方法1:修改 vocab
  • 方法2:更通用,修改分词器tokenizer
  • 如何保留现有模型能力,并训练新词汇的embedding表示

内容:

NLP的分词

NLP的处理流程:

  1. 对输入的句子进行分词,得到词语及下标
  2. 通过embedding层获得词语对应的embedding
  3. embedding送入到预训练模型,经过attention注意力机制,获得token在句子中的语义embedding向量
  4. 利用语义embedding向量,构建下游任务。

其中,预训练模型是在公开语料上训练的,我们在做迁移学习,把模型迁移到财经领域时,会面临的一个问题,就是财经词汇不在词汇表,会被拆分成单个字,从而会导致专业名词的完整意思的破坏,或者让模型去学习时,不那么直观,比如:

  • ‘华为的市盈率较高’ 默认会被拆分为:[', ‘’, ‘华为’, ‘的’, ‘市’, ‘盈’, ‘率’, ‘较高’, ‘’]
  • 可见,市盈率被拆分成了 ‘市’, ‘盈’, ‘率’。
  • 我们可以让显式的告诉分词器,市盈率是一个专业名词,无需拆分。因此,经过处理后,词汇被分成了[‘’, ‘’, ‘华为’, ‘的’, ‘市盈率’, ‘’, ‘较高’, ‘’]
  • 达到了预期目标
from transformers import AutoTokenizer,AutoModel

PRE_TRAINED_MODEL_NAME='xlm-roberta-base'
tokenizer = AutoTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME)

e = tokenizer.encode('华为的市盈率较高')
s = [tokenizer.decode(i) for i in e]
print(s)
# ['<s>', '', '华为', '的', '市', '盈', '率', '较高', '</s>']
tokenizer.add_tokens(["市盈率"])
e2 = tokenizer.encode('华为的市盈率较高')
s2 = [tokenizer.decode(i) for i in e2]
print(s2)
# ['<s>', '', '华为', '的', '市盈率', '', '较高', '</s>']

实现方式:

有两种实现

    1. 在vocab.txt中,利用前100里的[unused],将[unused]换成自己想要添加的。具体有多少个[unused]要看自己的预训练模型,可能100个,可能1000个,但都有限。如果要添加的词汇量小,并且预训练模型确实有vocab.txt文件,则可以,比如bert,目前看对于领域来说,量不够大。
    1. 更加通用的办法:通过tokenizer,向词汇表中追加新的专业词汇,没有不限。特别是现在比较复杂的模型,都没有单独的vocab.txt文件了,只能通过这种方式。
import torch
from transformers import AutoTokenizer,AutoModel

PRE_TRAINED_MODEL_NAME='xlm-roberta-base'
tokenizer = AutoTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME)
model = AutoModel.from_pretrained(PRE_TRAINED_MODEL_NAME)

print(len(tokenizer))  # 250002
tokenizer.add_tokens(["NEW_TOKEN"])
print(len(tokenizer))  # 250003

新词汇embedding的生成:

新词汇的加入,势必会不适配原始embedding的维度,原始的embedding维度为[vocab_size,hidden_size],但是我们又不可能重新去训练整个embedding,我们想尽量保留原始embedding参数,因此,这里比较巧妙的运用了reshape技巧,人为添加新词汇的embedding(随机的,没学习),然后使用领域材料进行学习。
这种方法,因为是添加token,需要修改embedding matrix。
实验证明resize matrix不会打扰原始预训练的embeddings。

import torch
from transformers import AutoTokenizer,AutoModel

PRE_TRAINED_MODEL_NAME='xlm-roberta-base'
tokenizer = AutoTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME)
model = AutoModel.from_pretrained(PRE_TRAINED_MODEL_NAME)

print(len(tokenizer))  # 250002
tokenizer.add_tokens(["NEW_TOKEN"])
print(len(tokenizer))  # 250003

x = model.embeddings.word_embeddings.weight[-1, :] # 原始最后一个token的embedding

model.resize_token_embeddings(len(tokenizer)) # 调整embedding维度
# The new vector is added at the end of the embedding matrix

print(model.embeddings.word_embeddings.weight[-1, :])
# Randomly generated matrix 添加的embedding是随机值。

with torch.no_grad():
    model.embeddings.word_embeddings.weight[-1, :] = torch.zeros([model.config.hidden_size])
# 人为设置新添加的embedding为0

print(model.embeddings.word_embeddings.weight[-1, :])
# outputs a vector of zeros of shape [768]

y = model.embeddings.word_embeddings.weight[-2, :] # 原始最后一个token变成倒数第二了,取其embedding

print(x == y) # 原始token的embedding会改变吗?原来embedding weight 不会变

e = tokenizer.encode('华为的市盈率较高')
s = [tokenizer.decode(i) for i in e]
print(s)
tokenizer.add_tokens(["市盈率"])
e2 = tokenizer.encode('华为的市盈率较高')
s2 = [tokenizer.decode(i) for i in e2]
print(s2)

有了这个初始embedding,经过MLM等任务,就可以训练新词汇的embedding表示了,通过下游任务来学习这个embedding。文章来源地址https://www.toymoban.com/news/detail-536085.html

掌握:

  • 添加领域词汇的方式
  • 修改新embedding的方式
  • 训练新token的embedding

到了这里,关于Pytorch transformers tokenizer 分词器词汇表添加新的词语和embedding的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (教程)如何在BERT模型中添加自己的词汇(pytorch版)

    来源:投稿 作者:皮皮雷 编辑:学姐 参考文章: NLP | How to add a domain-specific vocabulary (new tokens) to a subword tokenizer already trained like BERT WordPiece | by Pierre Guillou | Medium https://medium.com/@pierre_guillou/nlp-how-to-add-a-domain-specific-vocabulary-new-tokens-to-a-subword-tokenizer-already-trained-33ab15613a41 中文

    2024年02月13日
    浏览(38)
  • Elasticsearch对数字,英文字母等的分词N-gram tokenizer

    Elasticsearch中提供了一个叫N-gram tokenizer的分词器,官方介绍如下 The  ngram  tokenizer first breaks text down into words whenever it encounters one of a list of specified characters, then it emits N-grams of each word of the specified length. N-grams are like a sliding window that moves across the word - a continuous sequence of charac

    2023年04月16日
    浏览(38)
  • es自定义分词器支持数字字母分词,中文分词器jieba支持添加禁用词和扩展词典

    自定义分析器,分词器 所有字段检索 高亮搜索 分词测试 GET /test_index/_analyze jieba中文分词支持添加禁用词和扩展词库功能 创建索引:PUT http://xxxx:9200/test_index 分词测试: GET http://xxxxxx:9200/test_index/_analyze

    2024年02月11日
    浏览(44)
  • 用于弱监督语义分割的多类token transformer

    本文提出了一种新的基于Transformer的框架,将特定于类的对象定位映射学习为弱监督语义分割(WSSS)的伪标签。 标准视觉Transformer中一个类Token 的参与区域可以被利用来形成一个类不确定的定位映射 本文研究了Transformer模型是否也可以通过学习Transformer中的多个类Token 来有效地捕

    2023年04月09日
    浏览(51)
  • ViT: Vision transformer的cls token作用?

    知乎:Vision Transformer 超详细解读 (原理分析+代码解读)  CSDN:vit 中的 cls_token 与 position_embed 理解 CSDN:ViT为何引入cls_token CSDN:ViT中特殊class token的一些问题 Vision Transformer在一些任务上超越了CNN,得益于全局信息的聚合。在ViT论文中,作者引入了一个class token作为分类特征。

    2024年02月01日
    浏览(44)
  • Elasticsearch添加7.17.10IK分词器

    在https://github.com/medcl/elasticsearch-analysis-ik/tree/7.x中未找到7.17.10版本的发布版本,如歌ik版本和Elasticsearch版本不同安装后无法启动。所以下载git上的源代码,并手动编译指定版本IK分词器。 (1)下载elasticsearch-analysis-ik-7.x源码的zip压缩包,并解压 (2)打开解压后文件夹里的p

    2024年01月18日
    浏览(46)
  • 【AI学习】Transformer的Token嵌入表示为什么那么长

    有朋友问,BERT等大模型的参数量怎么计算的?这个问题,李沐在BERT那篇论文中讲过,主要包括几部分。1、词嵌入:token数量乘以token表示的向量长度,就是 V H;2、注意力计算没有参数,只计算多头注意力的投影矩阵,三个输入的权重矩阵,每个矩阵参数= H (H/头数) 头数

    2024年04月25日
    浏览(46)
  • vue 前端登录获取token后添加到cookie,并使用token获取其他数据(添加到请求头中)

    1.登录获取到token存到cookie中   这里我的cookie设置为一天失效 cookie.js代码如下 main.js导入到全局使用 request.js请求头添加token   最后浏览器可查看到   并且下一次发请求时候请求参数中可查看到

    2024年02月15日
    浏览(43)
  • postman如何添加token

    参考博客:https://blog.csdn.net/Mrbignose/article/details/107237581 1.添加token: 2.设置token: 3.发送时携带token:

    2024年02月13日
    浏览(40)
  • postman登录获取token,接口header中添加token发送请求

    该文章只是用于记录,防止自己忘记。 1、准备登录接口 2、添加全局变量 3、添加一个登录接口,登录获取token,将获取到的token设置到全局变量中 4、密码加密 var password = pm.environment.get(“password”);//获取环境变量password的值 var md5Password= CryptoJS.MD5(password).toString();//使用MD5()方

    2024年02月10日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包