RUCAIBox / RecBole-DA

MIT License
20 stars 5 forks source link

您好,请问我们的对比学习算法,是不是存在一些问题呀~还是说是对比学习的问题 #6

Open SakuraXiaMF opened 1 year ago

SakuraXiaMF commented 1 year ago

您好,作者。我很感谢您的框架为我的科研工作带来的方便。我今天测试CL4Rec模型进行对比学习时,数据选的是ml-100K,我的结果如下:其他参数均为默认参数,没有对比学习是指计算loss时 把原本的“return loss + self.lmd * nce_loss, alignment, uniformity”改为 “return loss, alignment, uniformity”,删除了对比学习的nceloss.

todo 加了对比学习:

best valid : {'recall@5': 0.0435, 'recall@10': 0.0827, 'recall@20': 0.1463, 'recall@50': 0.2948, 'mrr@5': 0.0212, 'mrr@10': 0.0264, 'mrr@20': 0.0309, 'mrr@50': 0.0356, 'ndcg@5': 0.0266, 'ndcg@10': 0.0393, 'ndcg@20': 0.0555, 'ndcg@50': 0.0849, 'precision@5': 0.0087, 'precision@10': 0.0083, 'precision@20': 0.0073, 'precision@50': 0.0059}

test result: {'recall@5': 0.0318, 'recall@10': 0.0636, 'recall@20': 0.1166, 'recall@50': 0.2534, 'mrr@5': 0.0149, 'mrr@10': 0.0188, 'mrr@20': 0.0224, 'mrr@50': 0.0266, 'ndcg@5': 0.019, 'ndcg@10': 0.0289, 'ndcg@20': 0.0422, 'ndcg@50': 0.0692, 'precision@5': 0.0064, 'precision@10': 0.0064, 'precision@20': 0.0058, 'precision@50': 0.0051}

!没有加对比学习:

best valid : {'recall@5': 0.0626, 'recall@10': 0.1007, 'recall@20': 0.1782, 'recall@50': 0.3309, 'mrr@5': 0.0336, 'mrr@10': 0.0386, 'mrr@20': 0.0436, 'mrr@50': 0.0484, 'ndcg@5': 0.0408, 'ndcg@10': 0.0531, 'ndcg@20': 0.0722, 'ndcg@50': 0.1023, 'precision@5': 0.0125, 'precision@10': 0.0101, 'precision@20': 0.0089, 'precision@50': 0.0066}

test result: {'recall@5': 0.0477, 'recall@10': 0.0965, 'recall@20': 0.158, 'recall@50': 0.298, 'mrr@5': 0.0187, 'mrr@10': 0.0249, 'mrr@20': 0.0291, 'mrr@50': 0.0335, 'ndcg@5': 0.0258, 'ndcg@10': 0.0413, 'ndcg@20': 0.0568, 'ndcg@50': 0.0844, 'precision@5': 0.0095, 'precision@10': 0.0097, 'precision@20': 0.0079, 'precision@50': 0.006}

很明显,加了对比学习的效果比没有加的好……

SakuraXiaMF commented 1 year ago

并且当我删除 alignment, uniformity这两个差异指标之后,效果越来越好了……

INFO best valid : {'recall@5': 0.0594, 'recall@10': 0.1029, 'recall@20': 0.1718, 'recall@50': 0.3393, 'mrr@5': 0.0327, 'mrr@10': 0.0382, 'mrr@20': 0.0429, 'mrr@50': 0.0482, 'ndcg@5': 0.0392, 'ndcg@10': 0.053, 'ndcg@20': 0.0704, 'ndcg@50': 0.1035, 'precision@5': 0.0119, 'precision@10': 0.0103, 'precision@20': 0.0086, 'precision@50': 0.0068}

INFO test result: {'recall@5': 0.0583, 'recall@10': 0.087, 'recall@20': 0.1442, 'recall@50': 0.2916, 'mrr@5': 0.0247, 'mrr@10': 0.0285, 'mrr@20': 0.0325, 'mrr@50': 0.037, 'ndcg@5': 0.0329, 'ndcg@10': 0.0421, 'ndcg@20': 0.0566, 'ndcg@50': 0.0856, 'precision@5': 0.0117, 'precision@10': 0.0087, 'precision@20': 0.0072, 'precision@50': 0.0058}

easyble commented 1 year ago

我也复现到了这个问题,当不使用基于数据增强的对比学习的时候,其实模型就等效于一个SASRec,报告的指标和Paper里面的基本一致。但使用基于数据增强的对比学习后,得到的CLS4Rec的指标甚至不如SASRec,这和Paper里面报告的情况有些出入

