Hugging Face实战-系列教程1:Tokenizer分词器(Transformer工具包/自然语言处理)
Hugging Face实战-系列教程1:Tokenizer分词器(Transformer工具包/自然语言处理)
🚩🚩🚩Hugging Face 实战系列 总目录
有任何问题欢迎在下面留言
本篇文章的代码运行界面演示结果均在notebook中进行
本篇文章配套的代码资源已经上传
下篇内容:
Hugging Face实战-系列教程2:AutoModel模型自动选择工具_机器学习杨卓越的博客-CSDN博客
今天要做的这个任务其实就是一个调包的过程,但是我们需要了解一下这个流程。这个流程熟悉了,NLP领域的很多问题都可以按照这个流程去做了,比如对话生成、机器翻译、文本摘要等任务,你脑海中就会浮现出一个通用模板了,你不需要在做所有的子任务之前都需要再熟悉一遍了。你只需要知道,到了今天在NLP领域的所有任务,都可以用Transformer结合Hugging Face去玩就行了。
1、相关背景
NLP要解决的任务:
- 处理文本数据,首先对文本数据进行分词操作(分词的方法可能会不同,中文常见的就是分词或者分字)
- 分完的词它不还是字符嘛,计算机还不认识,最终我们希望把这些字符映射成实际的特征(向量)
- 输入搞定好了之后,接下来咱们要构建模型了(一般都用预训练模型,例如BERT,GPT系列等)
- 怎么去完成我们自己的任务呢,基本上就是在预训练模型的基础上进行微调(训练我们自己数据的过程)
2012年的word2vec到现在除了科研机构,已经完全不需要使用了。绝大多数的算法工程师和科研人员都没有机会去参与词向量的制作。词向量的制作,这个数据量已经不仅仅是用G或者T来衡量的单位,这个数据量是非常惊人的。
国内一般使用哈工大的或者清华的词向量库,我们调现成的就行,别觉得调现成的很low,这是最方便的做法。(你自己做,先不说你有没有这种级别的计算资源,你存都没地方存,真做起来电费你都交不起)。我们需要做的就是在别人的模型和词库基础上,对模型进行微调来解决自己的任务。
NLP任务,主要分成两个方向来学习一个是谷歌的bert,一个是openAI的gpt,二者都是2018年所出的模型基本同一时间,谁抄谁还不一定呢。
2、安装测试
首先看看怎么使用Hugging Face给我们提供的包,首先安装:
安装就是很简单,打开命令行,执行这个命令就是装,只需要这一步操作!(没有什么CPU、GPU版本,没有一大串恶心人的操作,可能之前装Pytorch、TF还有一些商汤做的一些包,已经把我们算法工程给装怕了。)
pip install transformers
但是在此之前,你最起码要把深度学习的环境配置好,可以参考我这篇文章:PyTorch深度学习开发环境搭建全教程
先来瞅瞅多简单就干了一个大活
Huggingface这个包基本上就是调用即可,开箱即用的过程
对刚刚安装的包进行Hello Word级别任务测试:
import warnings
warnings.filterwarnings("ignore")
from transformers import pipeline#用人家设计好的流程完成一些简单的任务
classifier = pipeline("sentiment-analysis")
classifier(
[
"I've been waiting for a HuggingFace course my whole life.",
"I hate this so much!",
]
)
输出结果:
[{'label': 'POSITIVE', 'score': 0.9598050713539124},
{'label': 'NEGATIVE', 'score': 0.9994558691978455}]
这就是从transformers调出一个pipeline模块,这个模块可以给你提供很多接口,比如sentiment-analysis就是情感分析接口,第一次执行这个代码的时候,会给你下载一些已经训练好的模型。(你跑这个可能不需要梯子,但是你玩HuggingFace没有梯子可能还真不行)
下载的模型一般在这个位置:
3、基本流程概述分析
- 首先就是第一步Raw text输入文本(This course is amazing)
- 不管是中文还是英文都会将文本转化为ID,(This course is amazing)是四个词为什么会有6个ID呢?后面解释。
- ID直接输入到模型中(Bert、GPT),生成一个Logits结果
- 在经过一个后处理词操作,把前面的结果转换成概率
NLP的流程比CV简单的多,在CV领域的任务流程处理方式百花齐放,但是在NLP领域就是Transformer一统天下的格局。NLP的流程非常非常固定,没有任何区别。人类学会人类语言需要两年,这两年过程中的每天可能需要听到上万个词,所以让计算机学会人类语言也是需要一个过程的。NLP任务基本上都是大同小小小异。
4、Tokenizer需要做的事情
- 分词,分字以及特殊字符(起始,终止,间隔,分类等特殊字符可以自己设计的)
- 对每一个token映射得到一个ID(每个词都会对应一个唯一的ID)
- 还有一些辅助信息也可以得到,比如当前词属于哪个句子(还有一些MASK,表示是否事原来的词还是特殊字符等)
上代码:
from transformers import AutoTokenizer#自动判断
checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"#根据这个模型所对应的来加载
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
(Hugging Face一个特别牛逼的地方就是一个API玩儿所有东西,就不用在多个地方调分词器)
从Transformers中调出一个自动分词器,这个“自动”分词器AutoTokenizer可以根据你选择的模型自动选择分词器,这就太省事儿,但是我们应该怎么选择模型呢?你去Hugging Face上去下载,不知道选哪个,按照销量(下载量)来呗。(现在NLP领域研究的论文,全都得根据Hugging Face去做,为什么?你得做对比试验啊,在HuggingFace就很方便去和别人作对比)
一个小例子:
raw_inputs = [
"I've been waiting for a this course my whole life.",
"I hate this so much!",
]
inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
print(inputs)
解释一下tokenizer的参数:
- raw_inputs:你选择的语言文本
- padding:默认为True,你输入的句子长度不一样,不管你输入多少句子,按照最长的那个进行补齐,补得就是0,padding这个词,我们在卷积神经网络就已经见过了
- truncation:截断操作,这里没用上,其实任务中需要制定一个max_longs参数,指定一个最大长度的句子,事实上所有的模型都指定来512个词为最大长度,谷歌、openAI亦是如此,在深度学习中科学家也很喜欢512个词。也就是说,一个句子最大长度就是512个词
- return_tensors:在Hugging Face中支持多种框架,默认的是PyTorch,PyTorch的数据格式就是tensor,指定为pt
这段代码的输出结果:
{'input_ids': tensor([[ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 2023, 2607, 2026, 2878,
2166, 1012, 102],
[ 101, 1045, 5223, 2023, 2061, 2172, 999, 102, 0, 0, 0, 0,
0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]])}
你需要记住这个input_ids,input_ids这个名字是自动生成的,它是将每一个词都生成一个对应的索引。
比如看第二句话 I hate this so much! 一共有5个单词,但是还得加上标点符号,就是6个,但是在上面的结果中可以看到有8个编号后面再加上一下补长的0,其中101表示一个句子的开头,102表示一个句子的结束,所以有8个编号。(不同分词器的编号规则和内容不一定相同)
也就是说当前的id可以转化为tensor,也可以转化为文本,可以做编码解码的工作
使用这个编号,将句子解码出来,代码:
tokenizer.decode([ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 2023, 2607, 2026, 2878,2166, 1012, 102])
输出的结果:
"[CLS] i've been waiting for a this course my whole life. [SEP]"
这里的CLS表示的是分类的字符,SEP表示终止的字符,也就是说101和102表示特殊字符。
那后面0是什么?前面提到为来保证长度一致,做了padding补齐的操作,通过SEP做来分隔,SEP之前是实际内容,SEP之后是补0的内容,但是我们注意到了一个叫做attention_mask的东西。我们在做Transformer在做Self-Attention的时候,每一个词都需要跟所有的词计算关系(还不知道什么是Transformer去看我的这篇文章),那我后面补了0,需要前面的词需要和0计算关系吗?是不是不用啊。attention_mask表示的意思就是SEP后面的0,是不用计算的,全都是占位符而已。
下篇内容:
更多推荐
所有评论(0)