pytorch-bert实现简单问答系统

1.前言

注意区分两种BertForQuestionAnswering导入方式,上面一个是tensorflow,下面一个才是pytorch,反正我用第一种导入方式来加载模型时会报错。用pytorch的朋友,最好用第二种。

from transformers import BertForQuestionAnswering
from pytorch_pretrained_bert import BertForQuestionAnswering

2. 下载模型

2.1 模型下载地址:

bert模型
进入这个网页后,大家可以自行下载不同的模型,我下载的是:BERT-Base, Uncased: 12-layer, 768-hidden, 12-head, 110M parameters
pytorch-bert实现简单问答系统_第1张图片
我的保存路径是:K:\码云\yu-ling-QuestionAnswerBot-master\uncased_L-12_H-768_A-12\uncased_L-12_H-768_A-12 (记住这个路径,后面会涉及到它)
下载完后,解压,将会看到 5 个 文件:如下图
pytorch-bert实现简单问答系统_第2张图片

2.2 模型转化

上图这5个模型还不能直接被pytorch拿来使用,必须先进行转化,代码如下:

import shutil   # 用来复制文件

from pytorch_pretrained_bert import convert_tf_checkpoint_to_pytorch

BERT_MODEL_PATH =  r'K:\码云\yu-ling-QuestionAnswerBot-master\uncased_L-12_H-768_A-12\uncased_L-12_H-768_A-12/'"                      # 注意文件路径

WORK_DIR = r"K:\码云\yu-ling-QuestionAnswerBot-master\uncased_L_12"  # 转化后模型想要保存的路径,可以自定义

if __name__ == "__main__":
    convert_tf_checkpoint_to_pytorch.convert_tf_checkpoint_to_pytorch(
        BERT_MODEL_PATH + "bert_model.ckpt",
        BERT_MODEL_PATH + "bert_config.json",
        WORK_DIR + r'\pytorch_model.bin',    ## pytorch_model.bin 是我们最终想要的模型
    )
    shutil.copyfile(BERT_MODEL_PATH + 'bert_config.json', WORK_DIR + r'\bert_config.json')   # 把原来的'bert_config.json'文件拷贝到自定义目录下
    shutil.copyfile(BERT_MODEL_PATH + 'vocab.txt', WORK_DIR + r'\vocab.txt')   # 把原来的'vocab.txt'文件拷贝到自定义目录下

执行完上述代码可以发现自定义目录下有了3个我们最终想要的模型:
pytorch-bert实现简单问答系统_第3张图片

3. 问答demo

import torch
import os

from transformers import BertTokenizer    # 这个要从 transformers 导入
from pytorch_pretrained_bert import BertForQuestionAnswering # 从pytorch导入

bert_path = r"K:\码云\yu-ling-QuestionAnswerBot-master\uncased_L_12"
## 上面我们自定义的保留最后3个模型的路径
model = BertForQuestionAnswering.from_pretrained(bert_path)
tokenizer = BertTokenizer.from_pretrained(bert_path)
question, doc = "Who is Lyon" , "Lyon is a killer"
encoding = tokenizer.encode_plus(text = question,text_pair = doc,  verbose=False)
inputs = encoding['input_ids']  #Token embeddings
sentence_embedding = encoding['token_type_ids']  #Segment embeddings
tokens = tokenizer.convert_ids_to_tokens(inputs)  #input tokens
print("tokens: ", tokens)
>>>>>>>
tokens:  ['[CLS]', 'who', 'is', 'lyon', '[SEP]', 'lyon', 'is', 'a', 'killer', '[SEP]']
start_scores, end_scores = model(input_ids=torch.tensor([inputs]),
                                  token_type_ids=torch.tensor([sentence_embedding]))
start_index = torch.argmax(start_scores)
end_index = torch.argmax(end_scores)
#print("start_index:%d, end_index %d"%(start_index, end_index))
answer = ' '.join(tokens[start_index:end_index + 1])
print(answer) 
# 每次执行的结果不一致,这里因为模型没有经过训练,所以效果不好,输出结果不佳

4.总结

这篇文章只是为了记录如何在pytorch中跑通问答demo,后面训练过程可以在这个基础上进行优化 ><

你可能感兴趣的:(NLP自学笔记,nlp,python,深度学习)