Python Keras-带权重的多标签分类

Python Keras-带权重的多标签分类,python,keras,loss-function,Python,Keras,Loss Function,我试图对一些CXR图像进行分类,这些图像在每个样本中都有多个标签。据我所知,我必须把一个密集层与乙状激活,并使用二进制交叉熵作为我的损失函数。问题是存在着严重的阶级不平衡(正常人比异常人多得多)。我很好奇,这是我目前的模型: from keras_applications.resnet_v2 import ResNet50V2 from keras.layers import GlobalAveragePooling2D, Dense from keras import Sequential R

我试图对一些CXR图像进行分类,这些图像在每个样本中都有多个标签。据我所知,我必须把一个密集层与乙状激活,并使用二进制交叉熵作为我的损失函数。问题是存在着严重的阶级不平衡(正常人比异常人多得多)。我很好奇,这是我目前的模型:

from keras_applications.resnet_v2 import ResNet50V2
from keras.layers import GlobalAveragePooling2D, Dense
from keras import Sequential
ResNet = Sequential()
ResNet.add(ResNet50V2(input_shape=shape, include_top=False, weights=None,backend=keras.backend,
    layers=keras.layers,
    models=keras.models,
    utils=keras.utils))
ResNet.add(GlobalAveragePooling2D(name='avg_pool'))

ResNet.add(Dense(len(label_counts), activation='sigmoid', name='Final_output'))
正如我们所看到的,我正在使用sigmoid来获得输出,但是对于如何实现权重,我有点困惑。我想我需要使用一个使用BCE的自定义损失函数(use_logits=true)。大概是这样的:

xent = tf.losses.BinaryCrossEntropy(
    from_logits=True,
    reduction=tf.keras.losses.Reduction.NONE)
loss = tf.reduce_mean(xent(targets, pred) * weights))
所以它将输出视为logit,但我不确定的是最终输出的激活。我是将其与乙状结肠激活一起保存,还是使用线性激活(未激活)?我假设我们保留了sigmoid,只是将其视为logit,但我不确定pytorches“
torch.nn.BCEWithLogitsLoss
”包含一个sigmoid层

编辑:找到以下内容:

根据:pgaleone

from_logits=True意味着损失函数需要线性张量 (网络的输出层没有任何激活功能,但是 身份),因此您必须删除乙状结肠,因为它将是 丢失函数本身,将softmax应用于网络输出,以及 然后计算交叉熵


实际上,您不希望在多标签分类中使用来自_logits的

根据文件[1]:

登录:按标签激活,通常为线性输出。这些活化能被解释为非标准化对数概率

所以你说的没错,当激活函数设置为True时,你不想使用它

然而,文件还说

警告:此op需要无标度的logits,因为它在内部对logits执行softmax以提高效率。不要使用softmax的输出调用此op,因为它将产生不正确的结果

Softmax针对每个定义优化一个类。这就是softmax的工作原理。既然你在做多标签分类,你应该使用sigmoid,就像你提到的那样

这意味着,如果要使用sigmoid,则不能使用来自_logits
,因为它会在sigmoid之后应用softmax,这通常不是您想要的

解决方案是删除此行:

from_logits=True,

[1]

当然可以,我知道它内置了BCE,而且透镜(标签计数)很好。我的问题是在底部,当使用
BCE(from_logits=True)
时,我是否需要一个带有
sigmoid
激活的密集层?你是对的,但我正在进行
多标签
分类(标题中)。Hrmm有趣的是,在多标签分类中,我们不想使用softmax,因为它只会改进一个类。但我不知道它在内部使用softmax。是的,我指的是多标签。将更新答案。你的问题解决了吗?请为将来的读者做标记。