卷友们,好久没发文了。不是没读paper,是因为读的paper都太简单了,不值得分享,基本都是一两句话就能概括的文章。本次我们就展开讲讲最近看的几篇论文。
目录:
- ADEA(非常简单有效的数据增广方法)
- ESimCSE(在SimCSE上稍作手脚)
Paper1: ADEA(非常简单有效的数据增广方法)
论文链接: arxiv.org/abs/2108.13…
提起数据增广,大多人肯定首先想到的是EDA的方式,对数据中的部分词进行删除、交换、插入、同义词替换等等,亦或是采用互译的方式。该论文所提的AEDA方法的思路: 随机在原始文本中加入一些标点符号,以达到数据的增广。
一个句子中插入多长标点符号呢?作者给出的是从1到文本的(1/3)长度之间随机选择一个数。反正最多不能超过1/3。具体代码如下:
import random
import jieba
def insert_punctuation_marks(sentence, punc_ratio):
words = jieba.lcut(sentence)
print(words)
new_line = []
q = random.randint(1, int(punc_ratio * len(words) + 1)) # 随机选一个1到文本长度(1/3)之间的一个数
qs = random.sample(range(0, len(words)), q) # 然后随机采样一个加入标点符号的位置
print(qs)
for j, word in enumerate(words):
if j in qs:
new_line.append(PUNCTUATIONS[random.randint(0, len(PUNCTUATIONS) - 1)])
new_line.append(word)
else:
new_line.append(word)
new_line = ''.join(new_line)
return new_line
if __name__ == '__main__':
PUNCTUATIONS = ['。', ',', '!', '?', ';', ':']
PUNC_RATIO = 0.3
sentence = 'AEDA是一种更简单的文本分类数据增强技术。'
res = insert_punctuation_marks(sentence=sentence, punc_ratio=PUNC_RATIO)
print(res)
接下来看看实验结果:
不同样本数下各个模型的分类效果
另外,在bert横行的时代,这种对数据增广对于bert来说,有效果么? 如下图:
感觉还是很香的。大家可以去试试。
Paper2: ESimCSE(在SimCSE上稍作手脚)
论文链接: arxiv.org/abs/2109.04…
在看本篇论文之前,首先要对SimCSE有所了解。简单概括: 就是通过Dropout实现数据的增广,在一个batch内,正例距离拉进,负例距离拉远。对比损失如下图所示:
这里就不详细讲了。接下来,我们讲一下SimCSE存在哪些问题?
-
在SimCSE中,正样本是通过Dropout实现的,这样会让模型有一种错觉: 相关性比较强的样本难道长度都是一样的?显然不是这样子的。
-
在一个Batch内,每个样本除了其Dropout生成的那个样本为正样本外,其他样本都认为是当前这个样本的负样本。真的能保证其他样本一定是负样本吗?难道随机采用就不可能采到与当前样本相关的样本?显然不是这样子的。
本次分享的这篇论文ESimCSE主要是解决第一个问题,是怎样解决的呢?就是人工进行数据增广,对当前句子的某个词进行重复,然后生成其对应的正样本。
具体的重复是咋实现呢?
首先给出一个dup_rate(超参数),dup_rate * 文本的长度: 代表最多能选多少个token进行重复。最少选2个token进行重复。具体选多少,是从中随机选一个数字,如下式:
接下来,从总的长度里面,选择要重复的token位置。选dup_len个。
重复几次,也是自己定吧。
另外,文章还提到了一种东西,叫做动量对比,简单概括就是对batch进行缓存,扩大每个样本对应的负样本数。即: 当前batch中的某个样本的负样本不仅仅在当前batch中找,之前batch内的样本也是当前这个样本的负样本。
实验结果
看起来确实比SimCSE好一些。
再看看本文中到底是重复样本带来的提升大还是动量对比提升大,如下图:
要想了解更多的细节,请阅读原始论文。
对于上面提出SimCSE的缺点2,目前还没有解决方案。如果大家有好的想法,可以交流交流~
完结。。。