Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
SakuraXiaMF opened this issue Apr 21, 2023 · 34 comments

Comments

@SakuraXiaMF
Copy link

您好,作者。我很感谢您的框架为我的科研工作带来的方便。我今天测试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
Copy link
Author

并且当我删除 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
Copy link

easyble commented May 9, 2023

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

@easyble
Copy link

easyble commented May 9, 2023

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

@SakuraXiaMF
Copy link
Author

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

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

@zyx1017
Copy link

zyx1017 commented May 10, 2023

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

@SakuraXiaMF
Copy link
Author

SakuraXiaMF commented May 10, 2023 via email

@SakuraXiaMF
Copy link
Author

SakuraXiaMF commented May 10, 2023

`
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)

    # !原版本代码
    # 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
Copy link

zyx1017 commented May 10, 2023

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

@zyx1017
Copy link

zyx1017 commented May 10, 2023

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

@easyble
Copy link

easyble commented May 10, 2023

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

@easyble
Copy link

easyble commented May 10, 2023

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

@easyble
Copy link

easyble commented May 10, 2023

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

@SakuraXiaMF
Copy link
Author

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

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

@SakuraXiaMF
Copy link
Author

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

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

@zyx1017
Copy link

zyx1017 commented May 12, 2023

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

@easyble
Copy link

easyble commented May 12, 2023

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

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

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

@SakuraXiaMF
Copy link
Author

SakuraXiaMF commented May 12, 2023

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
Copy link
Author

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

发了

@SakuraXiaMF
Copy link
Author

SakuraXiaMF commented May 12, 2023

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

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

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

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

@easyble
Copy link

easyble commented May 12, 2023

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

@zyx1017
Copy link

zyx1017 commented May 12, 2023

@SakuraXiaMF 谢谢!

@SakuraXiaMF
Copy link
Author

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

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

@SakuraXiaMF
Copy link
Author

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

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

@easyble
Copy link

easyble commented May 12, 2023

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

@SakuraXiaMF
Copy link
Author

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

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

@zyx1017
Copy link

zyx1017 commented May 20, 2023

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里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
Copy link

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里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
Copy link

zyx1017 commented May 31, 2023

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

@xiaxiaxiatengxi
Copy link

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

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

@zyx1017
Copy link

zyx1017 commented May 31, 2023

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

@XiaoJing-C
Copy link

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

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

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

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

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

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

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

@zyx1017
Copy link

zyx1017 commented Jun 1, 2023

我大概明白你对正负样本的取法了,但是如果你沿用了他代码里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
Copy link

zyx1017 commented Jul 6, 2023

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

@p114514-new
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants