语义分割的样本权重

Posted

技术标签:

【中文标题】语义分割的样本权重【英文标题】:Sample Weights for Semantic Segmentation 【发布时间】:2020-09-12 12:36:44 【问题描述】:

我尝试使用 Keras 和 Tensorflow2 后端解决语义分割问题。我尝试将每个像素标记为具有分类交叉熵的 22 个类别之一。我的输入和输出的形状是

Input: (None, 224, 224, 3)

Output: (None, 224, 224, 23) 22 and 1 for background

我想为每个样本添加权重,以尝试使用我的模型进行伪标记。对于样本权重,我尝试创建一个样本权重数组,它是一个一维数组,长度与批量大小相同。但它失败并给出了以下错误:

weights can not be broadcast to values. values.rank=3. weights.rank=1.

然后我尝试将 3D 数组 (16, 224, 224) 作为批量大小为 16 的样本权重,它给出了以下错误:

Found a sample_weight array with shape (16, 224, 224).
In order to use timestep-wise sample weights, you should specify sample_weight_mode="temporal" in compile(). 
If you just mean to use sample-wise weights, make sure your sample_weight array is 1D.

【问题讨论】:

我在尝试对 tf.keras 中的不同图像进行加权时遇到了类似的问题。你有进步吗? 就我而言,不,我无法取得任何进展。但是如果你的输出只是标量类标签而不是二维数组,你可以使用 fit 方法的 sample_weight 参数。如果您有自定义数据生成器,则在每个批次的数据生成器的 get_item 方法中返回您的样本权重数组。 【参考方案1】:

我设法解决了具有多个输出的 TF2 的类似问题,并在 model.compile 中使用了 loss_weights。这样,用于训练网络的最终损失是每个损失的加权和。在我的例子中,我有 2 个类而不是 23 个,因此您需要修改这 23 个类的代码。还要注意代码中的层 c9 有 3 个过滤器,因此您可能需要增加它。

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.losses import BinaryCrossentropy
from tensorflow.keras.optimizers import Adam
# build your CNN
inputs = Input((224, 224, 1), name='inputs')
c1 = Conv2D(64, (3, 3), activation='relu', padding='same')(inputs)
...
c9 = Conv2D(3, (3, 3), activation='relu',padding='same')(c9)

output_0 = Conv2D(1, (1, 1), name='class0')(c9)
output_1 = Conv2D(1, (1, 1), name='class1')(c9)

model = Model(inputs=inputs, outputs=[output_0, output_1])
model.compile(optimizer=Adam(learning_rate=0.001, name='adam'),
              loss=[BinaryCrossentropy(from_logits=True), BinaryCrossentropy(from_logits=True)],
              loss_weights=[1, 1000],
              metrics=[["accuracy"], ["accuracy", "mse"]])

此外,您可以在数据生成器中定义一个采样 pdf,例如,您可以向网络提供属于一个类的对象多于背景的对象。效果可能类似于使用加权损失函数。最后,网络会尝试最小化平均损失值,因此如果您添加更多一个类别的样本,该平均损失值将精确地受到该类别结果的影响。

【讨论】:

我不明白你的方法,第二个输出的真实值是多少? 对于二值分割,第一个输出是前景的预测,第二个是背景的预测(1-foreground)。您有两个输出,每个输出都有一个通道,并且每个输出都使用二元交叉熵 (CCE),而不是具有 2 个通道的输出并使用分类交叉熵。如果你使用 loss_weights = [1,1] 你会得到与 CCE 相似的结果。但是,如果你使用 loss_weights = [10, 1],那么前景像素预测中的错误会受到更多的惩罚。 好的,我现在明白你的意思了,谢谢你的回答。然而,这并不是我真正想要的。我想加权整个图像样本而不是特定类。我想我能做的唯一解决方案是为该图像样本的像素赋予相同的权重,并为所有其他图像样本的像素赋予 1 的权重。 我明白了。我建议使用以下方法:***.com/a/48577360/13319360

以上是关于语义分割的样本权重的主要内容,如果未能解决你的问题,请参考以下文章

论文速递ECCV2022 - 密集高斯过程的小样本语义分割

ICCV 2021 | 简而优:用分类器变换器进行小样本语义分割

论文精选TPAMI2020 - PFENet_先验引导的特征富集网络_小样本语义分割

论文速递ICCV2021 - 基于超相关压缩实现实时高精度的小样本语义分割

图像语义分割

图像语义分割