文章目录
1. 项目思路
上周对整个项目的完成思路进行了进一步的明确和梳理,决定采用先疑问词分类,后根据分类获得的疑问词问题生成的思路进行。
完整实现思路如下图:
2. 当前成果总结及下一步计划
2.1 当前成果总结
目前已经阅读问题生成方向的综述论文,并且在查阅大量资料后对问题的解决有了一定的思路。精读了Let Me Know What to Ask: Interrogative-Word-Aware Question Generation一文,认为本篇文章的思想很新颖值得效仿,计划大体思路上按照该文思路进行。
2.2 下一步计划
- 项目基于百度的DuReader数据集进行,通过分析数据集发现数据集还需要进行数据清洗、分词等预处理工作才能使用,因此计划任务之一为完成数据集的预处理工作。
- 此外,在查阅资料的基础上发现,BERT不适宜做生成问题的预训练模型,因而决定使用uniLM模型,第二个任务就是学习uniLM模型,并且开始完成疑问词分类任务
3. 疑问词分类
3.1 具体思路
使用[ANS]
特殊标记符标记答案,使得篇章内容与答案有所区分。将处理过的文本按输入Bert
模型中进行训练,抽取其中[CLS]
标记对应的词向量用于下一步的操作。这里认为[CLS]
词向量能够表示本段文字的语义信息。
对答案文本进行命名实体识别(NER),经研究标明,疑问词与答案的实体类型有很强的关联。因此将[CLS]
与答案的实体类型一起作为的输入,通过前馈神经网络(分类器)获得疑问词的分类。
3.2 [CLS]词向量的获取
处理数据
本实验使用Dureader数据集,数据集的层次如下图所示。
因此对数据集进行下述处理,并加载到 数据加载器DataLoader中。
#初始化分词器
tokenizer=BertTokenizer.from_pretrained(bert_path)
#添加特殊token[ANS]来标记答案区域
tokenizer.add_special_tokens({'additional_special_tokens':["[ANS]"]})
#预处理数据集
input_ids,input_masks,input_types,=[],[],[]
label=[]
maxlen=300
with open("testCode.json",'r',encoding="utf-8")as f:
dataset= [json.loads(s) for s in f.readlines()]
for data in dataset:
documents=data['documents']
paragraph=selectAndJointDoc(documents)
answers=" ".join(data['answers'])
print(type(paragraph),type(answers))
encode_dict=tokenizer.encode_plus(text=paragraph+"[ANS]"+answers+"[ANS]",max_length=maxlen,padding="max_length",truncation=True)
input_ids.append(encode_dict['input_ids'])
input_types.append(encode_dict['token_type_ids'])
input_masks.append(encode_dict['attention_mask'])
print(type(input_ids),type(input_masks),type(input_types))
input_ids, input_types, input_masks = np.array(input_ids), np.array(input_types), np.array(input_masks)
print(input_ids.shape, input_types.shape, input_masks.shape)
BATCH_SIZE=2
train_data=TensorDataset(torch.LongTensor(input_ids),torch.LongTensor(input_masks),torch.LongTensor(input_types))
train_sampler=RandomSampler(train_data)
train_loader=DataLoader(train_data,sampler=train_sampler,batch_size=BATCH_SIZE)
DataLoader数据加载器: 结合了数据集和取样器,pytorch会采取一系列的操作将数据拷贝到GPU多线程完成,能够加速运算过程;在训练是使用该函数,会将训练的data分为多个batch,每次抛出一个batch,直至将所有数据抛出。
定义并实例化Bert模型
#定义bert模型
class Bert_Model(nn.Module):
def __init__(self,bert_path):
super(Bert_Model,self).__init__()
self.config=BertConfig.from_pretrained(bert_path)
self.bert=BertModel.from_pretrained(bert_path)
#实例化bert模型
print(type(train_loader))
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
EPOCHS = 2
model = BertModel.from_pretrained(bert_path)
获得[CLS]
Bert模型的输出:
last_hidden_state
:(tensor)模型最后一层的隐藏状态序列,整个句子每一个token的向量表示。pooler_output
:(tensor)[CLS]表示。
cls=output.last_hidden_state
4. Bert模型的相关学习
4.1 Bert模型概述及部分学习笔记
Bert模型是基于Transformer的双向编码器表征,当处理一个token的时候,能够考虑前后文本的信息,从而获得上下文语义。
- bert有两个模型,base和large
- Bert的输入表征
- Bert各个部分的作用
4.2 学习资料汇总
- BERT模型学习与分析
- 图解BERT模型:从零开始构建BERT
- 9102年了,再不会用bert就out啦,看这篇基于pytorch的bert文本分类的完整代码
- 汉语自然语言处理-从零解读碾压循环神经网络的transformer模型
5. Transformers库学习
5.1 Transformers库简介
Transformers库是一个比较新的项目,当中已经收录了不少arxiv上2020年发表的论文的模型代码,通过这个库可以非常轻松的调取最先进的,包括BERT在内的深度学习模型(以自然语言处理领域的模型为主),并且可以使用PyTorch或TensorFlow 2.x进行继续训练或微调。
5.2 学习资料
Transformers库官方网站写的很详细,参照官网文档进行一系列的学习。
6. 参考资料
Let Me Know What to Ask: Interrogative-Word-Aware Question Generation