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

about loss implementation #36

Open
foralliance opened this issue Jan 4, 2019 · 6 comments
Open

about loss implementation #36

foralliance opened this issue Jan 4, 2019 · 6 comments
Labels
bug Something isn't working

Comments

@foralliance
Copy link

foralliance commented Jan 4, 2019

@louis-she HI

在paper中,在计算loss时,有这样的描述:

The two terms are normalized by Ncls and Nreg , and weighted by a balancing parameter λ . 
In our implementation, the cls term is normalized by the number of positive and negative anchors, and the reg term is normalized by the number of positive anchors.  Because of the imbalance between the number of positive and negative anchors, λ is used to balance these two loss terms.

换句话说,理论上,分类损失除以(正样本+负样本)个数,回归损失除以(正样本)个数,然后给分类损失乘以一个权重(4).
比如正样本个数是100,那么分类损失就是除以400,然后乘以4;回归损失就是除以100.

但在code中,在计算2个损失时,

loss_class = 4 * F.cross_entropy(total_effective_pred, total_targets)
loss_reg = F.smooth_l1_loss(total_t, total_gt)

此时,相当于分类损失和回归损失都除以了(正样本+负样本)个数,都是400

那么再给分类损失乘以权重4是不是有问题啊??

@louis-she
Copy link
Owner

louis-she commented Jan 5, 2019

分类损失除以(正样本+负样本)个数,回归损失除以(正样本)个数

total_effective_pred 和 total_targets 就是只包含正样本的哈

@foralliance
Copy link
Author

我是基于你的training-v2分支进行分析的,
training-v2分支中,分类损失乘以了4:
loss_class = 4 * F.cross_entropy(total_effective_pred, total_targets)
master分支中,分类损失没有乘以4:
loss_class = F.cross_entropy(total_effective_pred, total_targets)
我认为master分支中才是合理的,不应该乘以4.

另外根据你的code,通过debug分析,total_effective_pred 和 total_targets 应该包含的是(正样本+负样本),请你再确认下:

effective_preds = torch.cat((cls_preds[pos_indices], neg_cls_preds[neg_indices]))
targets = torch.cat((pos_targets, neg_targets))

@louis-she
Copy link
Owner

Ahh sorry.. 分类Loss肯定是要包含正负样本的,回归Loss只会包含正样本(负样本没办法回归)

分类损失和回归损失都除以了(正样本+负样本)个数,都是400.

所以这里 回归损失 并没有除以所有样本数,只除以了正样本数,因为:

loss_reg = F.smooth_l1_loss(total_t, total_gt)

如果你跟一下 total_t 和 和 total_gt,是只包含正样本的

@foralliance
Copy link
Author

foralliance commented Jan 5, 2019

smooth_l1_loss中的total_t, total_gt确实只包含正样本.这点没问题.

对于loss_reg = F.smooth_l1_loss(total_t, total_gt),参数size_average默认为True,即要除以样本数

我一开始和你认为一样,既然total_t, total_gt只包含了正样本,那么在计算smooth_l1_loss时,除以的就应该是(正样本)个数(100).但是昨天在发现,虽然total_t, total_gt只包含了正样本,但是在计算smooth_l1_loss时,除以的却是(正样本+负样本)个数(400).
你可以debug跟一下.

@louis-she
Copy link
Owner

louis-she commented Jan 5, 2019

https://github.com/pytorch/pytorch/blob/eb3cabffd69e37162a3fe0bb1bbfa3de83404f3a/torch/nn/modules/loss.py#L748-L751

因为 smooth_l1_loss 的每个样本都含有4个值(坐标),所以最后 reduction = 'mean' 在算均值的时候,实际是除以 样本数 * 4 ,所以这里除了400,这个400并不是正样本+负样本。所以这里应该修改为:

loss_reg = F.smooth_l1_loss(total_t, total_gt, reduction='sum') / total_t.size(0)

确实是个问题,感谢提出!会抽空修复这个问题。另外也非常欢迎提PR

@louis-she louis-she added the bug Something isn't working label Jan 5, 2019
@foralliance
Copy link
Author

虽然结果一样,但我还是理解错了,也谢谢你的提醒.

另外对于master分支,其实不用改,本身就是:

loss_class = F.cross_entropy(  total_effective_pred, total_targets)
loss_reg = F.smooth_l1_loss(total_t, total_gt)
loss = loss_class + loss_reg

我是基于training-v2这个分支分析时,才发现了这个权重4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants