LUSE: 无监督数据预训练短文本编码模型
LUSE: 无监督数据预训练短文本编码模型
1 前言
本博文本应写之前立的Flag:基于加密技术编译一个自己的Python解释器,经过半个多月尝试已经成功,但考虑到安全性问题就不公开了,有兴趣的朋友私聊讨论吧。
从本篇博客开始,本人将转化写作模式,由话痨模式转为极简模式,力求三言两语让各位看的明白。
2 工作简介
受到MOCO和SimCSE的启发, 基于自监督,使用海量无监督数据(nlp_chinese_corpus),预训练了一个专门用于短文本表征的编码器。该编码器在分类任务尤其是短文本相似度任务上效果超过同级别BERT模型。该预训练模型暂且叫LUSE.
本次实验结果是仅在预训练0.1轮(10万步)情况下得到的,完全训练后会得到更强的效果。
三层预训练模型(torch)下载地址:
百度网盘:https://pan.baidu.com/s/1Do3ojovAe7VviSXdsk4mQQ 提取码:luse
和彩云(不限速): https://caiyun.139.com/m/i?1A5ChPLNDFGuW 提取码:tFK0
代码地址: https://github.com/DunZhang/LUSE
预处理后的nlp_chinese_corpus下载地址: https://pan.baidu.com/s/11ddgvZ7QAbIlliJgUiau9g 提取码:luse
使用方法:和正常BERT一样加载使用,使用CLS作为句表征。text_vec = transformers.BertModel()(input_id,attention_mask,token_type_ids)[1]
3 算法详情
算法伪代码如下:
Input: sens: List[str], sen_encoder: torch.nn.Module
Output: None
aug_sens = data_augment(sens) # 数据增强, 每个句子均会增强固定数量相似句做为正例,剩余所有句子则为负例
sens_vecs = sen_encoder.forward(sens+aug_sens) # 将所有句子编码为句向量
scores = compute_score(sens_vecs) # 计算所有向量间的相似度值
loss = multi_positive_multi_negative_func(scores) # 基于相似度值计算loss
update(sen_encoder,loss) # 更新模型权重
3.1 数据增强
本人将数据增强分为两类, text-level和vector-level.
text-level:字词句层面的数据增强, 本算法使用EDA
vector-level:句编码层面的数据增强,可参考图像, 本算法只使用随机裁剪,对应NLP操作为置0,即dropout操作, SimCSE就是该方法. CV与NLP的完美融合!!!
3.2 损失函数
对于一个句子,自身和其增强而来的句子为正例,其他句子及其增强为负例. 优化目标为让这些正例的概率最高,如果有n个正例,那么希望这n个正例概率都很高,那就索性平分概率值1得了,让其他负例概率都为0, 这其实就是均值不等式. 详细推导公式和代码实现见本人博客:一种基于均值不等式的Listwise损失函数
3.3 预训练数据
预训练数据为brightmart开源的nlp_chinese_corpus. 本人只做简单分句和去除空白字符两种清洗操作.然后将所有语料库所有句子完全打散作为训练集.最终约有1.1亿个句子
3.4 训练细节
batch_size为128, 每个句子增强8个相似问(4个EDA, 4个dropout),因此每个句子有9(8+1)个正例和(9*128-9)个负例,这变相扩大了batch_size, 也正是此原因, 本人未使用MOCO的负例队列来增大batch_size. 忍不住再夸一波MOCO负例队列的精巧设计,何凯明yyds.
优化器为Adam, 学习率5e-5,最大长度64(本模型只考虑短文本),短文本表征的pooling_mode为CLS向量,有兴趣的可以使用SentenceBERT, BERT-Whitening 和 SimCSE的pooling方式, 本开源项目已经提供代码.
GPU是租了一块RTX3090,训练了两天两夜,约12万步,即1500万个句子,离1.1亿差的远了,更别提多epoch了. 中途还遇上服务器宕机,不得不加载以前的模型重新训练, 真是倒了血霉. 共花了约150块大洋,要是训练完一轮非得倾家荡产不可,这就是只预训练三层模型且0.1轮的原因.
3.5 小技巧:同义词搜索加速
EDA里最耗时操作为选取同义词, 本人使用腾讯800万词向量, 使用gensim选取同义词速度比训练还慢, 对于穷逼是无法接受.
解决方案: 预缓存同义词词典, 计算同义词时不要用gensim库, 使用faiss或milvus向量加速库, 本人在不使用GPU的情况下仅耗时一夜就完成了缓存. 句向量加速指南可以看我的博客:[milvus和faiss安装及其使用教程]. 或者直接用我计算好的也行,本人能开源的都开源了,就是希望有算力的同志把我的方法跑一波.
4 微调验证
作为预训练模型,总需要微调来证明效果的.
4.1 数据集
4个分类数据集:
数据集 | #Trian | #Dev | 任务类型 | 参考链接 |
---|---|---|---|---|
NLPCC情感分类 | 8000 | 2000 | 2分类 | https://www.luge.ai/ |
微博情感分类 | 99988 | 20000 | 2分类 | https://github.com/SophonPlus/ChineseNlpCorpus |
购物网站评论情感分类 | 52774 | 10000 | 2分类 | https://github.com/SophonPlus/ChineseNlpCorpus |
今日头条新闻分类 | 53360 | 10000 | 15分类 | https://github.com/CLUEbenchmark/CLUE |
6个相似度数据集:
数据集 | #Train | #Dev | 参考链接 |
---|---|---|---|
LCQMC(哈工大通用聊天数据集) | 238766 | 8802 | http://icrc.hitsz.edu.cn/Article/show/171.html |
ADAT(基于Adversarial Attack的问题等价性判别比赛数据集) | 36210 | 9027 | / |
ATEC(蚂蚁金服相似度数据集) | 81981 | 20496 | / |
CHIP(平安医疗中文的疾病问答数据) | 16000 | 4000 | / |
COVID(新冠句对) | 8747 | 2001 | https://aistudio.baidu.com/aistudio/datasetdetail/48492 |
CCKS(微众银行智能客服问句匹配大赛) | 80000 | 20000 | / |
没有链接的数据集可以自行搜索, 由于微调数据集可能设计到一些版权问题, 开源项目里就不再放出.
为了简化操作只使用dev评估.
4.2 微调方法
对于分类数据集,使用交叉熵微调
对于相似度数据集,由于预训练模型为短文本编码器, 将两个句子一起输入做0/1分类是不合适的. 做法是单独对两个句子进行编码,计算余弦相似度并归一化至0-1之间作为概率值, 然后最大似然求解.
同时考虑到低计算资源情况, 训练又分为全部微调和固定bert训练上层神经网络两种.
4.3 评价指标
分类数据集使用ACC和F1
相似度数据集使用Spearman相关系数
4.4 基线模型
哈工大的RBT3
4.4 实验结果
分类实验结果(ACC / F1):
NLPCC情感分类 | 微博情感分类 | 购物网站评论情感分类 | 今日头条新闻分类 | |
---|---|---|---|---|
ACC / F1 | ACC / F1 | ACC / F1 | ACC / F1 | |
RBT3-TrainBERT | 0.786 / 0.784 | 0.979 / 0.979 | 0.945 / 0.945 | 0.554 / 0.538 |
LUSE-TrainBERT | 0.791 / 0.789 | 0.979 / 0.979 | 0.944 / 0.944 | 0.556 / 0.541 |
RBT3-FreezeBERT | 0.720 / 0.720 | 0.864 / 0.864 | 0.873 / 0.873 | 0.445 / 0.416 |
LUSE-FreezeBERT | 0.740 / 0.740 | 0.804 / 0.804 | 0.888 / 0.888 | 0.482 / 0.460 |
文本相似度实验结果(Spearman):
ADAT | ATEC | CCKS微众银行 | CHIP | COVID | LCQMC | |
---|---|---|---|---|---|---|
RBT3-TrainBERT | 0.633 | 0.086 | 0.785 | 0.624 | 0.703 | 0.642 |
LUSE-TrainBERT | 0.636 | 0.210 | 0.796 | 0.634 | 0.692 | 0.650 |
RBT3-FreezeBERT | 0498 | 0.070 | 0.432 | 0.308 | 0.507 | 0.280 |
LUSE-FreezeBERT | 0.556 | 0.200 | 0.675 | 0.527 | 0.653 | 0.497 |
行名解释, RBT3代表使用的是哈工大的RBT3模型,LUSE代表本人预训练的模型.
TrainBERT代表微调时整体训练耗时但效果好, FreezeBERT代表冻结BERT训练上层神经网络,省时省力但效果差些.
实验结论: 专门针对短文本编码预训练的模型确实可以取得更好的效果, 尤其是在短文本相似度任务上
5 总结
LUSE模型是一个优缺点非常明显的模型, 成也预训练任务败也预训练任务.
LUSE模型在需要进行短文本编码的任务上能取得较好的效果,即便只训练了0.1轮,效果也很明显.
但是缺点同样突出, 由于其预训练任务, 使其适用场景变得很小, 在其他任务上LUSE怕是无能为力了, 估计在二分类的短文本相似度任务上,LUSE都未必效果好,后续可以做实验看下.
即便如此, 本人构想还是对的,基于无监督数据, 借助对比学习, 还是可以预训练出优质文本编码模型的, 挺好奇为什么SimCSE的作者不预训练一个文本编码模型.
图像的好多东西都可以借鉴到NLP中,NLPer需要定期关注图像领域的最新进展.
6 TODOList
- MOCO负例队列或许可以一试
- 能否基于GAN做vector-level的数据增强
- 使用百GB级别数据预训练一次大模型
- 和MLM-Loss做交叉训练
- 文本相似度微调模型可以尝试Sentence-BERT的方式
- alignment和uniformity验证无监督句向量效果
7 FAQ
Q: 为什么就放出了一个没完全训练的小模型?
A: 穷
Q: 后续还会放出新的预训练模型吗?
A: 会的, 一定会的. 该预训练任务本人会一直尝试下去的, 但是要等到显卡回落到正常价格之后(万恶的虚拟货币)
Q: 与simbert以及RoFormer-sim相比如何?
A: 没有可比性,有监督对无监督就是降维打击. 中文数据任务完全可以用SimBERT替代LUSE预训练模型.
Q:接上一问题,那LUSE预训练模型的意义何在呢?
A:如果没有有监督数据怎么办?如果数据脱敏了怎么办? 本文主要探索无监督数据预训练短文本编码模型的可能性.
Q:EDA和dropout数据增强,那个更有用?
A:没钱做消融实验了,中庸了, 两个都用. 个人猜测两个都起正面作用, dropout可能会更强些, 毕竟simcse论文效果很好
Q:为什么实验结果的好多F1和ACC一样了?
A:其实不一样,只是取了前三位恰好一样罢了
8 致谢
特别感谢 数据集nlp_chinese_corpus, 没有数据集一切免谈.
还要感谢SimCSE和MOCO,正是这两篇论文激发本人尝试LUSE的兴致.
LUSE: 无监督数据预训练短文本编码模型的更多相关文章
- 深度学习tensorflow实战笔记 用预训练好的VGG-16模型提取图像特征
1.首先就要下载模型结构 首先要做的就是下载训练好的模型结构和预训练好的模型,结构地址是:点击打开链接 模型结构如下: 文件test_vgg16.py可以用于提取特征.其中vgg16.npy是需要单独 ...
- Machine Learning With Spark学习笔记(在10万电影数据上训练、使用推荐模型)
我们如今開始训练模型,还输入參数例如以下: rank:ALS中因子的个数.通常来说越大越好,可是对内存占用率有直接影响,通常rank在10到200之间. iterations:迭代次数,每次迭代都会降 ...
- 【转】有监督训练 & 无监督训练
原文链接:http://m.blog.csdn.net/article/details?id=49591213 1. 前言 在学习深度学习的过程中,主要参考了四份资料: 台湾大学的机器学习技法公开课: ...
- 转:Deep learning系列(十五)有监督和无监督训练
http://m.blog.csdn.net/article/details?id=49591213 1. 前言 在学习深度学习的过程中,主要参考了四份资料: 台湾大学的机器学习技法公开课: Andr ...
- 预训练语言模型的前世今生 - 从Word Embedding到BERT
预训练语言模型的前世今生 - 从Word Embedding到BERT 本篇文章共 24619 个词,一个字一个字手码的不容易,转载请标明出处:预训练语言模型的前世今生 - 从Word Embeddi ...
- Supervised pre-trainning有监督预训练
如我们有一个分类任务,数据库很小,这时还是需要通过预训练来避免深度模型的过拟合问题的,只不过预训练是通过在一个大的数据库上(比如imagenet),通过有监督的训练来完成的.这种有监督预训练加小的数据 ...
- 从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史(转载)
转载 https://zhuanlan.zhihu.com/p/49271699 首发于深度学习前沿笔记 写文章 从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史 张 ...
- 将句子表示为向量(上):无监督句子表示学习(sentence embedding)
1. 引言 word embedding技术如word2vec,glove等已经广泛应用于NLP,极大地推动了NLP的发展.既然词可以embedding,句子也应该可以(其实,万物皆可embeddin ...
- zz从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史
从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史 Bert最近很火,应该是最近最火爆的AI进展,网上的评价很高,那么Bert值得这么高的评价吗?我个人判断是值得.那为什么 ...
随机推荐
- 12:media配置以及后端指定资源暴露
django需要用到的静态文件默认都是放在static目录下 而针对后期用户上传的静态文件也应该统一存储 # media配置:规定用户上传的静态文件存储位置 MEDIA_ROOT = os.path. ...
- SVN报错“Failed to run the WC DB work queue associated with”解决办法
最近在更新SVN上的ISO代码时,失败报错: Failed to run the WC DB work queue associated with "目录/文件",clean u ...
- Redis 性能问题分析
在一些网络服务的系统中,Redis 的性能,可能是比 MySQL 等硬盘数据库的性能更重要的课题.比如微博,把热点微博[1],最新的用户关系,都存储在 Redis 中,大量的查询击中 Redis,而不 ...
- redis为什么要提供pipeline功能
通常我们用redis做接口缓存后,查询接口的性能就能提升到ms级别: 但是redis是纯内存操作啊,总不至于要到ms吧,根据官方的 benchmark 单实例也是能抗 7w+ qps 也就是说单个re ...
- Golang十六进制字符串和byte数组互转
Golang十六进制字符串和byte数组互转 需求 Golang十六进制字符串和byte数组互相转换,使用"encoding/hex"包 实现Demo package main i ...
- 如何在Linux下部署Samba服务?
Samba简介 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件 ...
- external-attacher源码分析(1)-main方法与启动参数分析
更多 ceph-csi 其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 摘要 ceph-csi分析-external-attacher源码分析.external- ...
- 整理!企业选择好用的CRM系统的要点(上)
随着市场经济的发展,对任何行业的企业来说,客户都是非常重要的一个部分.CRM系统帮助企业做到以客户为中心,它可以根据客户的具体要求进行跟进和反馈,在很大程度上提高公司的客户服务水平和客户满意度,进而提 ...
- phpstorm之"Can not run PHP Code Sniffer"
前言 其实我是不太愿意写这种工具使用博客的,因为实在没有营养,只是有些简单问题,搜索一番,却始终找不到答案,遂以博客记录下来,希望后面的人,可以省去搜索之苦. 相信你搜到这篇博客,肯定是已经安装好了P ...
- WAF集成:Acunetix和FortiWeb
Acunetix API使您有机会自动化任务以提高效率,尤其是在您可以加速与工作流其他组件的集成功能时.在此示例中,我们将在上一篇文章的基础上,向您展示如何在Bash脚本中使用Acunetix API ...