当前位置:   article > 正文

【自然语言处理七】Bert模型及应用_bert模型使用

bert模型使用

1.Bert模型

简介

BERT的全称是Bidirectional Encoder Representation from Transformers,即双向Transformer的Encoder,因为decoder是不能获要预测的信息的。模型的主要创新点都在pre-train方法上,即用了Masked LM和Next Sentence Prediction两种方法分别捕捉词语和句子级别的representation。
MLM任务
NSP任务

预训练和微调

你需要搭建一个网络模型来完成一个特定的图像分类的任务。首先,你需要随机初始化参数,然后开始训练网络,不断调整直到网络的损失越来越小。在训练的过程中,一开始初始化的参数会不断变化。当你觉得结果很满意的时候,你就可以将训练模型的参数保存下来,以便训练好的模型可以在下次执行类似任务时获得较好的结果。这个过程就是 pre-training。
之后,你又接收到一个类似的图像分类的任务。这时候,你可以直接使用之前保存下来的模型的参数来作为这一任务的初始化参数,然后在训练的过程中,依据结果不断进行一些修改。这时候,你使用的就是一个 pre-trained 模型,而过程就是 fine-tuning。
所以,预训练 就是指预先训练的一个模型或者指预先训练模型的过程;微调 就是指将预训练过的模型作用于自己的数据集,并使参数适应自己数据集的过程。

Bert的掩码机制

(1) 处理非定长的批次序列,让模型忽略Padding部分。
(2)防止标签泄露,在模型预测时,将后面的词遮住防止“偷看”。

2.Bert模型应用

这里分别介绍利用transformers库来进行完形填空和文本生成任务。

transformers库

在Bertology系列模型中,包含ELMO,BERT,Transformer-XL,GPT-3等多种预训练语言模型,这些模型代码接口不同,训练起来极耗算力资源,且使用复杂。为了解决这一问题,推出了transformers库。

完形填空
import torch
from transformers import BertTokenizer, BertForMaskedLM
from transformers import AutoModelWithLMHead
from transformers.models.auto.tokenization_auto import AutoTokenizer
#加载预训练模型 tokenizer (vocabulary)
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')

#输入文本
text = "[CLS] Who is Li Jinhong ? [SEP] Li Jinhong is a programmer [SEP]"
tokenized_text = tokenizer.tokenize(text)
print(tokenized_text)

masked_index = 8 #掩码一个标记,用' BertForMaskedLM '预测回来
tokenized_text[masked_index] = '[MASK]'
print(tokenized_text)


# 将标记转换为词汇表索引
indexed_tokens = tokenizer.convert_tokens_to_ids(tokenized_text)
# 将输入转换为PyTorch张量
tokens_tensor = torch.tensor([indexed_tokens])

#指定设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

# 加载预训练模型 (weights)
model = AutoModelWithLMHead.from_pretrained('bert-base-uncased')
model.eval()
model.to(device)


segments_ids = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]
segments_tensors = torch.tensor([segments_ids]).to(device)

tokens_tensor = tokens_tensor.to(device)
# 预测所有的tokens
with torch.no_grad():
    outputs = model(tokens_tensor, token_type_ids=segments_tensors)

print('outputs:',outputs)    
predictions = outputs[0]  #[1, 15, 30522]
print('predictions:',predictions.shape) 
predicted_index = torch.argmax(predictions[0, masked_index]).item()
predicted_token = tokenizer.convert_ids_to_tokens([predicted_index])[0] #转成单词
print('Predicted token is:',predicted_token)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
文本生成
# -*- coding: utf-8 -*-
"""
Created on Fri Mar 20 11:10:34 2020
@author: ljh
"""

import torch
from transformers import GPT2Tokenizer, GPT2LMHeadModel

# 加载预训练模型(权重)
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')

# for tokenstr in tokenizer.SPECIAL_TOKENS_ATTRIBUTES:
#     stro="tokenizer."+tokenstr
#     print(stro)


# #编码输入
indexed_tokens = tokenizer.encode("Who is Li Jinhong ? Li Jinhong is a")

print(tokenizer.decode(indexed_tokens))

tokens_tensor = torch.tensor([indexed_tokens])  # 转换为张量

# 加载预训练模型(权重)
model = GPT2LMHeadModel.from_pretrained('gpt2')

#将模型设置为评估模式
model.eval()

tokens_tensor = tokens_tensor.to('cuda')
model.to('cuda')

# # 预测所有标记
# with torch.no_grad():
#     outputs = model(tokens_tensor)
#     predictions = outputs[0]

# # 得到预测的下一词
# predicted_index = torch.argmax(predictions[0, -1, :]).item()
# predicted_text = tokenizer.decode(indexed_tokens + [predicted_index])
# print(predicted_text)


#生成一段完整的话
stopids = tokenizer.convert_tokens_to_ids(["."])[0]
past = None
for i in range(100):
    with torch.no_grad():
        outputs = model(tokens_tensor, past_key_values=past)
    # print(outputs)
    logits = outputs['logits']
    past = outputs['past_key_values']
    
    token = torch.argmax(logits[..., -1, :])

    indexed_tokens += [token.tolist()]

    if stopids == token.tolist():
        break
    tokens_tensor = token.unsqueeze(0)
    
sequence = tokenizer.decode(indexed_tokens)

print(sequence)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/180760
推荐阅读
相关标签
  

闽ICP备14008679号