LibRec 学习笔记(十二):SBPR 的训练 Loss 为什么越来越大,没有收敛的迹象?

简单记录下困扰了我半个多月的问题:在跑 Librec 的 SBPR 算法代码的时候,发现 Loss 一直随着迭代次数在逐渐增加,这不是不正常吗???

一、我的疑问

最早的时候,只是拿 Librec 去跑一个数据集的实验结果,但是一不下心瞄了一眼输出的迭代结果,竟然发现 loss 一直在逐渐增大,跑了其他几个方法,都没有发现这样的情况,按理来说,越训练 loss 应该越小才对,所以到底哪里有问题???
在这里插入图片描述
说明

  • 上图的 loss 是每一次迭代的 loss 总值
  • delta_loss 是上一次迭代的 loss 值 - 本次迭代 loss 值

二、我的尝试解决办法

然后我开始尝试不断的解决问题,劝说自己:

  • 首先排查是不是不小心把对方的代码改了,这里没有。
  • 然后想想是不是迭代次数不够,慢慢的后面会逐渐收敛,所以把迭代次数设置的超级大,但 loss 还是一直在持续上升,并且不是上升一点点的那种。
  • 查询很多资料后,发现 loss 上升绝对是不正常的,所以我开始看原论文,发现原论文是用梯度上升求最大值,看了眼公式,既然是求最大值,那 loss 上升应该是对的,我这样想。

我以为这是我的最终答案,遂不管它。但是过了几天想想还是不对劲,loss 代表的是误差,误差一直在增大,怎么样都说不过去啊,只有 loss 缓慢更新才代表收敛啊,这样才叫训练好了啊,然后我就开始查梯度上升的资料,发现这方面的资料很少。咨询同门师弟也说,loss 一直上升是不正常的!!!

  • 后来查到如果 loss 上升的话,可以调整下学习率,每次迭代的时候都相应的更新学习率,loss 就会收敛。而在 librec 中确实有一个 bolddriver 的设置问题,设置为 true 的话,可以控制每次迭代的时候相应的更新学习率的大小,比如 loss 在增加,学习率在下一轮变小,loss 在减小,学习率在下一轮变大。这样设置后, 虽然前面的迭代次数 loss 都在上升,但是后面逐渐收敛。

我以为上面就是我的最终答案,只要改一个默认的参数设置 bolddriver就可以解决 。遂又开始不管它。(但SBPR的梯度上升的疑问一直留在我的心中,这是个啥?)

三、插句题外话,BPR公式错了?

后面因为种种原因,我重新看了遍 BPR 的公式以及重新推导了一遍 BPR 的公式,发现 BPR 也是要查找最大值,但是为啥最后用的是梯度下降,梯度下降不是用来找最小值的吗???为啥 SBPR 用的是梯度上升???然后我去翻了很多 BPR 的其他变体,大家普遍用的是梯度下降。

我开始纳闷了。真的纳闷了!!!看来我真的没有看懂过 BPR 这个算法,枉我之前还更新过【论文阅读+实现】BPR: Bayesian Personalized Ranking from Implicit Feedback,简直打脸,我连它为啥用梯度下降找最大值都不知道。

