NLP-学习笔记(一)

NLP-学习笔记(一)

自然语言处理NLP的学习,不可能有一步登天的方法。博客用于记录自然语言处理的学习路程和知识点。
相信很多初学的同学,一开接触NLP,都会知道TransformersBERT,性子比较急切的同学开始了死磕BERT源码,我一开始也是这样,从源码中获取知识,但是总是对网络的相关输入困惑,这篇学习笔记主要记录NLP数据输入处理的相关概念。

Model inputs

Token

Token的理解比较容易,是一串自然语言符号的最小语言单位(单词、词组、字符),将输入的一句话根据规定的最小语言单位划分开。 例如:“I am Chinese, I love China”

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
sequence = "I am Chinese, I love China"

tokenized_sequence = tokenizer.tokenize(sequence)
print("tokenized sequence:", tokenized_sequence)
[output] tokenized sequence: ['I', 'am', 'Chinese', ',', 'I', 'love', 'China']

每个tokenizer的工作方式不同,但其底层机制是相同的,上面是一个使用BERT分词器的例子,它是一个WordPiece分词器。
对tokenizer更好的解释:

The tokenizer takes care of splitting the sequence into tokens available in the tokenizer vocabulary.

input IDs

自然语言,是符号记录,需要将这种符号记录输入模型,使得模型能够“看得懂”这串记录,也就是说,input IDs 是作为输入传递给模型的唯一必需参数,它们是符号索引,是符号的数字表示形式,用于构建将被模型用作输入的序列。有了上述得到的token,将每个token转换成IDs

input_ids = tokenizer.convert_tokens_to_ids(tokenized_sequence)
print("ids sequence      :", input_ids)
[output] ids sequence      : [146, 1821, 1922, 117, 146, 1567, 1975]

也就是说,[146, 1821, 1922, 117, 146, 1567, 1975]这串IDs序列,是符号索引,对应着例句"I am Chinese, I love China",将这串IDs序列解码,即可得到相应的自然语言表示。

decode_output = tokenizer.decode(input_ids)
print("decode output     :", decode_output)
decode output     : I am Chinese, I love China
[output] decode output     : I am Chinese, I love China

Attention mask

输入模型的句子都应该是等长的,但是句子有长有短,短的句子应该padding到等长,比如:

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-cased")

sequence_a = "This is a short sequence."
sequence_b = "This is a rather long sequence. It is at least longer than the sequence A."

encoded_sequence_a = tokenizer(sequence_a)["input_ids"]
encoded_sequence_b = tokenizer(sequence_b)["input_ids"]

len(encoded_sequence_a), len(encoded_sequence_b)
[output] (8,19)

句子A长度为8,句子B长度为19,因此句子A后面将padding一串0,使得长度等于19

padded_sequences = tokenizer([sequence_a, sequence_b], padding=True)
print("A ids:", padded_sequences["input_ids"][0])
print("B ids:", padded_sequences["input_ids"][1])
[output] A ids: [101, 1188, 1110, 170, 1603, 4954, 119, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
		 B ids: [101, 1188, 1110, 170, 1897, 1263, 4954, 119, 1135, 1110, 1120, 1655, 2039, 1190, 1103, 4954, 138, 119, 102]

这样可以在PyTorch或TensorFlow中转换成一个张量。此时需要Attention mask告诉模型,哪些是原句,哪些是填充,换句话说,Attention mask是一个二元张量,表示填充指标的位置。对于BertTokenizer, 1表示应该关注的值,而0表示填充值。

print("A attention mask:", padded_sequences["attention_mask"][0])
print("B attention mask:", padded_sequences["attention_mask"][1])
[output] A attention mask: [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
		 B attention mask: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

Token Type IDs

当模型的目的是对句子进行分类或回答问题,此时一次输入模型的句子就不止一句,Token Type IDs就是标识不同句子序列。通常"[CLS]"表示一个句子的开始,“[SEP]”表示一个句子的结束。

sequence_a = "HuggingFace is based in NYC"
sequence_b = "Where is HuggingFace based?"

encoded_dict = tokenizer(sequence_a, sequence_b)
decoded = tokenizer.decode(encoded_dict["input_ids"])
decoded
[output] '[CLS] HuggingFace is based in NYC [SEP] Where is HuggingFace based? [SEP]'

此时的Token Type IDs 是:

encoded_dict['token_type_ids']
[output] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]

开篇都是基础知识。

欲速则不达,千里筑基第一步
[1]: https://huggingface.co/docs/transformers/glossary

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值