easyble commented 1 year ago

当前代码复现的效果是DuoRec ≈ SASRec > CLS4Rec,但根据实际Paper中的应该是DuoRec > CLS4Rec > SASRec

SakuraXiaMF commented 1 year ago

当前代码复现的效果是DuoRec ≈ SASRec > CLS4Rec,但根据实际Paper中的应该是DuoRec > CLS4Rec > SASRec

我搞定了,参考清华的https://github.com/THUwangcy/ReChorus, 是人大的这个对比学习他们在进行对比学习标签设置的时候,暴力的将所有标签设置为0导致的。

zyx1017 commented 1 year ago

@SakuraXiaMF 请问能分享一下源码吗

SakuraXiaMF commented 1 year ago

等过几天吧,最近在赶ddl,有点忙

---- 回复的原邮件 ---- | 发件人 | @.> | | 日期 | 2023年05月10日 22:17 | | 收件人 | @.> | | 抄送至 | @.>@.> | | 主题 | Re: [RUCAIBox/RecBole-DA] 您好,请问我们的对比学习算法,是不是存在一些问题呀~还是说是对比学习的问题 (Issue #6) |

@SakuraXiaMF 请问能分享一下源码吗

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

SakuraXiaMF commented 1 year ago

` logits_mask = torch.scatter( torch.ones_like(mask), 1, torch.arange(mask.shape[0]).view(-1, 1).to(mask.device), 0 )#对角线为0,其他为1,(2batch,2batch) mask = mask logits_mask #为512个1,其他为0,(2batch,2*batch),正样本为1,其他为0 mask = ~mask mask = mask.filldiagonal(0)

print(mask.shape,torch.sum(~mask))

    # mask [2*batch,2*batch], 对脚线是False,其他是true
    negative_samples = sim[mask].reshape(N, -1)

    # !原版本代码
    # labels = torch.zeros(N).to(positive_samples.device).long()#256个数据,做数据增强,
    # labels = torch.eye(N, dtype=torch.long)[mask].to(positive_samples.device)
    # logits = torch.cat((positive_samples, negative_samples), dim=1)

    #!修改后的代码
    # labels =copy.deepcopy(mask).to(positive_samples.device).long()
    labels = torch.ones(N).to(positive_samples.device).long()#256个数据,做数据增强,
    logits = torch.cat((negative_samples,positive_samples), dim=1)

` 我是这样做的。你先试试吧~

zyx1017 commented 1 year ago

@SakuraXiaMF 谢谢你! 不过代码有点乱,有点看不明白5555

zyx1017 commented 1 year ago

@SakuraXiaMF 如果空闲时,希望能看看你分享的源码,谢谢!

easyble commented 1 year ago

@SakuraXiaMF 您好,我注意到这部分应该是模型里的info_nce部分 他的操作的结果是将positive_sample都置为首位,所以采用了暴力将标签设为0的做法 您的意思是这里会导致退化吗?我注意到您一部分操作是将positve放在对角线上,然后采用torch.eye生成标签 但另一部分的torch.ones来生成标签的做法我暂时没有完全领会

easyble commented 1 year ago

@SakuraXiaMF 而且在直觉上采用CE来计算的话,我理解标签只要和正样本位置对应就可以了,想请教下这里面的问题所在

easyble commented 1 year ago

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

SakuraXiaMF commented 1 year ago

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

不好意思,最近太忙了,忘记回复了。我是按照Thu的那个代码库写的。具体的来说,就是你这个思路

SakuraXiaMF commented 1 year ago

@SakuraXiaMF 谢谢你! 不过代码有点乱,有点看不明白5555

不好意思,我把原来的代码注释了。为了让你知道我改了哪里~

zyx1017 commented 1 year ago

@SakuraXiaMF 谢谢你的回复!请问能再发一遍吗

easyble commented 1 year ago

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

不好意思,最近太忙了,忘记回复了。我是按照Thu的那个代码库写的。具体的来说,就是你这个思路

哦哦,但我意思是这并不能表明他原来的写法有问题,你的新写法得到的指标,在加入对比学习的loss以后会显著提升吗,我对这个事比较疑惑

SakuraXiaMF commented 1 year ago
logits_mask = torch.scatter(
torch.ones_like(mask), 1,
torch.arange(mask.shape[0]).view(-1, 1).to(mask.device), 0
)#对角线为0,其他为1,(2batch,2batch)
mask = mask * logits_mask #为512个1,其他为0,(2batch,2batch),正样本为1,其他为0
mask = ~mask
mask = mask.fill_diagonal_(0)
# print(mask.shape,torch.sum(~mask))
# mask [2batch,2batch], 对脚线是False,其他是true
negative_samples = sim[mask].reshape(N, -1)
#这里是重新调整negative_samples
`#这里是labels里RecBole-DA的原版本代码
# labels = torch.zeros(N).to(positive_samples.device).long()#256个数据,做数据增强,
# labels = torch.eye(N, dtype=torch.long)[mask].to(positive_samples.device)
# logits = torch.cat((positive_samples, negative_samples), dim=1)

#!修改后的代码
labels = torch.ones(N).to(positive_samples.device).long()#256个数据,做数据增强,
logits = torch.cat((negative_samples,positive_samples), dim=1)
SakuraXiaMF commented 1 year ago

@SakuraXiaMF 谢谢你的回复!请问能再发一遍吗

发了

SakuraXiaMF commented 1 year ago

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

不好意思,最近太忙了,忘记回复了。我是按照Thu的那个代码库写的。具体的来说,就是你这个思路

哦哦,但我意思是这并不能表明他原来的写法有问题,你的新写法得到的指标,在加入对比学习的loss以后会显著提升吗,我对这个事比较疑惑

你试试?他原来的写法,我的Recall,NDCG一直没有单独的CE效果好。但我感觉加入对比学习,loss不一定会降低很快但最后的acc一点会上去。因为对比学习除了CE还要加CL_loss,这个cl_loss还是很高的。这是我训练的效果,我不确定是否是对比学习的极限,但提高个1%~2%? 我看CL4Rec这个论文里的提升也就是0.5%?

771c4c73d9bb19a48030c01187a9a71
easyble commented 1 year ago

你那个旧版本里的那个torch.eye确实很莫名奇妙,我这里没有这行。我跑出来CL4Rec确实基本不怎么明显优于SASRec,DuoRec也不显著好,但论文里Duo指标还是明显高很多的。另外有个小思路就是多采用crop的增强可能好点,他代码里面mask、 crop和reorder是随机的,但直觉上mask和reorder不太有解释性,我全采取crop后指标也好了不少

zyx1017 commented 1 year ago

@SakuraXiaMF 谢谢!

SakuraXiaMF commented 1 year ago

你那个旧版本里的那个torch.eye确实很莫名奇妙,我这里没有这行。我跑出来CL4Rec确实基本不怎么明显优于SASRec,DuoRec也不显著好,但论文里Duo指标还是明显高很多的。另外有个小思路就是多采用crop的增强可能好点,他代码里面mask、 crop和reorder是随机的,但直觉上mask和reorder不太有解释性,我全采取crop后指标也好了不少

哦,对因为我的模型用Bert,所以我只能适合reorder。因为bert本身就有mask

SakuraXiaMF commented 1 year ago

你那个旧版本里的那个torch.eye确实很莫名奇妙,我这里没有这行。我跑出来CL4Rec确实基本不怎么明显优于SASRec,DuoRec也不显著好,但论文里Duo指标还是明显高很多的。另外有个小思路就是多采用crop的增强可能好点,他代码里面mask、 crop和reorder是随机的,但直觉上mask和reorder不太有解释性,我全采取crop后指标也好了不少

旧版本的torch.eye是我自己理解的对比学习正负样本的采样,显然我没理解到位哈哈哈哈

easyble commented 1 year ago

哦哦,正负样本的在相似度矩阵中的实际位置就是我在之前陈述的,实际上对角线位置上的不是正样本对的相似度,他那段代码里前面处理的很微妙,我也是自己把他那部分扒下来才传入一些构造例才搞懂的

SakuraXiaMF commented 1 year ago

哦哦,正负样本的在相似度矩阵中的实际位置就是我在之前陈述的,实际上对角线位置上的不是正样本对的相似度,他那段代码里前面处理的很微妙,我也是自己把他那部分扒下来才传入一些构造例才搞懂的

是的。但其实我个人感觉,没有那么困难啊。按照他的写法,就是i和i+batchsize是正对嘛,之后其他都是负对。但不知道为啥ReBole的写法就是不Work。他们DuoRec还能有效果……

zyx1017 commented 1 year ago

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

不好意思,最近太忙了,忘记回复了。我是按照Thu的那个代码库写的。具体的来说,就是你这个思路

哦哦,但我意思是这并不能表明他原来的写法有问题,你的新写法得到的指标,在加入对比学习的loss以后会显著提升吗,我对这个事比较疑惑

你试试?他原来的写法,我的Recall,NDCG一直没有单独的CE效果好。但我感觉加入对比学习,loss不一定会降低很快但最后的acc一点会上去。因为对比学习除了CE还要加CL_loss,这个cl_loss还是很高的。这是我训练的效果,我不确定是否是对比学习的极限,但提高个1%~2%? 我看CL4Rec这个论文里的提升也就是0.5%? 771c4c73d9bb19a48030c01187a9a71

@SakuraXiaMF 您好!请问一下黄色列指的是什么?

xiaxiaxiatengxi commented 1 year ago

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

不好意思,最近太忙了,忘记回复了。我是按照Thu的那个代码库写的。具体的来说,就是你这个思路

哦哦,但我意思是这并不能表明他原来的写法有问题,你的新写法得到的指标,在加入对比学习的loss以后会显著提升吗,我对这个事比较疑惑

你试试?他原来的写法,我的Recall,NDCG一直没有单独的CE效果好。但我感觉加入对比学习,loss不一定会降低很快但最后的acc一点会上去。因为对比学习除了CE还要加CL_loss,这个cl_loss还是很高的。这是我训练的效果,我不确定是否是对比学习的极限,但提高个1%~2%? 我看CL4Rec这个论文里的提升也就是0.5%? 771c4c73d9bb19a48030c01187a9a71

@SakuraXiaMF 您好!请问一下黄色列指的是什么?

这个不用管,是我自己做的实验。就是训练时不取负样本……

zyx1017 commented 1 year ago

@xiaxiaxiatengxi @SakuraXiaMF 你好!看到楼上你说你用的bert,请问你试过伯乐框架里的bert4rec吗?好像跑出来的效果很差。。。甚至比不过最简单的BPR....

xiaxiaxiatengxi commented 1 year ago

@xiaxiaxiatengxi @SakuraXiaMF 你好!看到楼上你说你用的bert,请问你试过伯乐框架里的bert4rec吗?好像跑出来的效果很差。。。甚至比不过最简单的BPR....

没有,找别的Pytorch的实现。RecBole……可以作为参考

zyx1017 commented 1 year ago

@xiaxiaxiatengxi 能否问一下是参考了哪个pytorch的实现吗

XiaoJing-C commented 1 year ago

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

不好意思,最近太忙了,忘记回复了。我是按照Thu的那个代码库写的。具体的来说,就是你这个思路

哦哦,但我意思是这并不能表明他原来的写法有问题,你的新写法得到的指标,在加入对比学习的loss以后会显著提升吗,我对这个事比较疑惑

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

不好意思,最近太忙了,忘记回复了。我是按照Thu的那个代码库写的。具体的来说,就是你这个思路

哦哦,但我意思是这并不能表明他原来的写法有问题,你的新写法得到的指标,在加入对比学习的loss以后会显著提升吗,我对这个事比较疑惑

你好 我也遇到了同样的问题 请问 您有找到recbole代码的问题吗 正负样本的选取好像都没有问题?

zyx1017 commented 1 year ago

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里sim的计算的话,正样本不是分布在对角线上的,应该是在对角线上下距离N的副对角线上,对角线上分布的是样本对自身的相似度,取cos会恒为1,取dot就是平方,这部分在计算对比损失时是没有意义的

不好意思,最近太忙了,忘记回复了。我是按照Thu的那个代码库写的。具体的来说,就是你这个思路

哦哦,但我意思是这并不能表明他原来的写法有问题,你的新写法得到的指标,在加入对比学习的loss以后会显著提升吗,我对这个事比较疑惑

你试试?他原来的写法,我的Recall,NDCG一直没有单独的CE效果好。但我感觉加入对比学习,loss不一定会降低很快但最后的acc一点会上去。因为对比学习除了CE还要加CL_loss,这个cl_loss还是很高的。这是我训练的效果,我不确定是否是对比学习的极限,但提高个1%~2%? 我看CL4Rec这个论文里的提升也就是0.5%? 771c4c73d9bb19a48030c01187a9a71

对了,有个疑问,你的SASRec_CL对比SASRec怎么提升这么多?请问是在伯乐上做的嘛

zyx1017 commented 1 year ago

@XiaoJing-C 你好,你有解决问题了吗

p114514-new commented 6 months ago

似乎是contrastive loss的信号远远盖过了main loss的信号所以模型没有有效优化的问题。我将tau改成100或将lmd改成0.001得到了比原始SASRec好一些的结果。