Skip to content

Instantly share code, notes, and snippets.

@YimianDai
Last active August 4, 2019 06:08
Show Gist options
  • Save YimianDai/7032b6762c0e5e769449000c6ce485f7 to your computer and use it in GitHub Desktop.
Save YimianDai/7032b6762c0e5e769449000c6ce485f7 to your computer and use it in GitHub Desktop.
SoftmaxCrossEntropyLoss

SoftmaxCrossEntropyLoss

__init__

    def __init__(self, sparse_label=True, batch_axis=0, ignore_label=-1,
                 size_average=True, **kwargs):
  • ignore_label=-1 这里的 ignore_label-1,这里是可以设置的,但是在 SegmentationMetric 中是强制 ignore_label-1 的,因此,如果要在 SoftmaxCrossEntropyLoss 中不要忽略背景,而要在 SegmentationMetric 中忽略背景,可以把读入数据的背景类别设置成 -1,然后在调用 SoftmaxCrossEntropyLoss 中设置 ignore_label0

hybrid_forward

  • softmaxout = F.SoftmaxOutput(pred, label, ignore_label)
    • pred 是 N x C x H x W,label 是 N x H x W
    • 这里的 label 即使对于计算 softmaxout 本身是用不到的,但是 Backward 会用到;同理,ignore_label 也是对于计算 softmaxout 本身是用不到,但是会让对应 label 的梯度为 0
    • 得到的 softmaxout 也是 N x C x H x W
  • loss = -F.pick(F.log(softmaxout), label, axis=1, keepdims=True)
    • pick 函数,axis=1 指定了是对 C 挑选出 index(也就是 label)对应的 softmaxout 输出,由于 keepdims=True 得到的 loss 是 N x 1 x H x W
  • loss = F.where(label.expand_dims(axis=1) == self._ignore_label, F.zeros_like(loss), loss)
    • label.expand_dims(axis=1) 后的形状是 N x 1 x H x W,这么做是为了和形状同为 N x 1 x H x W 的 loss 可以一起用于 where 函数
    • where(cond, A, B) 如果 cond 中的为 True,则选 A 中对应位置上的返回,否则选 B 对应位置上的
    • 这句代码也就是如果预测的是 ignored label,则令其 loss 为 0,否则就返回对应的 loss
    • 从这里可以看出,如果是背景-前景二分类,那么令背景为 ignored 是不对的,那样网络只会往全部预测成前景的方向去优化,因为背景的 loss 被 ignore 了,所以在计算 loss 时,不可以将背景的 label 设置为 ignore label
  • F.mean(loss, axis=self._batch_axis, exclude=True)
    • self._batch_axis 默认是 0,对于 N x 1 x H x W 的 loss,求完均值后返回的大小为 N 的 Array,也就是只有 axis = 0 被保留下来了。

像 SSD 的 cls_pred 的大小是 B x N x (C + 1),cls_target 的大小是 B x N,box_targets 的大小是 B x N x 4,因此除非交换 axis,SSD 的分类损失是不可以直接调用 SoftmaxCrossEntropyLoss 的,因为 SoftmaxCrossEntropyLoss 是设置了 axis=1 是分类类别的 Channel,而 SSD 则是 axis = 2 才是分类的 Channel。

只要数据格式是 B x C [ x H x W ] 就可以直接用 SoftmaxCrossEntropyLoss,SSD 的输出和标签不符合这个,所以不可以直接调用。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment