文本分类
首先你需要克隆本仓库,你可以在该链接 Git - 安装 Git (git-scm.com) 下载并安装 git,同时你还需要安装可克隆大文件的 Git Large File Storage ,最终你就可以使用如下命令克隆本仓库的内容:
git clone https://www.modelscope.cn/tiansz/text_classification.git
1 环境准备
1.1 Windows 环境搭建
- miniconda
- 更换 pip 源:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
- Visual Studio Code
- NVIDIA GeForce 驱动程序
- PyTorch
1.2 Ubantu 环境搭建
1.2.1 miniconda
同样的,我们在 miniconda 中下载对应版本的 linux 安装包,然后使用 bash 命令执行安装,之后按照提示操作即可。安装完成后我们还要启动环境变量:source ~/.bashrc
接着你可以根据需要创建一个虚拟环境:conda create -n py39 python=3.9
然后你可以进入刚刚创建的虚拟环境:source activate py39
跟 Windows 一样,你也可以使用相同的命令更换 pip 源
1.2.2 显卡驱动
sudo apt-get remove nvidia-*
ubuntu-drivers devices
sudo ubuntu-drivers autoinstall
nvidia-smi
1.2.3 CUDA
在 Windows 系统中我们并没有安装 CUDA,这是因为只有一些较为底层实现需要用到 CUDA,例如使用 C++ 时。而大多数开源项目都是基于 Linux 系统的,所以 Windows 并不需要安装 CUDA,同时 Pytorch 也已经安装了一些 CUDA 的支持。
那么 CUDA 的安装只需要按照 CUDA Toolkit 的提示安装即可,若你的电脑原本已经安装了低版本的 CUDA,那么你再安装新版 CUDA 时还要考虑如何切换不同版本的 CUDA
1.2.4 cuDNN
cuDNN 是 CUDA 的补充,它可以一定程度上提升训练和推理速度,可以在 cuDNN Archive | NVIDIA Developer 下载。
1.2.4 PyTorch
pytorch 的安装跟 Windows 系统一样,同时我建议使用 conda 安装
2 数据准备
首先需要有适用于分类任务的数据集,例如豆瓣电影评分,该任务需要将用户对电影的评论分为好评、差评或者其他。这份数据是我从 kaggle 网站下载的开源数据集。类似的网站还有 github 、魔搭社区 和 huggingface 等。以下是我获取到的数据以及它们的格式,你可以在 datasets/豆瓣电影评分/未清洗数据.csv
中找到它。
text_a |
---|
连奥创都知道整容要去韩国。 |
虽然从头打到尾,但是真的很无聊啊。 |
漫威粉勿喷,真感觉比第一部差了些火候。没想到奥创竟然这么弱,出来失望之极。。。 |
猩红女巫美哭了,为何要弄我大快银 嘤嘤嘤 |
虽然从头打到尾,但是真的很无聊啊。 |
3 数据清洗
在拿到一份数据时,需要将数据集中的重复数据剔除,同时删除没有意义的句子,例如纯英文或者纯数字的句子。
python process/clean.py --origin_path datasets/豆瓣电影评分/未清洗数据.csv \
--clean_path datasets/豆瓣电影评分/已清洗数据.csv
运行完以上脚本后,你就会在 datasets/豆瓣电影评分/已清洗数据.csv
中找到类似如下格式的数据:
text_a |
---|
连奥创都知道整容要去韩国。 |
虽然从头打到尾,但是真的很无聊啊。 |
漫威粉勿喷,真感觉比第一部差了些火候。没想到奥创竟然这么弱,出来失望之极。。。 |
猩红女巫美哭了,为何要弄我大快银 嘤嘤嘤 |
可以看到在清洗时确实将重复的句子剔除了,这可以减少我们后续标注数据的工作量,同时确保模型学习时的多样性。
4 文本聚类
虽然目前很多开源数据集都已经进行了人工打标,但在实际处理业务时,面对的却是没有打标过的数据。在拿到数据时,首先需要确定这份数据有多少个类别,我建议先使用文本聚类对数据进行探索,找到有可能的分类。
python process/cluster.py --clean_path datasets/豆瓣电影评分/已清洗数据.csv \
--cluster_path datasets/豆瓣电影评分/已聚类数据.csv \
--uncluster_path datasets/豆瓣电影评分/未聚类数据.csv \
--batch_size 64
运行完以上脚本后,你将在 datasets/豆瓣电影评分/未聚类数据.csv
中找到类似如下格式的数据:
text_a | label |
---|---|
呵呵 | 0 |
连奥创都知道整容要去韩国。 | 0 |
失望失望太失望 | 1 |
一顿瞎打 | 1 |
钢铁流星拳拳拳拳拳拳 | 1 |
在使用聚类脚本时,我们需要人工在命令行中确认当前的簇能否形成一个类别,并将当前可形成一个类别的数据剪切出来,让剩余的数据继续聚类,这样我们就可以找到当前这份数据中有可能形成的类别的数据集。后续我们还需要不断细化类别,但聚类工具确确实实帮助我们提升了标注的效率,并且当数据集比较大时格外明显。
5 数据标注
我们确定好类别标准之后就要进行打标了,而打标工具只需要使用 excel 即可。在以往我也使用过专业的标注工具,但远不如使用 excel 方便快捷,这是因为它是所有人都或多或少使用过的工具,所以还是比较熟悉的。若使用专业标注工具,就要面对不熟悉的英文,同时它们还没有 excel 那么多强大功能。而对于文本分类的标注而言,最重要的是理解每个类别的含义才能正确做出标注,所以数据标注也是一项需要大量思考的工作,你可以在 datasets/豆瓣电影评分/文本分类数据.csv
中找到类似如下格式的标注后的数据:
text_a | label |
---|---|
奥创设定太差。 | 差评 |
连奥创都知道整容要去韩国。 | 其他 |
我是男脑残粉 所以怎么都好看 | 好评 |
哪个保证一刀不剪的,不是剪了好几刀吗! | 差评 |
我。。。居然。。。没看懂。。。只觉得三个光束打奥创好燃,以及快银也很顺眼而且口音好喜感 | 好评 |
6 增量预训练
目前分类效果较好的模型都是预训练模型,它们会在大量数据训练出一个模型,然后再用这个模型用于分类任务。听起来可能复杂,但总之我们会用该模型来学习句子之间的语义,让模型懂得句子之间的区别。因此我们会用预训练模型再在我们自己的数据上进行增量预训练,用于提升模型的效果。
python process/preprocess.py --corpus_path datasets/豆瓣电影评分/语料库.txt \
--dataset_path datasets/豆瓣电影评分/dataset.pt
python pretrain.py --dataset_path datasets/豆瓣电影评分/dataset.pt \
--pretrained_model_path models/roberta_wwm_base/pretrain_model.bin \
--output_model_path models/new_pretrain_model.bin \
--world_size 1 --gpu_ranks 0 \
--total_steps 100 --save_checkpoint_steps 100 \
--batch_size 32 \
--data_processor mlm --target mlm
7 模型微调
首先需要将数据拆分成训练集和开发集,其中训练集就是模型需要学习的数据了,而开发集就是让模型在开发集来验证当前的拟合效果,所以开发集有时也称为验证集。如果以往接触过相关知识的同学可能要问我为什么不设置测试集,这是因为测试集虽然确实能判断当前模型是否存在过拟合的情况,但由于测试集比较小,所以也无法覆盖所有应用场景,因此不再划分测试集。
python process/split.py --label_path datasets/豆瓣电影评分/文本分类数据.csv \
--train_path datasets/豆瓣电影评分/train.tsv \
--dev_path datasets/豆瓣电影评分/dev.tsv \
--label2id_path datasets/豆瓣电影评分/label2id.json \
--id2label_path datasets/豆瓣电影评分/id2label.json
得到拆分的数据后我们终于可以来训练分类模型了:
python finetune.py --pretrained_model_path models/new_pretrain_model.bin \
--train_path datasets/豆瓣电影评分/train.tsv \
--dev_path datasets/豆瓣电影评分/dev.tsv \
--epochs_num 50 --batch_size 32
在进行模型训练时,轮次可以设置的大一些,因为不论你训练多少轮次,代码都会保存最优的模型。
8 模型推理
我们在训练完模型后,还需要不断地迭代模型,所以需要在大量的未标注数据上进行推理。同时在推理完之后需要对推理后的数据重新进行标注,用以提升模型的准确率和泛化性。
python inference.py --load_model_path models/finetune_model.bin \
--test_path datasets/豆瓣电影评分/test_nolabel.tsv \
--prediction_path datasets/豆瓣电影评分/prediction.tsv \
--labels_num 3 --batch_size 32
不过最终得到的推理结果是保存在 tsv 格式的文件中,为了更方便标注,后续需要将推理结果转换为 xlsx 文件:
python process/merge.py --test_path datasets/豆瓣电影评分/test_nolabel.tsv \
--prediction_path datasets/豆瓣电影评分/prediction.tsv \
--mapping_path datasets/豆瓣电影评分/label2id.json \
--merge_path datasets/豆瓣电影评分/合并语料.xlsx
9 模型部署
首先需要将模型转换为huggingface格式的模型:
python process/uer2hf.py --input_model_path models/finetune_model.bin \
--output_model_path models/classification_model/pytorch_model.bin
同时为了加速该模型的推理效果,我们还要对模型进行量化处理:
python process/quantization.py --model_path models/classification_model \
--model_path_q models/classification_model_q
在以上的流程中,数据标注、模型训练和模型推理是不断循环进行的。当你得到了一个迭代好的模型后,就可以将模型进行部署了,这里我们就需要运行 python 代码了,你可以在 server.py
中找到它。
>>> from transformers import AutoModelForSequenceClassification, AutoTokenizer, pipeline
>>> model = AutoModelForSequenceClassification.from_pretrained("models/classification_model_q")
>>> tokenizer = AutoTokenizer.from_pretrained("models/classification_model_q")
>>> pipe = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer, device_map="cuda")
>>> print(pipe("奥创弱爆了弱爆了弱爆了啊!!!!!!"))
[{'label': '差评', 'score': 0.9795011878013611}]
>>> print(pipe("我就问一句:老万是被炸死的老万造吗?"))
[{'label': '其他', 'score': 0.9226566553115845}]
>>> print(pipe("我。。。居然。。。没看懂。。。只觉得三个光束打奥创好燃,以及快银也很顺眼而且口音好喜感"))
[{'label': '好评', 'score': 0.8346151113510132}]
10 未来展望
以上都是介绍一些工具的使用,后续会计划出更多自然语言处理或其他有趣内容的总结,同时我还考虑阅读经典的论文,以理解更深层的原理,甚至后续自己动手搭建模型。
11 参考资料
GitHub - dbiir/UER-py: Open Source Pre-training Model Framework in PyTorch & Pre-trained Model Zoo
Ubuntu 安装 conda - 知乎 (zhihu.com)
评论