HuggingFace API学习(1)

HuggingFace API学习

transformers.pipline

pipline(“model name”)

可选的pipline:

在这里插入图片描述

Zero-shot classification:

可以自定义分类标签,预训练模型会将判断该句子是否属于这些自定义标签。

NER(named entity recognition)命名实体识别

ner = pipeline("ner", grouped_entities=True)

问答任务

question_answer = pipeline("question-answering")
result = question_answer(
    question="Where do I work?",
    context="My name is Sylvain and I work at Hugging Face in Brooklyn",
)

总结任务(Summarization)

summarizer = pipeline("summarization")

不同类型的Transformer模型

  1. GPT-like(regressive Transformer models)自回归Transformer模型
  2. BERT-like(auto-encoding Transformer models)自编码Transformer模型
  3. BART/T5-like(seq2seq Transformer models)序列到序列Transformer模型

在这里插入图片描述

编码器:适用于需要理解输入的任务,例如句子分类和命名实体识别。

解码器:适用于文本生成等生成任务

编码器-解码器或者序列到序列模型:适用于需要输入的生成任务,例如翻译和摘要。

在每个阶段,注意力层都可以访问初始句子中的所有单词。这些模型被描述为具有“双向注意力”,通常为成为auto-encoding model(自动编码模型)

Encoder models最适用于需要理解整个句子的任务。例如分类,命名实体识别,问答。该系列模型的代表有:ALBERT、BERT、DistilBERT、ELECTRA、RoBERTa

Decoder models使用Transformer模型中的解码器。在每个阶段,注意力层只能访问句子中位于它之前的单词,这些模型通常被成为auto-regressive models(自回归模型)这些模型适用于文本生成,该系列模型的代表有CTRL、GPT、GPT-2、Transformer XL

Encoder-Decoder models就是seq2seq模型。编码器可以访问输入的所有单词,解码器只能访问输入中给定单词之前的单词。seq2seq模型最适合围绕根据给定输入生成新句子的任务,例如摘要、翻译或生成式问答。该系列模型的代表有:BART、mBART、Marian、T5

Behind the pipeline

在使用pipeline方法时,底层都发生了什么事情?

在这里插入图片描述

  1. 使用tokenizer(分词器)进行预处理

    from transformers import AutoTokenizer
    
    checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
    tokenizer = AutoTokenizer.from_pretrained(checkpoint)
    

    处理过后,字符串转化为了ids,并存放在result中的input_ids中。

    可以直接使tokenizer返回tensor类型,并且可以指定是什么机器学习框架中的tensor

    inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
    
  2. 相同的方法得到model

    from transformers import AutoModel
    checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
    model = AutoModel.from_pretrained(checkpoint)
    

    该模型使用的是Transformer的Encoder,输出结果的维度是[batch size, Seq len, Hidden size]

    除了得到隐藏层的“Model”,还有很多其他的语言模型:

在这里插入图片描述

在这里插入图片描述

  1. Mode的输出实际上是隐藏层,隐藏层将会被输入到一个叫“head”的层做处理(个人理解这个heda层有点像是下游任务模型)

    例如使用句子分类的模型:

    from transformers import AutoModelForSequenceClassification
    
    checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
    model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
    outputs = model(**inputs)
    
  2. 输出之后的处理

    一般是softmax

Model

创建一个Transformer模型:

from transformers import BertConfig, BertModel

# Building the config
config = BertConfig()

# Building the model from the config
model = BertModel(config)

Config类拥有很多可以用于创建模型的配置信息:

BertConfig {
  [...]
  "hidden_size": 768,
  "intermediate_size": 3072,
  "max_position_embeddings": 512,
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  [...]
}

这种创建方法,该模型的参数是随机初始化的。

使用一下方法导入预训练的模型:

from transformers import BertModel

model = BertModel.from_pretrained("bert-base-cased")

可以初始化Bert模型的chechpoint的完整列表:

https://huggingface.co/models?filter=bert

模型的保存方法:

model.save_pretrained( "directory_on_my_computer" )

Tokenizers

一句话–>数字

  1. word-based:基于词的

    一种语言的词汇太多,使用词表覆盖所有是不可能的,因此就有了[UNK],要尽可能的少引用这个token。一种减少引用[UNK]的方法是,使用一个character-based的分词器。

  2. character-based:有两个优点

    1. 词表小很多
    2. 少得多的[UNK]

    出现了标点符号问题,而且英文中这样分词意义不大,但是中文中每个字能包含更多的信息。而且一个词语可能包含多个基于字符的标记。

    为了两全其美,有了第三种技术:子词标记化

  3. subword tokenization

    频繁的单词不应该被划分为更小的单词,但是不频繁的应该被拆分为有意义的子词。

加载和保存:和Model一样

text–>encoding:需要两步

  1. 分词
  2. 转化为IDs

Handling multiple sequences

一次处理1个序列,由于模型需要的输入默认是有batch的,解决方法是:

input_ids = torch.tensor([ids])

如果一次处理多个序列,则怎么解决长度不同的问题?

Padding the inputs:

batched_ids = [
    [200, 200, 200],
    [200, 200]
]
转换为:
padding_id = 100

batched_ids = [
    [200, 200, 200],
    [200, 200, padding_id],
]

但是有一个问题,由于自注意力机制,padding_id会对整个seq造成影响,为了取消这种影响,可以使用Attention masks

Attention masks

Attention mask使用0,1标记,1代表注意力层不应该忽略,0表示注意力层应该忽略。

batched_ids = [
    [200, 200, 200],
    [200, 200, tokenizer.pad_token_id],
]

attention_mask = [
    [1, 1, 1],
    [1, 1, 0],
]

outputs = model(torch.tensor(batched_ids), attention_mask=torch.tensor(attention_mask))
print(outputs.logits)

Longer Seqence

transformer模型对输入的模型序列长度有限制,如果要求处理更长序列怎么办?两种方法:

  1. 使用支持序列长度更长的模型:

    Longformer、LED

  2. 截断序列

    sequence = sequence[:max_sequence_length]
    

Putting it all together

tokenizer的强大:

padding:

# Will pad the sequences up to the maximum sequence length
model_inputs = tokenizer(sequences, padding="longest")

# Will pad the sequences up to the model max length
# (512 for BERT or DistilBERT)
model_inputs = tokenizer(sequences, padding="max_length")

# Will pad the sequences up to the specified max length
model_inputs = tokenizer(sequences, padding="max_length", max_length=8)

截断:

model_inputs = tokenizer(sequences, max_length=8, truncation=True)

注意:先分词再转化为id的输出和直接调用tonkenizer的输出不同,因为后者还对原来的句子加上了[CLS]和[SEP]的token

总体使用:

tokens = tokenizer(sequences, padding=True, truncation=True, return_tensors="pt")
output = model(**tokens)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值