🚩🚩🚩Hugging Face 实战系列 总目录
有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传
上篇内容:
中篇内容:
10、评估标准
接下来我们需要制作评估标准了,把预测值和标签拿到之后,可以自己定义评估方法是什么,更多的时候是用现成的,这里就是用这4个:
- precision:精确率
- recall:召回率
- f1:F1分数
- accuracy:准确率
对机器学习的指标不了解的同学,可以参考这篇文章,有比较详细的解释:
11、训练
checkpoint = 'bert-base-chinese'
num_train_epochs = 1000
per_device_train_batch_size=8
per_device_eval_batch_size=8
- 第一行:训练完成的时候,需要保存模型,指定保存的模型是什么
- 第二行:训练的迭代次数
- 第三行:训练的batch_size
- 第四行:验证的batch_size
指定训练的参数
training_args = TrainingArguments(
output_dir='./output', # 输入路径
num_train_epochs=num_train_epochs, # 训练epoch数量
per_device_train_batch_size=per_device_train_batch_size, # 每个GPU的BATCH
per_device_eval_batch_size=per_device_eval_batch_size,
warmup_steps=500, # warmup次数
weight_decay=0.01, # 限制权重的大小
logging_dir='./logs',
logging_steps=10,
save_strategy='steps',
save_steps=1000,
save_total_limit=1,
evaluation_strategy='steps',
eval_steps=1000
)
- output:模型保存的路径
- num_train_epochs:训练epoch数量
- per_device_train_batch_size:每个GPU的BATCH
- per_device_eval_batch_size:验证集的
- warmup_steps:warmup次数,预热次数
- weight_decay:限制权重的大小
- logging_dir:日志位置
- logging_steps:pycharm中每10次迭代打印一次结果
- save_strategy:按照什么样的方式保存模型
- save_steps:按照每迭代一千次保存模型
- save_total_limit:总共保存模型次数(次数达到了就删除最开始保存的一个)
- evaluation_strategy:按照什么样的方式做验证集
- eval_steps:按照每迭代一千次做验证集
把前面配置好的参数传进去:
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=val_dataset,
compute_metrics=compute_metrics
)
- model:模型
- args:参数
- train_dataset:训练集
- eval_dataset:验证集
- compute_metrics:评估标准
训练,评估:
trainer.train()
trainer.evaluate()
为了保险起见,再保存一次模型:
model.save_pretrained("./checkpoint/model/%s-%sepoch" % (checkpoint, num_train_epochs))
12、训练过程
12.1训练过程
数据集构建好,指定评估标注,参数全部配置了,先训练,再跑一次评估,最后把模型再保存一次。
现在可以实际去训练这个模型了,第一次启动需要加载tokenizer,需要加载模型,这些是比较慢的,你自己第一次启动的时候是需要下载的,训练过程:
可以看出迭代还是比较快的,损失下降的也挺快的,因为数据量小啊,我已经听到我的卡嗡嗡响了。
eporch也很少,才两千个,我这个4080几分钟就能跑完了。
这个就是我们本地保存的pytorch模型:
使用的时候,就可以加载这个模型进行实际的应用。
那怎么使用呢?
12.2模型使用
模型使用部分的代码在demoNer.py文件中。
随便选择一个文本:
input_str = '2009年高考在北京的报名费是2009元'
看看预测结果:
预测的结果:
- 2009年是一个year
- 高考是一个exam
- 北京是一个地点
- 009是一个考试
前面三个对了,最后一个错了。
预测的结果也和实际标注的有点不太一样,比如将高考和北京预测成两个了。但是可以知道的是,十几个数据就有效果了。
其实并不是我们的数据厉害,还是因为我们有一个强大的语言模型。
现在的NLP拼的已经不是数据了,也不是谁的下游任务是怎么样的,而是谁有一个强大的语言模型。谁有一个强大的语言模型,谁的下游任务就做的非常好。
Hugging Face是什么呢,其实是一个江湖,在这个江湖谁都想证明自己,这么多机构,这么多学者,大家都希望自己的模型自己的论文是最牛的,大家都来引用我的论文。所以大家都会大量开源这些东西,这就造成了这个领域极大的发展。对于我们普通的算法工程师我可以直接拿来就用了。
比如我们这篇文章用的台湾那家机构的模型,在维基百科的介绍,人家用了好几千个g数据训练得到的,特别特别大,训练时间都是很长的。
但是对于我们来说,就是一行代码:
model = AutoModelForTokenClassification.from_pretrained('ckiplab/albert-base-chinese-ner',num_labels=7,
ignore_mismatched_sizes=True,
id2label=id2tag,
label2id=tag2id
)
接下来还是debug一下demoNer.py的代码吧
13、demo测试
给input_str这部分打上断点:
继续运行,自己写一个函数做分词:
将一个文本,分词一个字一个字,第一步做一个分字符的事情。接下来继续用tokenizer将文本转换为id:
这个时候的tokenizer是不变的,继续做input_ids,offset在我们输出的时候也是需要的:
offset和预测没什么关系,只不过等下在我们输出的时候会用到,将offset剔除:
模型前向传播走一次:
得到输出结果,将输出结果经过一个softmax,因为在刚才的模型只是经过一个全连接,没有经过softmax:
这里的list有20个,表示token有20个,7是每个token做一个7分类,每个类别都有一个概率值,得到的预测值是7个类别中哪个概率最高的那个id。
那最后怎么把预测值转换成结果打印出来呢?
这个时候就要把前面的offset拿出来了,遍历所有文本,如果是特殊字符就continue,如果不是就用id2label进行映射,比如2预测成B-year
接下来是一些评分策略以及词的起始位置和终止位置的记录。
最后将识别的结果打印出来:
score就是评分,后面的start和end就是起始位置终止位置。
14、相关bug记录
待更新
上篇内容:
中篇内容: