首先需要说明的是PyTorch里面的BCELoss和CrossEntropyLoss都是交叉熵,数学本质上是没有区别的,区别在于应用中的细节。

BCE适用于0/1二分类,计算公式就是 “ -ylog(y^hat) - (1-y)log(1-y^hat) ”,其中y为GT,y_hat为预测值。这样,当gt为0的时候,公式前半部分为0,y^hat需要尽可能为0才能使后半部分数值更小;当gt为1时,后半部分为0,y^hat需要尽可能为1才能使前半部分的值更小,这样就达到了让y^hat尽量靠近gt的预期效果。当然,显然这要求输入必须在0-1之间,所以为了让网络的输出确保在0-1之间,我们一般都会加一个Sigmoid,而更具体一点来说,使用BCELoss的话只需要网络输出一个节点即可,不像CE Loss那样,往往是有n_class个类就需要网络最终输出n_class个节点。

而CE因为需要用在多分类上,所以计算公式就变成了sum(-ylog(y^hat))。可能有些同学很敏锐的发现了,这个函数实际上只是在对相应gt=1的那个节点的值做约束,希望这一点的输出能尽量为1;而其他原本gt为0的节点因为y=0,在计算到sum中的时候无论其相应输出节点是多少都没有关系,那这是不是意味着CE的公式还有漏洞呢?话虽这么说,但其实是因为我们忘记了CE之前还有Softmax这个函数,这个函数会让输入的n_class个节点中大的更大,小的更小,并且可以确保最终所有节点的输出的总和为1,这样一来只要对应gt=1的那个节点输出足够靠近1,其他的节点自然输出就会趋近于0了。

上面的两个例子都是在分类任务中说的,而在分割任务中,BCE和CE的另一个区别就可以说是,BCE只需要输出一个通道,而CE需要输出n_class个通道。

05-11 19:21