序列标注 通常也可以看作是token级别的分类问题 对每一个token进行分类。
最常见的token级别分类任务:
organization组织机构名, location地点名…).POS (Part-of-speech tagging词性标注) 根据语法对token进行词性标注 (noun名词, verb动词,
adjective形容词…)Chunk (Chunking短语组块) 将同一个短语的tokens组块放在一起。 2.对齐
tokenized_input tokenizer(example[ tokens ], is_split_into_words True) tokens tokenizer.convert_ids_to_tokens(tokenized_input[ input_ids ]) print(tokens)
结果
由于标注数据通常是在word级别进行标注的 既然word还会被切分成subtokens 那么意味着我们还需要对标注数据进行subtokens的对齐。同时 由于预训练模型输入格式的要求 往往还需要加上一些特殊符号比如 [CLS] 和 [SEP]。
len(example[f {task}_tags ]), len(tokenized_input[ input_ids ])
结果
(31, 39)
tokenizer有一个 word_ids方法可以帮助我们解决这个问题。
print(tokenized_input.word_ids())
结果
[None, 0, 1, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, None]
可以看到 word_ids将每一个subtokens位置都对应了一个word的下标。比如第1个位置对应第0个word 然后第2、3个位置对应第1个word。特殊字符对应了None。有了这个list 我们就能将subtokens和words还有标注的labels对齐啦。
word_ids tokenized_input.word_ids()
aligned_labels [-100 if i is None else example[f {task}_tags ][i] for i in word_ids]
print(len(aligned_labels), len(tokenized_input[ input_ids ]))
结果
39 39
我们通常将特殊字符的label设置为-100 在模型中-100通常会被忽略掉不计算loss。
我们有两种对齐label的方式
多个subtokens对齐一个word 对齐一个label多个subtokens的第一个subtoken对齐word 对齐一个label 其他subtokens直接赋予-100.


