如何将权重应用于 Tensorflow 中的 sigmoid 交叉熵损失函数?

min*_*als 3 python tensorflow

训练数据集包含两个类 A 和 B,我们分别表示为10在我们的目标标签中。Out 标签数据严重偏向于类0,该类占了大约 95% 的数据,而我们的类1仅占 5%。在这种情况下,我们应该如何构建我们的损失函数?

我发现 Tensorflow 有一个可以与权重一起使用的函数:

tf.losses.sigmoid_cross_entropy
Run Code Online (Sandbox Code Playgroud)

weights作为损失的系数。如果提供了标量,则损失仅按给定值进行缩放。

听起来不错。我将权重设置为 2.0 以增加损失并更多地惩罚错误。

loss = loss_fn(targets, cell_outputs, weights=2.0, label_smoothing=0)
Run Code Online (Sandbox Code Playgroud)

然而,不仅损失没有下降,反而增加了,数据集的最终准确率略有下降。好吧,也许我误解了它应该 < 1.0,我尝试了一个较小的数字。这没有改变任何东西,我得到了几乎相同的损失和准确性。o_o

不用说,在相同数据集上训练的相同网络但损失权重为 0.3,在 Torch/PyTorch 中显着减少了多达 x10 倍的损失。

有人可以解释一下如何在 Tensorflow 中使用损失权重吗?

Pet*_*dan 5

如果您使用标量缩放损失,例如 2.0,那么基本上您是在乘以损失,从而乘以反向传播的梯度。这类似于增加学习率,但不完全相同,因为您也在更改正则化损失(例如权重衰减)的比率。

如果您的类严重偏斜,并且您想在计算损失时对其进行平衡,那么您必须指定一个张量作为权重,如手册中所述tf.losses.sigmoid_cross_entropy()

weights:可选张量,其等级为 0,或与标签相同的等级,并且必须可广播到标签(即,所有维度必须为 1,或与相应的损失维度相同)。

这就是使 0 类的权重张量为 1.0,而 1 类的权重张量可能为 10,现在“假阴性”损失将被计算得更重。

这是一门艺术,你应该在多大程度上超过代表性不足的阶级。如果你做得太多,模型就会崩溃,并且会一直预测超重的类别。

实现相同目的的另一种方法是使用tf.nn.weighted_cross_entropy_with_logits(),它具有pos_weight完全相同的目的的参数。但它tf.nn不是,tf.losses所以您必须手动将其添加到损失集合中。

通常处理这个问题的另一种方法是在抽样时任意增加代表性不足的类的比例。然而,这也不应该过分。你也可以做这两件事。