【Pytorch神经网络理论篇】 40 Transformers中的词表工具Tokenizer

 

同学你好!本文章于2021年末编写,获得广泛的好评!

故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现,

Pytorch深度学习·理论篇(2023版)目录地址为:

CSDN独家 | 全网首发 | Pytorch深度学习·理论篇(2023版)目录本专栏将通过系统的深度学习实例,从可解释性的角度对深度学习的原理进行讲解与分析,通过将深度学习知识与Pytorch的高效结合,帮助各位新入门的读者理解深度学习各个模板之间的关系,这些均是在Pytorch上实现的,可以有效的结合当前各位研究生的研究方向,设计人工智能的各个领域,是经过一年时间打磨的精品专栏!https://v9999.blog.csdn.net/article/details/127587345欢迎大家订阅(2023版)理论篇

以下为2021版原文~~~~

1 Tokenizer

在Transformers库中,提供了一个通用的词表工具Tokenizer,该工具是用Rust编写的,其可以实现NLP任务中数据预处理环节的相关任务。

1.1 Tokenizer工具中的组件

在词表工具Tokenizer中,主要通过PreTrainedTokenizer类实现对外接口的使用。

1.1.1 Normaizer

对输入字符串进行规范化转换,如对文本进行小写转换、使用uni-code规范化。

1.1.2 PreTokenizer

对输入数据进行预处理,如基于字节空格、字符等级别对文本进'Madel:生成和使用子词的横型,如Wordlevel、BPE、WordPlece等模型。这部分是可训练的。

1.1.3 Post-Processor

对分词后的文本进行二次处理。例如,在BERT模型中,使用ssor为输入文本添加特殊字符(如[CLS]、[SEP]等)。

1.1.4 Dcoder

负责将标记化输入映射回原始字符串。

1.1.5 Trainer

为每个模型提供培训能力。

1.2 子词的拆分

