xinyi-code/SimCSE-Pytorch

ESimCSE貌似实现有误?

Opened this issue · 7 comments

阅读了一下这里的代码,对MoCo的实现是在dataloader里面维护了一个队列存储了历史样本(而不是样本的embedding),但是Momentum encoder的**,如果我理解的无误,应该是缓存momentum encoder的输出embedding,并通过动量更新的方法使embedding空间的波动不至于太大(同时不用占用额外显存)。是否是实现有误呢?

阅读了一下这里的代码,对MoCo的实现是在dataloader里面维护了一个队列存储了历史样本(而不是样本的embedding),但是Momentum encoder的**,如果我理解的无误,应该是缓存momentum encoder的输出embedding,并通过动量更新的方法使embedding空间的波动不至于太大(同时不用占用额外显存)。是否是实现有误呢?

动量更新主要解决的是针对进行大batch对比,而内存不足问题。原文中提到的存的是embedding,对比的是上一个batch优化模型参数后encoder的embedding,而我这里存句子对比学习的是当前参数下model encoder的embedding。我这里由于内存限制,存的是句子节省内存。你可以尝试一下,看下效果有区别么,可以交流一下哈。

如果你是在显卡上运行,根本不存在cache输入可以省内存(显存)的说法啊,因为你缓存样本相当于增大batch size,中间的activations应该更费显存。

这跟activation没什么关系,队列中存放text,是实时的产生embedding,相当于队列可以维护10000个样本,每次就encoder 部分样本(n x batch)作为对比样本,而维护embedding是维护一个(10000,maxlen, 768)矩阵,这里面占用的内存是有差距的。

1、存放文本之后,你每次需要forward key encoder才可以得到这么多负样本表示,这中间计算都是占用额外显存的;
2、维护embedding是一个句子对应一个embedding,中间的maxlen是没有的。
显然,前者比后者多占内存。

1、存放文本之后,你每次需要forward key encoder才可以得到这么多负样本表示,这中间计算都是占用额外显存的; 2、维护embedding是一个句子对应一个embedding,中间的maxlen是没有的。 显然,前者比后者多占内存。

但是抛开急剧增加的计算量,他这样写是不是能直接解决负样本一致性的问题,根本不需要什么动量编码器了

1、存放文本之后,你每次需要forward key encoder才可以得到这么多负样本表示,这中间计算都是占用额外显存的; 2、维护embedding是一个句子对应一个embedding,中间的maxlen是没有的。 显然,前者比后者多占内存。

但是抛开急剧增加的计算量,他这样写是不是能直接解决负样本一致性的问题,根本不需要什么动量编码器了

他这样相当于直接开了更大的batchsize训练而已...

1、存放文本之后,你每次需要forward key encoder才可以得到这么多负样本表示,这中间计算都是占用额外显存的; 2、维护embedding是一个句子对应一个embedding,中间的maxlen是没有的。 显然,前者比后者多占内存。

但是抛开急剧增加的计算量,他这样写是不是能直接解决负样本一致性的问题,根本不需要什么动量编码器了

他这样相当于直接开了更大的batchsize训练而已...

还是有点区别的,他是只把query当做更新当前batch的embedding的工具。batch还是这么点大,学习率也不需要改变。某些模型上增大batch_size会造成性能下降(正如ESimCSE原文所述),或者需要重新调学习率等等参数,他这样就没有这些问题