置业问答分类器
参数设计及数据预处理
此实验中的数据为置业顾问与潜在顾客间的问答,首先熟悉新闻数据,格式为 “问句\t回答\t标签”,如下例所示:
首付多少 首套房 1
首付多少 首付办完 63万左右 1
首付多少 包含全部 0
价格最低多少卖? 没有说,但是估计少不到多少 1
价格最低多少卖? 3楼房子卖了 0
采光怎么样呢? 今天有时间吗 0
采光怎么样呢? 我拿好钥匙可以直接现场看的 0
采光怎么样呢? 好的 就考虑义堂这块小三室吗 0
此任务目标在于判断输入的一问一答是否是真正的问答对,1 表示是,0 表示否。由于 Bert 模型在预训练过程中本身会输入两个句子,判断是否为上下文关系,与当前任务目标一致,因此本项目可直接应用 Bert 预训练模型来进行微调。
由于本项目涉及到的参数较多,这里将所有参数整合到类 Config 中,主要涉及数据及模型相关的参数:
import torch
!pip install pytorch_transformers
from pytorch_transformers import BertModel, BertTokenizer
class Config(object):
"""配置参数"""
def __init__(self, dataset): # dataset指数据所在的文件名
self.model_name = 'bert'
self.train_path = dataset + '/train.txt' # 训练集
self.dev_path = dataset + '/valid.txt' # 验证集
self.test_path = dataset + '/test.txt' # 测试集
self.save_path = dataset + self.model_name + '.pkl' # 模型训练结果存储路径
self.device = torch.device(
'cuda' if torch.cuda.is_available() else 'cpu') # 设备
# 若超过 1000 batch 效果还没提升,则提前结束训练
self.require_improvement = 1000
self.class_list = [x.strip() for x in open(
dataset + '/class.txt').readlines()] # 类别名单
self.num_classes = len(self.class_list) # 类别数
self.n_epochs = 1 # epoch 数
self.batch_size = 38 # 一个 batch 的大小
# 每句话处理成的长度(短填长切)
self.pad_size = 20
self.learning_rate = 5e-5 # 学习率
self.bert_path = 'bert_wwm_pretrain' # 中文 Bert 预训练模型路径
self.tokenizer = BertTokenizer.from_pretrained(
self.bert_path) # 预训练模型的 tokenizer
self.hidden_size = 768 # 隐层大小
初始化参数类:
# 下载并解压数据集
!wget -nc "https://labfile.oss.aliyuncs.com/courses/3382/BeiKeData.zip"
!unzip "BeiKeData.zip"
# 下载并解压预训练模型
!wget -nc "https://labfile.oss.aliyuncs.com/courses/3382/bert_wwm_pretrain.zip"
!unzip "bert_wwm_pretrain.zip"
# 初始化参数类
config = Config("BeiKeData")
接下来为 Bert 模型准备输入数据,首先需要设置一些特殊符号(这是 Bert 在预训练过程中数据本身带有的符号):
# 分别为 padding 符号, bert 中分类标志符号以及句子隔开符号
PAD, CLS, SEP = '[PAD]', '[CLS]', '[SEP]'
对于输入 Bert 的一对数据(一问一答)而言,需要转化为三种输入数据,首先假设数据对为:
问句 1:首付多少
答句 2:首付办完63万左右
三大输入数据:
input_ids(文本 id 向量):添加标志符号,分词,并且截长补短(假设每个句子 pad_size = 5):‘[CLS] 首付 多少 [PAD] [SEP] 首付 办完 63 万 左右 [PAD] [SEP]’,接着将文本中的单词转化为对应的 id。
attenti