【ERROR】关于训练时以及开发集上loss丝毫不变的原因

博主记录了在项目代码中添加新model后出现的问题,训练及开发集上loss不变,说明模型待学习参数未更新。经调试排除模型内部问题,又排查优化器函数也没问题,最后发现曾将参数放CPU优化,使用优化器更新参数需特定步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记录一次马虎导致的BUG

 

事情起因:

最新在跑项目的代码,一切都好好的,直到我突发奇想加了个新model之后,一切诡异了起来。。。

代码逻辑是每训练一轮会在开发集上测三次,然后log打印每次测出的loss以及PRF指标,在改了model之后,在每一次打印的log中所有的数值都丝毫没有变化。。。

 

出现问题:

训练时以及开发集上loss丝毫不变

这说明了虽然模型每一轮都在训练,但是模型中待学习的参数却丝毫没有得到更新。

 

调试过程:

            print(probs.grad)
            print(targets.grad)
            print("probs:{}".format(probs.requires_grad))
            print("targets:{}".format(targets.requires_grad))
            
            loss = criterion(probs, targets) 
            print("loss:{}".format(loss.requires_grad))

训练时:

None
None
probs:True
targets:False
loss:True

测试时:

None
None
probs:False
targets:False
loss:False

一切正常,其中.grad只有在loss.backward()之后才会计算自己的梯度,并在此后累计梯度,所以默认输出None是正常的

因此可以排除问题出在模型内部的可能性

 

现在来排查函数之外,首先怀疑优化器函数写的不对,几次尝试后,发现问题依然不在这里。。。

 

突然发现一处代码,之前由于模型较大出现out of memory,所以曾经把参数放到CPU去优化,定义获取参数代码如下:

    if args.optimize_on_cpu:
        param_optimizer = [(n, param.clone().detach().to('cpu').requires_grad_()) for n, param in net.named_parameters()]
    else:
        param_optimizer = net.named_parameters()

这样的话在使用优化器更新参数,即optimizer.step(),时,要进行以下三个步骤:

1)对于模型的每一个参数,若该参数有梯度,则把该参数的梯度的值(para_model.grad.data)copy给对应的优化器的参数(若对应的优化器参数的梯度为None则为其赋予梯度);若模型某一参数的梯度为None,则给对应的优化器的参数的grad也复制为None;

2)梯度回传后,进行模型参数的更新;

3)将优化后的优化器的各个参数值copy到模型的各个参数上。

if args.optimize_on_cpu:
    is_nan = set_optimizer_params_grad(param_optimizer, net.named_parameters(), test_nan=True)
    optimizer.step()
    copy_optimizer_params_to_model(net.named_parameters(), param_optimizer)
else:
    optimizer.step()

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值