问题描述
所以我有一些带注释的图像,我想用它们来训练二值图像分类器,但我在创建数据集和实际训练测试模型时遇到了问题。每个图像要么属于某个类别,要么不属于某个类别,所以我想使用 PyTorch 设置一个二元分类数据集/模型。我有一些问题:
- 标签应该是浮动的还是长的?
- 我的标签应该是什么形状?
- 我正在使用来自 torchvision 模型的 resnet18 类,我的最终 softmax 层应该有一个还是两个输出?
- 如果我的批量大小为 200,我的目标应该是什么形状?
- 我的输出应该是什么形状?
提前致谢
报价 删除
解决方法
二元分类与多标签分类略有不同:对于多标签,您的模型预测每个样本的“logits”的向量,并使用 softmax 将 logits 转换为概率;在二元情况下,模型预测每个样本的标量“logit”,并使用 sigmoid 函数将其转换为类别概率。
在 pytorch 中,softmax 和 sigmoind 被“折叠”到损失层(出于数值稳定性考虑),因此两种情况有不同的交叉熵损失层:nn.BCEWithLogitsLoss
用于二进制case(使用 sigmoid)和 nn.CrossEntropyLoss
用于多标签案例(使用 softmax)。
在您的情况下,您想使用二进制版本(带有 sigmoid):nn.BCEWithLogitsLoss
。
因此,您的标签应该是 torch.float32
类型(与网络输出相同的 float
类型)而不是整数。
每个样本应该有一个单个标签。因此,如果您的批次大小为 200,则目标应具有形状 (200,1)
。
我将把它留在这里作为练习来说明训练具有两个输出和 CE+softmax 的模型等效于二进制输出 + sigmoid ;)