找了很多资料,开始手把手的重新推导公式,下面是 BPR 论文中的优化公式(目标函数),说是要最大化这个公式,这个公式到这里的推导都是正确的。
在这里插入图片描述
但后面就开始说用梯度下降求解了,这?????(这里开始不断的怀疑自己几百次)
在这里插入图片描述
我这里就不卖关子了,直接说出我最后的结论,结论就是要找最大值没有错,整个公式加个负号不就是找最小值了吗!!!不就可以使用梯度下降了吗!!!(这里原论文感觉也没有说明白,然后就直接推导公式了,其实这个推导是有错误的)
在这里插入图片描述
证据就是这一步这样推下来是没有那个负号的!(我推了很多次,不要怀疑…不过,也可以怀疑…)
所以这个目标公式其实应该改成下面这样,再来进行梯度下降求最小值(整体取负,想想ln函数在(0,1)区间得到的值都是负数就明白了)。
在这里插入图片描述
我其实一开始不太肯定自己的这种猜想,但是为了劝服自己,我又去看了其他论文,比如下面这篇发表在CIKM2018上的MBPR上的目标函数。我才敢觉得我这样的猜想有些正确…
在这里插入图片描述
那么自然而然这个公式最后求导的结果为
在这里插入图片描述
参数更新公式为
在这里插入图片描述
其实到这里我还是不太敢详细论文中公式推错了,而且很多人都推错了…(或许是我错了…)但是我仔仔细细的研究了下 librec 中的 BPR代码,发现我这样的公式和那里的实现是吻合的。

四、言归正传,SBPR 用梯度上升有问题吗?

为啥中间插个 BPR 呢?其实是因为在不断的解决问题中,一直不断的产生新的疑问,新的自我怀疑,上面这个怀疑公式推导错误我也是想了很久,验证了很久。(验证方法无非是看其他引文的公式推导,发现我没有错),看其他开源代码的实现方法(有的和我一致,有的不一致…)

但上面就是我现阶段对于 BPR 的结论了,可能过个几个月,我又会觉得我自己错了。学术交流嘛,反正我就是想把这个思考的过程记录在这里。

言归正传,上面讲到 BPR 的目标函数已经变为了这个,所以用梯度下降求最小值,没有任何问题。在这里插入图片描述
而SBPR的目标函数如下,这个公式没有问题,求最大值没有问题,用梯度上升求最大值更没有问题了。至此不纠结为啥SBPR用梯度上升,而其他方法都用梯度下降了,确实这样说一点问题都没有!在这里插入图片描述

五、我又开始尝试解决这个问题了

既然如此,因为使用梯度上升,所以 loss 一直上升,而且最后 loss 会收敛好像确实没有毛病(我也不知道是不是这样)。我又以为这是我最终的答案

但出人意料的点来了。在 Librec 中是使用梯度下降的方法来优化 SBPR 算法的。所以 loss 会一直上升是真的有问题!!!

再来回顾下,SBPR的 loss 公式:
在这里插入图片描述
下面是计算 loss 的代码,没有错误。
在这里插入图片描述
在这里插入图片描述
我们知道,对于一个用户来说,如果没有 social item 的话,那该用户的参数更新就会降为BPR算法了在这里插入图片描述
由此,此时的 loss 公式为
在这里插入图片描述
下面是 librec 这部分的代码
在这里插入图片描述
终于找到错误了!!!就是上面画×的地方,这里的代码应该是

double posNegDiffValue = posPredictRating - negPredictRating;
double lossValue = - Math.log(Maths.logistic(posNegDiffValue));
loss += lossValue;

要哭了…原来是 librec 库里的代码写错了,完全可能是复现作者的笔误,直接将posNegDiffValue 作为 loss 相加…下面的结果是修改完这段代码之后的运行结果,loss 在逐渐降低并且收敛。(没有设置 bolddriver)
在这里插入图片描述
至此,我的问题终于解决了。值得一提的是,因为代码部分这里的 loss 写错了,参数更新以及其他的地方都没有写错,所以在同样的迭代次数下,实验结果是一样的。所以除了没有显示出正确的 loss 值外,其他都对!

六、小结

看完上面我的种种陷入自我怀疑又不断求证的"精分现场"是不是脑子里会有点???
在这里插入图片描述
我也觉得很无语,小小的问题被我解决来解决去,竟然发现了自己的这么多漏洞,自己有这么多理解错的地方,比如 梯度上升求最小值???loss 不收敛结果正确吗???BPR的公式推错了???梯度下降求最大值???简直是越求证,越无知!!!不过还好没有放弃妥协…

以上是我的"精分现场",如有同样疑问,欢迎评论交流。如有错误,欢迎指正。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值