from_logits=True和from_logits=False获取不同的培训结果分类交叉熵联合国

2024-10-05 10:14:45 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我为最后一层设置Softmax Activation,我使用unet执行图像语义分割工作:

...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
conv10 = (Activation('softmax'))(conv9)
model = Model(inputs, conv10)
return model
...

然后使用loss = tf.keras.losses.CategoricalCrossentropy(from_logits=False) 即使只对一个训练图像,训练也不会收敛。在

但如果我不为最后一层设置Softmax Activation,如下所示:

^{pr2}$

然后使用loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True) 对于一个训练图像,训练将收敛。在

我的groundtruth数据集是这样生成的:

X = []
Y = []
im = cv2.imread(impath)
X.append(im)
seg_labels = np.zeros((height, width, n_classes))
for spath in segpaths:
    mask = cv2.imread(spath, 0)
    seg_labels[:, :, c] += mask
Y.append(seg_labels.reshape(width*height, n_classes))

为什么?我的用法有问题吗?在

这是我的git实验代码:https://github.com/honeytidy/unet 您可以签出并运行(可以在cpu上运行)。你可以改变激活层和分类交叉熵的逻辑,看看我说了什么。在


Tags: 图像unetlabelsmodeltfactivationclasseskeras
3条回答

我想问题出在softmax激活函数上。查看doc我发现默认情况下sotmax应用于最后一个轴。你能看看model.summary()并检查一下这是否是你想要的吗?在

将“softmax”激活推到交叉熵损失层可以显著简化损失计算,并使其在数值上更稳定。
在您的例子中,可能是数值问题严重到使from_logits=False选项的培训过程无效的情况。在

你可以在this post中找到交叉熵损失(信息增益损失的一个特例)的推导。这一推导说明了将softmax与交叉熵损失相结合时避免的数值问题。在

要使softmax正常工作,必须确保:

  • 您正在使用'channels_last'作为Keras的默认通道配置。在

    • 这意味着模型中的形状将类似于(None, height, width, channels)
    • 这似乎是您的情况,因为您将n_classes放在最后一个轴上。但这也很奇怪,因为您使用的是Conv2D,而您的输出{}应该是{},而不是您使用的那个奇怪的形状。在
  • 您的Y只有0和1(而不是像通常对图像那样的0和255)

    • 检查Y.max() == 1和{}
    • 您可能需要Y = Y / 255.
  • 只有一个类是正确的(您的数据没有多个值为1的路径/通道)。在

    • 检查(Y.sum(axis=-1) == 1).all()是否为True

相关问题 更多 >

    热门问题