前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >(转载非原创)无监督数据预训练短文本编码模型

(转载非原创)无监督数据预训练短文本编码模型

作者头像
xlj
修改2021-07-31 19:18:22
6580
修改2021-07-31 19:18:22
举报
文章被收录于专栏:XLJ的技术专栏XLJ的技术专栏

1 前言

本博文本应写之前立的Flag:基于加密技术编译一个自己的Python解释器,经过半个多月尝试已经成功,但考虑到安全性问题就不公开了,有兴趣的朋友私聊讨论吧。 从本篇博客开始,本人将转化写作模式,由话痨模式转为极简模式,力求三言两语让各位看的明白。

2 工作简介

受到MOCO和SimCSE的启发, 基于自监督,使用海量无监督数据(nlp_chinese_corpus)预训练了一个专门用于短文本表征的编码器。该编码器在分类任务尤其是短文本相似度任务上效果超过同级别BERT模型。该预训练模型暂且叫LUSE.

本次实验结果是仅在预训练0.1轮(10万步)情况下得到的,完全训练后会得到更强的效果。

三层预训练模型(torch)下载地址

代码地址: 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 算法详情

算法伪代码如下:

代码语言:javascript
复制
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:其实不一样,只是取了前三位恰好一样罢了

本文系转载,前往查看

如有侵权,请联系?cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系?cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 前言
  • 2 工作简介
  • 3 算法详情
    • 3.1 数据增强
      • 3.2 损失函数
        • 3.3 预训练数据
          • 3.4 训练细节
            • 3.5 小技巧:同义词搜索加速
            • 4 微调验证
              • 4.1 数据集
                • 4.2 微调方法
                  • 4.3 评价指标
                    • 4.4 基线模型
                      • 4.4 实验结果
                      • 5 总结
                      • 6 TODOList
                      • 7 FAQ
                      相关产品与服务
                      NLP 服务
                      NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                      http://www.vxiaotou.com