如何获取对数作为神经网络输出



简单而简短的问题。我有一个执行图像分割的网络(Unet)。我希望对数作为输出输入到交叉熵损失中(使用 pytorch)。目前,我的最后一层如下所示:

class Logits(nn.Sequential):
def __init__(self, 
in_channels, 
n_class
):
super(Logits, self).__init__()
# fully connected layer outputting the prediction layers for each of my classes
self.conv = self.add_module('conv_out', 
nn.Conv2d(in_channels, 
n_class, 
kernel_size = 1
)
)
self.activ = self.add_module('sigmoid_out', 
nn.Sigmoid()
)

在这里使用 sigmoid 激活功能是否正确?这能给我对数吗?

当人们谈论"logits"时,他们通常指的是"原始"n_class维输出向量。对于多类分类(n_class> 2),您希望将原始"logits"的n_class维向量转换为n_class-dim概率向量.
也就是说,您希望对所有n_class条目进行prob_i >= 0prob = f(logits),并且sum(prob)=1.
以可微分的方式执行此操作的最直接方法是使用 Softmax 函数:

prob_i = softmax(logits) = exp(logits_i) / sum_j exp(logits_j)

很容易看出,softmax的输出确实是一个n_class暗的概率向量(我把它留给你作为一个简短的练习)。

顺便说一句,这就是为什么原始预测被称为"logits",因为它们是输出预测概率的"日志"。

现在,习惯上不会在分类网络之上显式计算softmax,而是将其计算推迟到损失函数,例如nn.CrossEntropyLoss内部计算softmax,并需要原始对数作为输入,而不是归一化概率。这样做主要是为了数值稳定性。

因此,如果您正在使用nn.CrossEntropyLoss训练多类分类网络,则完全不需要担心最终激活,只需从最终的卷积/线性层输出原始对数.
最重要的是,不要使用nn.Sigmoid()激活,因为它往往具有饱和梯度并且会弄乱您的训练。

据我了解,您正在处理多标签分类任务,其中单个输入可以有多个标签,因此您使用nn.Sigmoid(与多类分类的nn.Softmax相比)。

有一个结合nn.Sigmoidnn.BCELoss的损失函数:nn.BCEWithLogitsLoss。因此,您将有一个对数向量作为输入,其长度是类的数量。而且,目标也将具有相同的形状:作为多热编码,活动类具有1s。

最新更新