本代码推荐使用百度AIStudio平台https://aistudio.baidu.com/aistudio/index进行训练,提供免费的Tesla V100资源供学习者使用
环境为Python3.7、PaddlePaddle 1.8.4、PaddleHub 1.8.2
为了正常运行代码,请先下载提前下载好数据集https://aistudio.baidu.com/aistudio/datasetdetail/61815
首先,安装Paddlehub 1.8.2版本
pip install paddlehub==1.8.2
将下载好的数据集放在data文件夹中,并创建run.py文件
‘
将下列代码复制到run.py文件夹中
#导入模块,使用pip指令安装大于1.8.2版本,避免出现错误
import paddlehub as hub
from paddlehub.dataset.base_nlp_dataset import BaseNLPDataset
import os
class TextClassification(BaseNLPDataset):
# 句对分类数据集
def __init__(self, dataset_dir):
self.dataset_dir = dataset_dir #数据集存储文件夹路径,通过函数传入,通过传入不同数据集文件夹,来使用不同数据集
super(TextClassification, self).__init__(
base_path=self.dataset_dir,
train_file="train.tsv", #训练集文件名称
dev_file="train.tsv", #如果包含dev验证集,此处命名为dev.tsv
predict_file="test.tsv", #测试集文件名称
train_file_with_header=False,
dev_file_with_header=False,
predict_file_with_header=False,
label_list=["0", "1"]) #标签格式类别
# 句对分类
# 数据集设置,通过更换数据集文件夹更换数据集
dataset_dir = 'data' #数据集保存位置
dataset_name = dataset_dir.split('/')[-1]
# 加载语义模型,可更换其他语义模型比如bert、robert等
module = hub.Module(name="ernie") #模型名称,具体不同模型分析请参见另一篇博客
module_name_simple='ERNIE' #保存的文件名称
max_seq_len_num=256 #最大输入长度
# 定义数据集
dataset = TextClassification(dataset_dir) #载入数据集
# 定义数据读取器
reader = hub.reader.ClassifyReader(
dataset=dataset, #数据集
vocab_path=module.get_vocab_path(), #词表
max_seq_len=max_seq_len_num,
do_lower_case=True, #英文文本是否将大写字母进行小写转换
sp_model_path=module.get_spm_path(),
word_dict_path=module.get_word_dict_path()
)
# 设置优化策略
strategy = hub.AdamWeightDecayStrategy(
learning_rate=3e-5, #学习率
lr_scheduler="linear_decay", #学习策略
warmup_proportion=0.1, #慢热学习的比例
weight_decay=0.01, #权重衰减
optimizer_name="adam" #优化器
)
# 设置训练参数
config = hub.RunConfig(
log_interval=20, #运行日志保存步数
eval_interval=1000,#验证步数
use_pyreader=True,
use_data_parallel=True,
save_ckpt_interval=6740, #checkpoint模型保存步数,保存好的模型用于断点续训练
use_cuda=True,
checkpoint_dir='./outputs/{}_model'.format(module_name_simple), #checkpoint保存文件名
num_epoch=10, #epoch轮数,该数字代表“整个训练集集”的重复训练的次数
batch_size=32, #batch_size代表每轮载入到内存的“样本数目”
strategy=strategy)
# 模型上下文设置
inputs, outputs, program = module.context(
trainable=True,
max_seq_len=256
)
# 语义模型输出
sequence_output = outputs["sequence_output"]
# 模型输入
feed_list = [
inputs["input_ids"].name,
inputs["position_ids"].name,
inputs["segment_ids"].name,
inputs["input_mask"].name,
]
# 训练任务
cls_task = hub.TextClassifierTask(
num_classes=dataset.num_labels, #分类数目,此处是二分类问题,可以修改定义为[0,1,2]这样的三分类问题
data_reader=reader,
feed_list=feed_list,
token_feature=sequence_output,
config=config,
network='bilstm',
metrics_choices=['acc'])
# 开始训练
run_states = cls_task.finetune_and_eval()
# 开始预测
def get_testset(dataset_dir):
datas = []
with open(os.path.join(dataset_dir, 'test.tsv'), 'r', encoding='UTF-8') as f:
for line in f:
result=line.split('\t')[:2]
datas.append(result)
return datas
# 句对分类
dataset_dir = 'data' #测试集路径
dataset_name = dataset_dir.split('/')[-1] #获取测试集名称
testset = get_testset(dataset_dir) #获取测试集
# 开始对测试集预测
results = cls_task.predict(
data=testset, #输入测试集
label_list=dataset.get_labels(), #获取标签格式
return_result=True,
accelerate_mode=False)
#将预测结果输出在result.tsv文件中
if not os.path.exists('./pre_{}/'.format(module_name_simple)): #如果不存在则创建文件
os.makedirs('./pre_{}/'.format(module_name_simple))
with open('./pre_{}/result.tsv'.format(module_name_simple), 'w', encoding='UTF-8') as f:
f.write('index\tprediction\n')
for i, result in enumerate(results):
f.write('%d\t%s\n' % (i, result)) #写入结果