ResNet50 torchvision 实现在 CIFAR-10 上的精度较低

ResNet50 torchvision implementation gives low accuracy on CIFAR-10

我是深度学习和 PyTorch 的新手。我在 cifar10 上的 torchvision 模块中使用 resnet-50 模型。我已经从 torchvision 导入了 CIFAR-10 数据集。测试的准确性非常低,我尝试配置分类层,但准确性没有变化。我的代码有问题吗?我计算准确度有误吗?

import torchvision
import torch
import torch.nn as nn
from torch import optim
import os
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import numpy as np
from collections import OrderedDict
import matplotlib.pyplot as plt

transformations=transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])])
trainset=torchvision.datasets.CIFAR10(root='./CIFAR10',download=True,transform=transformations,train=True)

testset=torchvision.datasets.CIFAR10(root='./CIFAR10',download=True,transform=transformations,train=False)

trainloader=DataLoader(dataset=trainset,batch_size=4)
testloader=DataLoader(dataset=testset,batch_size=4)

inputs,labels=next(iter(trainloader))
labels=labels.float()
inputs.size()

print(labels.type())
resnet=torchvision.models.resnet50(pretrained=True)

if torch.cuda.is_available():
  resnet=resnet.cuda()
  inputs,labels=inputs.cuda(),torch.Tensor(labels).cuda()

outputs=resnet(inputs)
outputs.size()

for param in resnet.parameters():
  param.requires_grad=False

numft=resnet.fc.in_features
print(numft)
resnet.fc=torch.nn.Sequential(nn.Linear(numft,1000),nn.ReLU(),nn.Linear(1000,10))
resnet.cuda()
resnet.train(True)
optimizer=torch.optim.SGD(resnet.parameters(),lr=0.001,momentum=0.9)
criterion=nn.CrossEntropyLoss()

for epoch in range(5):
    resnet.train(True)

    trainloss=0
    correct=0
    for x,y in trainloader:
        x,y=x.cuda(),y.cuda()
        optimizer.zero_grad()

        yhat=resnet(x)
        loss=criterion(yhat,y)

        loss.backward()
        optimizer.step()
        trainloss+=loss.item()



    print('Epoch: {} Loss: {}'.format(epoch,(trainloss/len(trainloader))))

    accuracy=[]
    running_corrects=0.0
    for x_test,y_test in testloader:

        x_test,y_test=x_test.cuda(),y_test.cuda()
        yhat=resnet(x_test)
        _,z=yhat.max(1)
        running_corrects += torch.sum(y_test == z)

    accuracy.append(running_corrects/len(testloader))

print(running_corrects/len(testloader))
accuracy=max(accuracy)
print(accuracy)

TRAINING/TESTING

之后的输出
Epoch: 0 Loss: 1.9808503997325897
Epoch: 1 Loss: 1.7917569598436356
Epoch: 2 Loss: 1.624434965057373
Epoch: 3 Loss: 1.4082191940283775
Epoch: 4 Loss: 1.1343850775527955
tensor(1.1404, device='cuda:0')
tensor(1.1404, device='cuda:0')

我的一些观察:

  1. 您可能想要微调学习率、时期数和批量大小。例如,目前您只训练模型五个时期,这可能不足以达到高精度。您可以尝试使用更大的纪元值。
  2. 您是否尝试过通过设置 `param.requires_grad=True 为 CIFAR10 数据集调整 backbone(特征提取器)模型?因为原始模型是在 imagenet 上训练的,可能需要在 CIFAR10 上进行适配。
  3. 在 evaluation/testing 之前,您可能想设置 resnet.train(False)resnet.eval() 以让模型知道您处于评估模式。此外,您可能希望使用 with torch.no_grad():no_grad() 范围内评估您的模型,这将加快推理时间并减少内存使用。
  4. [CIFAR-10 是一个平衡数据集,因此它是一个可选的 (EDA) 任务。]您是否检查过 CIFAR10 的 class 分布是否符合它是否是一个不平衡的数据集?如果它是一个不平衡的数据集,您可能需要使用加权交叉熵来计算损失。还有其他策略可以解决 class-不平衡,例如过采样或欠采样。

关于测试准确率,您需要将正确预测的总数除以数据集中的样本总数,len(testloader.dataset)而不是len(testloader)。如果您希望精度在 [0,100] 范围内,只需乘以 100。您可以打印每个时期的测试精度,以检查它是如何变化的,而您当前显示的是最大精度。