CheXpert 数据集仍然过拟合图像分类

Posted

技术标签:

【中文标题】CheXpert 数据集仍然过拟合图像分类【英文标题】:STILL overfitting image classification for CheXpert dataset 【发布时间】:2020-10-29 19:13:50 【问题描述】:

我尝试仅根据其中一项观察结果(Alectasis)和 2 类分类问题(1 真,0 假)对来自 CheXpert 数据集的图像进行分类。 我通过将图像调整为 224x224 并对其进行标准化来预处理图像。我使用了 30,000 张图片进行训练(10% 验证)和 7,500 张测试图像。 作为模型,我在 ImageNet 上使用 预训练的 ResNet34。 运行模型时,它是过拟合的:训练损失减少到 0.043,而验证损失上升到 2.199,这导致测试准确率为 55.56%。 我尝试了以下尝试来防止过度拟合:

#尝试 1:我使用了带有 dropout 层的分类器

-> 验证损失在开始时减少,但在 6 个 epoch 后再次上升

#尝试 2:我在整个模型中添加了 dropout 层

-> 验证损失在开始时减少,但模型收敛非常缓慢。经过一些时期后,验证损失增加,模型也更快收敛

#尝试 3:我冻结了所有非线性层,只在最后一个线性层上拟合了模型

-> 网络似乎根本没有收敛,甚至在 50 个 epoch 之后也没有

使分类任务成为二元分类任务也没有改变。用 DenseNet121 尝试同样的事情也没有太大变化。

class ResNet(FitModule):
    def __init__(self, num_classes=2):
        super(ResNet, self).__init__()
        self.net = torchvision.models.resnet34(pretrained=True)
        # Change classifier
        kernel_count = self.net.fc.in_features
        self.net.fc = nn.Sequential(nn.Linear(kernel_count, 500), nn.Linear(500, num_classes))
        self.dropout = nn.Dropout(p=0.5)
        # Attempt 1: use classifier with dropout layers
        '''
        self.net.fc = nn.Sequential(
            nn.BatchNorm1d(kernel_count),
            nn.Dropout(p=0.5),
            nn.Linear(in_features=kernel_count, out_features=500),
            nn.ReLU(),
            nn.BatchNorm1d(500),
            nn.Dropout(p=0.5),
            nn.Linear(in_features=500, out_features=num_classes))
        '''


    def freeze_nonlinear_layers(self):
        self._freeze_layer(self.net.conv1)
        self._freeze_layer(self.net.bn1)
        self._freeze_layer(self.net.relu)
        self._freeze_layer(self.net.maxpool)
        self._freeze_layer(self.net.layer1)
        self._freeze_layer(self.net.layer2)
        self._freeze_layer(self.net.layer3)
        self._freeze_layer(self.net.layer4)
        self._freeze_layer(self.net.avgpool)


    def _freeze_layer(self, layer, freeze=True):
        if freeze:                              
            for p in layer.parameters():
                p.requires_grad = False
        else:                                   
            for p in layer.parameters():
                p.requires_grad = True

    def forward(self, inputs):
        # Attempt 2: build whole network with dropout layers
        '''
        out = self.net.conv1(inputs)
        out = self.net.bn1(out)
        out = self.net.relu(out)
        out = self.net.maxpool(out)
        out = self.dropout(out)
        out = self.net.layer1(out)
        out = self.dropout(out)
        out = self.net.layer2(out)
        out = self.dropout(out)
        out = self.net.layer3(out)
        out = self.dropout(out)
        out = self.net.layer4(out)
        out = self.dropout(out)
        out = self.net.avgpool(out)
        out = out.view(out.size(0), -1)
        out = self.net.fc(out)
        '''
        # Attempt 3: freeze nonlinear layers and only train last linear layer
        '''
        self.freeze_nonlinear_layers
        '''
        return out/self.net(inputs) # attempt 2/attempt 1,3

总结一下:要么网络不收敛,要么验证损失增加,测试准确率差。

【问题讨论】:

【参考方案1】:

您是否尝试过为您的火车图像添加新的变换。例如,您可能想要添加随机旋转或随机水平翻转。所有可用的转换都可以在这里找到pytorch transforms。如果我的模型过度拟合,我通常会这样做。不要将它们添加到您的验证或测试集中,它们仅用于训练图像。

【讨论】:

感谢您的回复。我试过transforms.RandomRotation(degrees=5)transforms.RandomHorizontalFlip(p=0.5)。但是在 4 个 epoch 之后,val loss 又开始上升,由此产生的测试精度很差。你有别的想法吗? 对于随机旋转,您可能希望角度更接近 90。5 度的转角一点也不大。你也试过降低你的学习率。目前是什么?【参考方案2】:

请尝试冻结到第 3 层,并尝试在前 10 个 epoch 训练模型。如果您没有看到任何过度拟合的问题,请尝试降低学习率并相应地进行。让我们知道这是否有效。

【讨论】:

感谢您的回复。我尝试了您的方法,但验证损失在第一个时期后立即开始上升。您还有其他想法吗?

以上是关于CheXpert 数据集仍然过拟合图像分类的主要内容,如果未能解决你的问题,请参考以下文章

这是过拟合的情况吗? CNN图像分类器

为啥我的 CNN 预训练图像分类器过拟合?

利用CNN进行图像分类的流程(猫狗大战为例)

Keras:过拟合模型?

使用迁移学习的单类数据集进行图像分类

使用迁移学习对单类数据集进行图像分类[关闭]