当前位置:   article > 正文

transformers DataCollator介绍_datacollatorforseq2seq

datacollatorforseq2seq

本博客主要介绍 transformers DataCollator的使用

  1. from transformers import AutoTokenizer, AutoModel, \
  2. DataCollatorForSeq2Seq, DataCollatorWithPadding, \
  3. DataCollatorForTokenClassification, DefaultDataCollator, DataCollatorForLanguageModeling
  4. PRETRAIN_MODEL = "E:\pythonWork\models\chinese-roberta-wwm-ext"
  5. tokenizer = AutoTokenizer.from_pretrained(PRETRAIN_MODEL)
  6. model = AutoModel.from_pretrained(PRETRAIN_MODEL)
  7. texts = ['今天天气真好。', "我爱你"]
  8. encodings = tokenizer(texts)
  9. labels = [list(range(len(each))) for each in texts]
  10. inputs = [{"input_ids":t, "labels": l} for t,l in zip(encodings['input_ids'], labels)]
  11. dc1 = DefaultDataCollator()
  12. dc2 = DataCollatorForTokenClassification(tokenizer=tokenizer)
  13. dc3 = DataCollatorWithPadding(tokenizer=tokenizer)
  14. dc4 = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model)
  15. d5 = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)
  16. d6 = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=True, mlm_probability=0.15)
  17. print('DataCollatorForTokenClassification')
  18. print(dc2(inputs))
  19. print('DataCollatorWithPadding')
  20. print(dc3(encodings))
  21. print('DataCollatorForSeq2Seq')
  22. print(dc4(inputs))
  23. print(123)

DataCollatorForTokenClassification

观察如下输出,token分类任务中,每个token都应该有一个标签,所以存在以下数量关系:

长度:ids==labels

ids进行了填充,

labels进行了填充

attention_mask进行了填充

  1. DataCollatorForTokenClassification
  2. {'input_ids': tensor([[ 101, 791, 1921, 1921, 3698, 4696, 1962, 511, 102],
  3. [ 101, 2769, 4263, 872, 102, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1],
  4. [1, 1, 1, 1, 1, 0, 0, 0, 0]]), 'labels': tensor([[ 0, 1, 2, 3, 4, 5, 6, -100, -100],
  5. [ 0, 1, 2, -100, -100, -100, -100, -100, -100]])}

DataCollatorWithPadding

这个collator一般使用在文本分类,文本分类中,label和输入的ids长度之间没有什么关系。

ids进行了填充,

labels进行了填充

attention_mask进行了填充

  1. DataCollatorWithPadding
  2. {'input_ids': tensor([[ 101, 791, 1921, 1921, 3698, 4696, 1962, 511, 102],
  3. [ 101, 2769, 4263, 872, 102, 0, 0, 0, 0]]), 'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0],
  4. [0, 0, 0, 0, 0, 0, 0, 0, 0]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1],
  5. [1, 1, 1, 1, 1, 0, 0, 0, 0]])}

DataCollatorForSeq2Seq

长度:ids 和labels之间的长度不存在关系。  (注意和DataCollatorForTokenClassification进行区分)

ids进行了填充,

labels进行了填充

attention_mask进行了填充

注意:这个示例通常是encoder-decoder(或者称之为condition generation)模型使用的输入,ids和label长度不需要一样,encoder模型输入ids,抽取特征,decoder进行解码,预测labels。此时的mask是针对ids的填充进行mask(ids中的0即是填充)

  1. DataCollatorForSeq2Seq
  2. {'input_ids': tensor([[ 101, 791, 1921, 1921, 3698, 4696, 1962, 511, 102],
  3. [ 101, 2769, 4263, 872, 102, 0, 0, 0, 0]]), 'labels': tensor([[ 0, 1, 2, 3, 4, 5, 6],
  4. [ 0, 1, 2, -100, -100, -100, -100]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1],
  5. [1, 1, 1, 1, 1, 0, 0, 0, 0]])}

还有另一种情况,就是gpt,chatglm,llama这种decoder模型中,也会使用DataCollatorForSeq2Seq,但是此时的labels和ids必是相同长度的然后。原因是这样的,

此时的输入=ids+labels

此时的标签(labels)= len(ids)*[-100] + labels (-100不计算损失)

举个例子:

假设输入input='我爱' ,对应的ids是[1,2]  ,我希望模型预测出标签label='人民',对应的label ids是[3,4]

那么模型输入=[1,2,3,4]

模型要预测的标签=[-100,-100,3,4]   

如果我们考虑多个例子,算上填充,那么情况是下面这样的。

假设我们还有另一条数据是input='今天天气',  label='真好'

把这两条样本组合成一个batch,则

输入=[

[1,2,3,4,0,0],  # 填充0,保持长度一样

[11,12,13,14,15,16]

]

标签=[

[-100,-100,3,4,-100,-100] ,  # 末尾填充了两个-100,保证batch内长度一致,并且-100不计算损失

[-100,-100,-100,-100,15,16]     # 前面4个是-100,因为‘今天天气’四个字是已知的,我们只想要预测“真好”两个字

]

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/945403
推荐阅读
相关标签
  

闽ICP备14008679号