PaddlePaddle / PaddleClas

A treasure chest for visual classification and recognition powered by PaddlePaddle
Apache License 2.0
5.41k stars 1.16k forks source link

celoss.py中损失函数写错 #2468

Closed DLlearn closed 1 year ago

DLlearn commented 1 year ago

PaddleClas 2.4 paddle 2.3.2

ppcls/losss/celoss.py 中 loss 在无label smooth时计算是不是有错, F.softmax后加了一个F.cross_entropy,默认情况下,F.cross_entropy中就有一个use_softmax=True ,用pytorch和tensorflow做了同样的试验,应该可以确认,是错了。你们确认一下。

def forward(self, x, label):
    if isinstance(x, dict):
        x = x["logits"]
    if self.epsilon is not None:
        class_num = x.shape[-1]
        label = self._labelsmoothing(label, class_num)
        x = -F.log_softmax(x, axis=-1)
        loss = paddle.sum(x * label, axis=-1)
    else:
        if label.shape[-1] == x.shape[-1]:
            label = F.softmax(label, axis=-1)
            soft_label = True
        else:
            soft_label = False
        loss = F.cross_entropy(x, label=label, soft_label=soft_label)
    loss = loss.mean()
    return {"CELoss": loss}
cuicheng01 commented 1 year ago

该模块是之前为了适配早期飞桨版本而为蒸馏适配做的,后期由于蒸馏模块在其他损失函数中实现,没能及时在新的飞桨版本中修复,由于很少使用到这个分支,所以没能及时发现,感谢你的有价值的issue,我们已经修复,拉取最新的代码即可~相关PR

RobinChiu commented 9 months ago

Base on the document,the label should be after F.softmax, the original should be correct. I try it without the F.softmax in ppcls/configs/quick_start/professional/R50_vd_distill_MV3_large_x1_0_CIFAR100.yaml. The loss will be negative or nan.

https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/functional/cross_entropy_cn.html#cross-entropy label (Tensor) – 输入 input 对应的标签值。若 soft_label=False,要求 label 维度为 [N1,N2,...,Nk] 或 [N1,N2,...,Nk,1] ,数据类型为'int32', 'int64', 'float32', 'float64',且值必须大于等于 0 且小于 C;若 soft_label=True,要求 label 的维度、数据类型与 input 相同,且每个样本各软标签的总和为 1。