词表工具将liyongle分成了[lI',yong','#le],使用子词的拆分技术可以防止NLP任务中,在覆盖大量词汇的同时,词表过大的问题。

1.2.1 子词的拆分原理

在进行NLP时,通过为每个不同词对应一个不同的向量,来完成文字到数值之间的转换,这个映射表被称作词表。

1.2.2 字词拆分优势

对于某些形态学丰富的语言(如德语,或是带有时态动词的英语),如果将每个变化的词都对应一个数值,则会导致词表过大的问题。而且这种方式使得两个词之间彼此独立,也不能体现出其本身的相近意思(如pad和padding)。

子词就是将一般的词,如padding分解成更小单元pad+ding。而这些小单元也有各自意思,同时这些小单元也能用到其他词中。子词与单词中的词根、词缀非常相似。通过将间分解成子词,可以大大降低模型的词汇量,减少运算量。

1.2.3 于统计方法实现的子词的分词方法

Byte Pair Encoding(BPE)法:统计频次,即先对语料统计出相邻符号对的频次,再根据频词进行融合。

WordPiece法:WordPiece法统计最大似然,是Google公司内部的子词包,其未对外公开。BERT最初用的就是WordPiece法分词。

Unigram Language Model法:先初始化一个大词表,接着通过语言模型评估不断减少词表,一直减少到限定词汇量。

1.2.4 使用模型训练的方法对子词进行拆分

在神经网络模型中,还可以使用模型训练的方法对子词进行拆分。常见的有子词正则和BPEDropout方法。二者相比,BPEDropout方法更为出色。

1.2.5 模型中使用子词

在模型的训练过程中,输入的句子是以子词形式存在的,这种方式得到的预测结果也是子词。

当使用模型进行预测时,模型输出子词之后,再将其合并成整词即可。例如,训练时先把liyongle分成了[lI',yong','##le'],获得结果后,将句子中的“##”去掉即可。

2 PreTrainedTokenizer类

2.1 PreTrainedTokenizer类中的特殊词

在PreTrainedTokenizer类中,将词分成了两部分:普通词与特殊词。其中特殊词是指用于标定句子的特殊标记,主要是在训练模型中使用

2.1.1 使用代码查看系统特殊词

import torch
from transformers import BertTokenizer, BertForMaskedLM# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')for tokerstr in tokenizer.SPECIAL_TOKENS_ATTRIBUTES:strto = "tokenizer." + tokerstrprint(tokerstr, eval(strto))# 获得标记词在词表中的索引值print(“masktken”,tokenizer.mask_token,tokenizer.mask_token_id)# 输出
输出:bos_token None 
eos_token None
unk_token [UNK] # 未知标记
Using bos_token, but it is not set yet.
sep_token [SEP] # 句子结束标记
pad_token [PAD] # 填充标记
Using eos_token, but it is not set yet.
cls_token [CLS] # 开始标记
mask_token [MASK] # 遮蔽词标记
additional_special_tokens [] # 用于扩充使用,用户可以把自己的自定义特殊词添加到里面,可以对应多个标记,这些标记都会被放到列表中。获取该词对应的标记并不是一个,在获取对应索引值时,需要使用additional_special_tokens_ids属性。

2.2  PreTrainedTokenizer类中特殊词的使用方法

2.2.1 encode完整定义

def encode(self,text, # 第一个句子text_pair=None,  #第二个句子add_special_tokens=True,#是否添加特殊词,如果为False,则不会增加[CLS],[SEP]等标记词max_length=None, # #最大长度stride=0, #返回截断词的步长窗口,stride在encode方法中没有任何意义。该参数主要为兼容底层的encode_plus方法。在encode_plus方法中,会根据stride的设置来返回从较长句子中截断的词。truncation_strategy="longest_first", # 截断策略#截断策略:longest_first(默认值))当输入是2个句子的时候,从较长的那个句子开始处理对其进行截断,使其长度小于max_length参数。#截断策略:only_frst:只截断第一个句子。#截断策略:only_second:只截断第二个句子。#截断策略:dou not_truncate:不截断(如果输入句子的长度大于max_length参数,则会发生错误)。pad_to_max_length=False,#对长度不足的句子是否填充return_tensors=None, #是否返回张量类型,可以设置成"tf"或"pt",主要用于指定是否返回PyTorch或TensorFlow框架下的张量类型。如果不设置,默认为None,即返回Python中的列表类型。**kwargs)

2.2.2 代码实现:使用encode方法实现语句分词与分句

from transformers import BertTokenizer, BertForMaskedLM# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')# encode方法对每句话的开头和结尾都分别使用了[CLS]和[SEP]进行标记,并对其进行分词
one_toind = tokenizer.encode("Who is Li BiGor ?")#将第一句转化成向量
two_toind = tokenizer.encode("Li BiGor is a programmer")#将第二句转化成向量# 在合并时,使用了two_toind[1:]将第二句的开头标记[CLS]去掉,表明两个句子属于一个段落。
all_toind = one_toind+two_toind[1:] #将两句合并print(tokenizer.convert_ids_to_tokens(one_toind))
print(tokenizer.convert_ids_to_tokens(two_toind))
print(tokenizer.convert_ids_to_tokens(all_toind))
# 输出:
# ['[CLS]', 'who', 'is', 'li', 'big', '##or', '?', '[SEP]']
# ['[CLS]', 'li', 'big', '##or', 'is', 'a', 'programmer', '[SEP]']
# ['[CLS]', 'who', 'is', 'li', 'big', '##or', '?', '[SEP]', 'li', 'big', '##or', 'is', 'a', 'programmer', '[SEP]']

2.2.3 代码实现:使用encode方法实现语句的索引值填充

from transformers import BertTokenizer, BertForMaskedLM# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')# encode方法的参数max_length代表转换后的总长度.如果超过该长度,则会被截断。
# 如果小于该长度,并且参数pad_to_max_length为True时,则会对其进行填充。
padd_sequence_word = tokenizer.encode("Li BiGor is a man",max_length=10,pad_to_max_length=True)
print("padd_sequence_word:",padd_sequence_word)
# 输出:padd_sequence_word: [101, 5622, 2502, 2953, 2003, 1037, 2158, 102, 0, 0]

2.2.4 代码实现:使用encode方法实现语句的截断

from transformers import BertTokenizer, BertForMaskedLM# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')return_num = tokenizer.encode("Li BiGor is a man",max_length=5)
return_word = tokenizer.decode(return_num) # 使用decode将索引值转化为汉子
print("return_word:",return_word)
# 输出:return_word: [CLS] li bigor [SEP]

2.2.5 代码实现:使用encode_plus方法完成非填充部分的掩码标志,被截短词的附加信息

# encode_plus方法是PreTrainedTokenzer类中更为底层的方法。在调用encode方法时,最终也是通过encode_plus方法来实现的。from transformers import BertTokenizer, BertForMaskedLM
# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')# encode_plus方法输出了一个字典,字典中含有3个元素:
# input_jds:对句子处理后的词素引值,与encode方法输出的结果一致。
# token_type_ids:对两个句子中的词进行标识,属于第一个句子中的词用0表示,属于第二个句子中的词用1表示。
# attention_mask:表示非填充部分的掩码,非填充部分的词用1表示,填充部分的词用0表示。padded_plus_toind = tokenizer.encode_plus("Li BiGor is a man",maxlength = 10,pad_to_max_length=True)
print("padded_plus_toind:",padded_plus_toind)
# 输出:padded_plus_toind: {'input_ids': [101, 5622, 2502, 2953, 2003, 1037, 2158, 102],
#                        'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0],
#                        'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1]
#                        }

2.2.5 代码实现:使用batch_encode_pus方法批处理语句

# batch_encode_pus方法同时处理两个句子,并输出了一个字典对象两个句子对应的处理结果被放在字典对象value的列表中。from transformers import BertTokenizer, BertForMaskedLM
# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')tokens = tokenizer.batch_encode_plus(["This is a sample","This is another longer sample text"],pad_to_max_length=True )
print(tokens)
# 输出:{'input_ids': [[101, 2023, 2003, 1037, 7099, 102, 0, 0], [101, 2023, 2003, 2178, 2936, 7099, 3793, 102]],
#     'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]],
#     'attention_mask': [[1, 1, 1, 1, 1, 1, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1]]}

3 向PreTrainedTokenizer类中添加词(普通词和特殊词)

3.1 方法定义

  1. 添加普通词:调用add_tokens方法,填入新词的字符串.
  2. 添加特殊词:调用add_Special_tokens方法,填入特殊词字典.

3.2 代码实现:向PreTrainedTokenizer类中添加词(普通词和特殊词)

from transformers import BertTokenizer, BertForMaskedLM
# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')print("-------------------------添加特殊词前-------------------------")print("特殊词列表",tokenizer.additional_special_tokens) # 特殊词列表 ['<#>']
print("特殊词索引值列表:",tokenizer.additional_special_tokens_ids) # 特殊词索引值列表: [30522]toind = tokenizer.encode("<#> yes <#>")print(tokenizer.convert_ids_to_tokens(toind))# 将索引词转化成字符串并输出 :['[CLS]', '<', '#', '>', 'yes', '<', '#', '>', '[SEP]']print(len(tokenizer))# 输出词表总长度:30522print("-------------------------添加特殊词后-------------------------")special_tokens_dict = {'additional_special_tokens':["<#>"]}
tokenizer.add_special_tokens(special_tokens_dict)  # 添加特殊词
print("特殊词列表",tokenizer.additional_special_tokens) # 特殊词列表 []
print("特殊词索引值列表:",tokenizer.additional_special_tokens_ids) # 特殊词索引值列表: []toind = tokenizer.encode("<#> yes <#>")print(tokenizer.convert_ids_to_tokens(toind))  # tokenzer在分词时,没有将“<#>”字符拆开。
# 将索引词转化成字符串并输出 :['[CLS]', '<#>', 'yes', '<#>', '[SEP]']print(len(tokenizer))   # 输出词表总长度:30523



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Pytorch神经网络实战案例】34 使用GPT-2模型实现句子补全功能(手动加载)

1 GPT-2 模型结构 GPT-2的整体结构如下图&#xff0c;GPT-2是以Transformer为基础构建的&#xff0c;使用字节对编码的方法进行数据预处理&#xff0c;通过预测下一个词任务进行预训练的语言模型。 1.1 GPT-2 功能简介 GPT-2 就是一个语言模型&#xff0c;能够根据上文预测下…

电容式传感器位移性能试验报告_一文读懂什么是接近传感器?

点击上方蓝字 记得关注我们哦&#xff01;接近传感器是一种非接触式传感器&#xff0c;当目标进入传感器的视野时&#xff0c;它会检测到物体(通常称为“目标”)的存在。取决于接近传感器的类型&#xff0c;传感器可以利用声音&#xff0c;光&#xff0c;红外辐射(IR)或电磁场来…

[dts]DTS实例分析

2. 通常会碰到的实际问题 到此&#xff0c;问题出现了&#xff1a; 1. 当写一个按键驱动&#xff0c;应该如何在*.dts或者*.dtsi中操作? 2. 当在串口driver中需要使用到某个pin脚作为普通输出IO&#xff0c;该如何操作&#xff1f; 3. 当在串口driver中需要使用某个muxpin脚作…

【解决】YOLOv6.1安装requirements.txt报错UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x84

案例描述: 使用YOLOV5时&#xff0c;报错解决UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x84 in position 285: illegal multibyte sequence 解决方案&#xff1a; 在C:\ProgramData\Anaconda3\lib\distutils\dist.py"文件搜索read 将parser.read(filenam…

bp 神经网络 优点 不足_深度学习之BP神经网络--Stata和R同步实现(附Stata数据和代码)

说明&#xff1a;本文原发于“计量经济圈”公众号&#xff0c;在此仅展示Stata的部分。R部分请移步至本人主页的“R语言与机器学习--经济学视角”专栏&#xff0c;或点击下方链接卡跳转。盲区行者&#xff1a;深度学习之BP神经网络--Stata和R同步实现&#xff08;附R数据和代码…

Win10系统下使用anaconda在虚拟环境下安装CUDA及CUDNN

前排预警&#xff1a;不要挂梯子!!!!!使用清华源就行不然报错&#xff01;&#xff01;&#xff01;&#xff01; 解决check_hostname requires server_hostname_orange_の_呜的博客-CSDN博客错误描述在GitHub下载代码文件后使用pip install -r requirement.txt下载依赖包时出…

将XML格式转化为YOLO需要的txt格式(代码)

1、XML的格式 <annotation><folder>cr</folder><filename>crazing_2.jpg</filename><source><database>NEU-DET</database></source><size><width>200</width><height>200</height><…

js 点击button切换颜色_ThingJS 和three.js开发示例对比,让开发早点下班回家!3D 可视化...

ThingJS 3D框架简化了开发工作&#xff0c;面向对象和模块化的特点使得网页代码更加易于管理和维护&#xff0c;并且提供近200个官方示例&#xff0c;直接获取API能力&#xff0c;不需要基于3D概念进行开发&#xff0c;适合3D商业项目快速生成&#xff01;距离您的业务仅一层之…

VSCode使用技巧——Ctrl+鼠标滚轮键使字体进行缩放

点击VSCode左下角的齿轮&#xff0c;进入设置 进入Extensions——》JSON——》Edit in settings.json 在json当中添加如下&#xff1a; "editor.mouseWheelZoom": true,

OpenCV各版本差异与演化,从1.x到4.0

最近因项目需要&#xff0c;得把OpenCV捡起来&#xff0c;登录OpenCV官网&#xff0c;竟然发现release了4.0.0-beata版本&#xff0c;所以借此机会&#xff0c;查阅资料&#xff0c;了解下OpenCV各版本的差异及其演化过程&#xff0c;形成了以下几点认识&#xff1a; 新版本的…

西门子s7-200解密软件下载_西门子S7-200/300/400通讯方式汇总,超级全面

1西门子 200 plc 使用 MPI 协议与组态王进行通讯时需要哪些设置?1)在运行组态王的机器上需要安装西门子公司提供的 STEP7 Microwin 3.2 的编程软件&#xff0c;我们的驱动需要调用编程软件提供的 MPI 接口库函数;2)需要将 MPI 通讯卡 CP5611 卡安装在计算机的插槽中&#xff0…

如何监控NVIDIA GPU 的运行状态和使用情况

设备跟踪和管理正成为机器学习工程的中心焦点。这个任务的核心是在模型训练过程中跟踪和报告gpu的使用效率。 有效的GPU监控可以帮助我们配置一些非常重要的超参数&#xff0c;例如批大小&#xff0c;还可以有效的识别训练中的瓶颈&#xff0c;比如CPU活动(通常是预处理图像)占…

HBase学习笔记——概念及原理

1.什么是HBase HBase – Hadoop Database&#xff0c;是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统&#xff0c;利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。HBase利用Hadoop HDFS作为其文件存储系统&#xff0c;利用Hadoop MapReduce来处理HBas…

.bat是什么语言_简单说说当我们打开网页时,浏览器到底做了什么?

前言&#xff1a;为什么我们需要掌握浏览器的原理作为一名前端研发&#xff0c;平日里打交道最多的&#xff0c;就是各式各样的客户端。不论你是针对pc端还是移动端&#xff0c;甚至是专门在微信端做前端研发&#xff0c;都需要跟一样东西接触——浏览器。不知道你有没有留意过…

花书《深度学习》代码实现:02 概率部分:概率密度函数+期望+常见概率分布代码实现

1 概率 1.1 概率与随机变量 频率学派概率 (Frequentist Probability)&#xff1a;认为概率和事件发⽣的频率相关。贝叶斯学派概率 (Bayesian Probability)&#xff1a;认为概率是对某件事发⽣的确定程度&#xff0c;可以理解成是确信的程度。随机变量 (Random Variable)&…

内存泄露Lowmemorykiller分析

01 前言 最近疫苗事情非常火热,这件事情让我对刘强东有点刮目相看,我们需要更多的人关注曝光此类问题 02 正文 Android Kernel 会定时执行一次检查,杀死一些进程,释放掉内存。Low memory killer 是定时进行检查。Low memory killer 主要是通过进程的oom_adj 来判定进程的…

TabError: inconsistent use of tabs and spaces in indentation

本文使用PyCharm的格式化代码功能解决TabError: inconsistent use of tabs and spaces in indentation。 1、提出问题&#xff1a; 当把代码从别处复制进来PyCharm&#xff0c;然后运行报错&#xff1a;TabError: inconsistent use of tabs and spaces in indentation 2、 分…

python 默认参数_有趣的 Python 特性 3 | 当心默认可变参数这个大猪蹄子。

本文字数&#xff1a;1575 字阅读本文大概需要&#xff1a;4 分钟写在之前Python 提供了很多让使用者觉得舒服至极的功能特性&#xff0c;但是随着不断的深入学习和使用 Python&#xff0c;我发现其中存在着许多玄学的输出与之前预想的结果大相径庭&#xff0c;这个对于初学者来…

AI-无损检测方向速读:基于深度学习的表面缺陷检测方法综述

1 表面缺陷检测的概念 表面缺陷检测是机器视觉领域中非常重要的一项研究内容, 也称为 AOI (Automated optical inspection) 或 ASI (Automated surface inspection)&#xff0c;它是利用机器视觉设备获取图像来判断采集图像中是否存在缺陷的技术。 1.1 传统检测的缺陷(非CNN)…

【完美解决】RuntimeError: one of the variables needed for gradient computation has been modified by an inp

正文在后面&#xff0c;往下拉即可~~~~~~~~~~~~ 欢迎各位深度学习的小伙伴订阅的我的专栏 Pytorch深度学习理论篇实战篇(2023版)专栏地址&#xff1a; &#x1f49b;Pytorch深度学习理论篇(2023版)https://blog.csdn.net/qq_39237205/category_12077968.html &#x1f49a;Pyt…