Closed zhangsuzerain closed 4 years ago
感觉是add_regularization_loss的方式不对,把
basemodel.py
的fit函数里的total_loss = loss # + self.reg_loss + self.aux_loss
后面的范数损失注释掉代码即正确运行,顺便后面total_loss.backward(retain_graph=False)
也可以改成False了。对比了一个DeepCTR里tensorflow的实现,
regularizers
是在build函数里通过add_weight
增加的,所以范数损失是在forward的时候计算的。而pytorch版本中,add_regularization_loss
在init的时候就已经加上了,每个epoch的reg_loss都依赖最初的weight,一旦backward
修改了weight,就会报错
按你说的方法可以跑通,但是发现从第一个epoch开始就出现训练集误差越来越低,val上却越来越高的情况,不知道你遇到没。模型DeepFM,数据集criteo
感觉是add_regularization_loss的方式不对,把
basemodel.py
的fit函数里的total_loss = loss # + self.reg_loss + self.aux_loss
后面的范数损失注释掉代码即正确运行,顺便后面total_loss.backward(retain_graph=False)
也可以改成False了。 对比了一个DeepCTR里tensorflow的实现,regularizers
是在build函数里通过add_weight
增加的,所以范数损失是在forward的时候计算的。而pytorch版本中,add_regularization_loss
在init的时候就已经加上了,每个epoch的reg_loss都依赖最初的weight,一旦backward
修改了weight,就会报错按你说的方法可以跑通,但是发现从第一个epoch开始就出现训练集误差越来越低,val上却越来越高的情况,不知道你遇到没。模型DeepFM,数据集criteo
这个情况解决了吗,我也有类似的问题。
刚开始接触推荐系统,不知道推荐系统中的参数正则是否和cv中实现相同, 下面的修改是默认为两者的参数正则是相同的。
修改basemodel.py文件
“训练集误差越来越低,val上却越来越高的情况,” 这应该是模型过拟合,在损失中加入参数正则就是为了解决这个问题
“如何在模型训练中加入参数正则” a. 把计算reg_loss部分从init函数移动到fit函数里面
def fit()
...
loss = loss_func(y_pred, y.squeeze(), reduction='sum')
self.add_regularization_loss( self.embedding_dict.parameters(), self.l2_reg_embedding) self.add_regularization_loss( self.linear_model.parameters(), self.l2_reg_linear)
total_loss = loss + self.reg_loss + self.aux_loss ...
b. 修改add_regularization_loss的实现
self.reg_loss = reg_loss
上面的#实现会把历史的 reg_loss 也添加到 self.reg_loss 中,导致代码报错。
刚开始接触推荐系统,不知道推荐系统中的参数正则是否和cv中实现相同, 下面的修改是默认为两者的参数正则是相同的。
修改basemodel.py文件
- “训练集误差越来越低,val上却越来越高的情况,” 这应该是模型过拟合,在损失中加入参数正则就是为了解决这个问题
- “如何在模型训练中加入参数正则” a. 把计算reg_loss部分从init函数移动到fit函数里面
def fit() ... loss = loss_func(y_pred, y.squeeze(), reduction='sum') self.add_regularization_loss( self.embedding_dict.parameters(), self.l2_reg_embedding) self.add_regularization_loss( self.linear_model.parameters(), self.l2_reg_linear) total_loss = loss + self.reg_loss + self.aux_loss ...
b. 修改add_regularization_loss的实现
#self.reg_loss = self.reg_loss + reg_loss self.reg_loss = reg_loss
上面的#实现会把历史的 reg_loss 也添加到 self.reg_loss 中,导致代码报错。
@selous123 谢谢分享!想请教下和cv一样的参数正则是什么意思?能不能稍微讲解下cv里面正则参数和推荐算法里的正则参数的区别?
我们这里的regularization loss
不需要包含历史的reg_loss
么?
L2参数正则:
total_loss = loss + \labmda * l2_norm(w)
只需要计算当前模型weight的l2范数(reg_loss)即可。
关于推荐系统中的正则: 我刚接触推荐系统, 所以不太明白为什么要加历史的 reg_loss。我认为可能是代码的问题。
L2参数正则:
total_loss = loss + \labmda * l2_norm(w)
只需要计算当前模型weight的l2范数(reg_loss)即可。
关于推荐系统中的正则: 我刚接触推荐系统, 所以不太明白为什么要加历史的 reg_loss。我认为可能是代码的问题。
我倾向于正则这种方法在cv领域和在推荐领域的定义是一样的,也就是用法和实现应该是一致的,不该有基本概念上的冲突。
这里的l2范数 code link 之所以会加入历史reg_loss
其实是想用到momentum
的想法,每次加入的是衰减后(乘以weight_decay
)的历史reg_loss
.
首先我同意你的观点:两者的定义应该是一样的, 不应该存在基础概念的冲突。其次,
reg_loss = weight_decay * reg_loss
self.reg_loss = self.reg_loss.item() + reg_loss
存疑点: a. 指数加权平均(momentum)的公式应该是: self.reg = \beta reg + (1-\beta)self.reg beta一般取值为0.9。 而代码中默认传入的参数weight_decay是1e-5,这只是一个scale的参数 所以如果需要加入momentum是否是应该需要加入新的参数 \beta
self.reg_loss = (1-\beta) * self.reg_loss.item() + beta * reg_loss
b. 对于在reg_loss上加momentum是否会使结果变好? 正则化项L1,L2以及weight decay在SGD,Adam中的理解
@selous123 我这里说的momentum
可能不是十分准确,原代码里面的想法应该只是把正则化项(reg_loss
)约束到了一个数量级(weight_decay
)(?)
p.s 我刚刚又跑了下examples/run_classification_criteo.py
发现梯度反向传播没有报错。
环境如下:
@selous123 我这里说的
momentum
可能不是十分准确,原代码里面的想法应该只是把正则化项(reg_loss
)约束到了一个数量级(weight_decay
)(?)p.s 我刚刚又跑了下
examples/run_classification_criteo.py
发现梯度反向传播没有报错。环境如下:
- python 3.7
- torch 1.4
- deepctr_torch 0.21 master
- cpu / CUDA 10.1
可是加了正则还是会出现过拟合现象。训练集auc 和 loss在降低,但是验证集确在上升,从第一个epoch开始就是这样。模型DeepFM,数据集Criteo45M。
@selous123 我这里说的
momentum
可能不是十分准确,原代码里面的想法应该只是把正则化项(reg_loss
)约束到了一个数量级(weight_decay
)(?) p.s 我刚刚又跑了下examples/run_classification_criteo.py
发现梯度反向传播没有报错。 环境如下:
- python 3.7
- torch 1.4
- deepctr_torch 0.21 master
- cpu / CUDA 10.1
可是加了正则还是会出现过拟合现象。训练集auc 和 loss在降低,但是验证集确在上升,从第一个epoch开始就是这样。模型DeepFM,数据集Criteo45M。
@WadasZhao 是在完整的Criteo45M数据集上面测试的么?
@selous123 我这里说的
momentum
可能不是十分准确,原代码里面的想法应该只是把正则化项(reg_loss
)约束到了一个数量级(weight_decay
)(?) p.s 我刚刚又跑了下examples/run_classification_criteo.py
发现梯度反向传播没有报错。 环境如下:
- python 3.7
- torch 1.4
- deepctr_torch 0.21 master
- cpu / CUDA 10.1
可是加了正则还是会出现过拟合现象。训练集auc 和 loss在降低,但是验证集确在上升,从第一个epoch开始就是这样。模型DeepFM,数据集Criteo45M。
@WadasZhao 是在完整的Criteo45M数据集上面测试的么?
是的,4500万。是这样的,第一个epoch还行,看不出来是否过拟合,从第二个epoch开始,训练集loss大幅度下降,val不降反升。
@selous123 我这里说的
momentum
可能不是十分准确,原代码里面的想法应该只是把正则化项(reg_loss
)约束到了一个数量级(weight_decay
)(?) p.s 我刚刚又跑了下examples/run_classification_criteo.py
发现梯度反向传播没有报错。 环境如下:
- python 3.7
- torch 1.4
- deepctr_torch 0.21 master
- cpu / CUDA 10.1
可是加了正则还是会出现过拟合现象。训练集auc 和 loss在降低,但是验证集确在上升,从第一个epoch开始就是这样。模型DeepFM,数据集Criteo45M。
@WadasZhao 是在完整的Criteo45M数据集上面测试的么?
是的,4500万。是这样的,第一个epoch还行,看不出来是否过拟合,从第二个epoch开始,训练集loss大幅度下降,val不降反升。
经过测试。正则化确实有问题,第一个epoch内每个bactch_size 能够正常更新,第二个epoch一开始第一个batch的loss就急剧下降,val的loss急剧上升,呈现过拟合趋势。 解决办法:去掉模型中的所有正则化参数,用optim内部的weight_decay来代替。
@selous123 我这里说的
momentum
可能不是十分准确,原代码里面的想法应该只是把正则化项(reg_loss
)约束到了一个数量级(weight_decay
)(?) p.s 我刚刚又跑了下examples/run_classification_criteo.py
发现梯度反向传播没有报错。 环境如下:
- python 3.7
- torch 1.4
- deepctr_torch 0.21 master
- cpu / CUDA 10.1
可是加了正则还是会出现过拟合现象。训练集auc 和 loss在降低,但是验证集确在上升,从第一个epoch开始就是这样。模型DeepFM,数据集Criteo45M。
@WadasZhao 是在完整的Criteo45M数据集上面测试的么?
是的,4500万。是这样的,第一个epoch还行,看不出来是否过拟合,从第二个epoch开始,训练集loss大幅度下降,val不降反升。
经过测试。正则化确实有问题,第一个epoch内每个bactch_size 能够正常更新,第二个epoch一开始第一个batch的loss就急剧下降,val的loss急剧上升,呈现过拟合趋势。 解决办法:去掉模型中的所有正则化参数,用optim内部的weight_decay来代替。
可以直接这么转换吗?印象中pytorch里optim的weight_decay会对bias也正则化?
没来得及看前面的讨论,不过如果是Criteo完整数据集,训练1个epoch就足够了,后面是会发生过拟合的
we have solved this issue in new version , please use pip install -U deepctr-torch
to upgrade.
感觉是add_regularization_loss的方式不对,把
basemodel.py
的fit函数里的total_loss = loss # + self.reg_loss + self.aux_loss
后面的范数损失注释掉代码即正确运行,顺便后面total_loss.backward(retain_graph=False)
也可以改成False了。对比了一个DeepCTR里tensorflow的实现,
regularizers
是在build函数里通过add_weight
增加的,所以范数损失是在forward的时候计算的。而pytorch版本中,add_regularization_loss
在init的时候就已经加上了,每个epoch的reg_loss都依赖最初的weight,一旦backward
修改了weight,就会报错