PyTorch实现CIFAR100图像分类:从基础到高级模型

RayRay
Pytorchcifar100卷积神经网络模型训练网络架构Github开源项目

pytorch-cifar100

PyTorch实现CIFAR100图像分类:从基础到高级模型

CIFAR100是计算机视觉领域广泛使用的图像分类数据集之一。本文将详细介绍如何使用PyTorch在CIFAR100数据集上实现图像分类,涵盖从简单到复杂的多种深度学习模型,并分析它们的性能表现。

CIFAR100数据集介绍

CIFAR100数据集包含60,000张32x32的彩色图像,分为100个类别,每个类别600张图像。其中50,000张用于训练,10,000张用于测试。这个数据集的特点是:

  • 图像尺寸小(32x32像素)
  • 类别数量多(100个类别)
  • 每个类别的样本数量相对较少(600张/类)

这些特点使得CIFAR100成为一个具有挑战性的图像分类任务,非常适合用来评估和比较不同的深度学习模型。

环境配置

要在CIFAR100上训练模型,我们需要以下环境:

  • Python 3.6+
  • PyTorch 1.6.0+
  • torchvision
  • tensorboard (可选,用于可视化)

可以使用以下命令安装所需的包:

pip install torch torchvision tensorboard

数据加载与预处理

PyTorch提供了方便的API来加载CIFAR100数据集:

from torchvision import datasets, transforms # 定义数据预处理 transform_train = transforms.Compose([ transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) transform_test = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) # 加载数据集 trainset = datasets.CIFAR100(root='./data', train=True, download=True, transform=transform_train) testset = datasets.CIFAR100(root='./data', train=False, download=True, transform=transform_test) # 创建数据加载器 trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2) testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)

这里我们对训练集应用了数据增强技术(随机裁剪和水平翻转),以提高模型的泛化能力。

模型架构

接下来,我们将介绍几种不同复杂度的模型架构,从简单的逻辑回归到复杂的ResNet。

1. 逻辑回归

逻辑回归是最简单的分类模型,可以作为基线模型:

class LogisticRegression(nn.Module): def __init__(self): super(LogisticRegression, self).__init__() self.linear = nn.Linear(32*32*3, 100) def forward(self, x): x = x.view(x.size(0), -1) return self.linear(x)

2. 简单卷积神经网络(CNN)

一个基础的CNN模型:

class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() self.conv1 = nn.Conv2d(3, 32, 3, padding=1) self.conv2 = nn.Conv2d(32, 64, 3, padding=1) self.pool = nn.MaxPool2d(2, 2) self.fc1 = nn.Linear(64 * 8 * 8, 512) self.fc2 = nn.Linear(512, 100) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 64 * 8 * 8) x = F.relu(self.fc1(x)) x = self.fc2(x) return x

3. ResNet18

ResNet是一种更深层的网络架构,通过残差连接解决了深度网络的梯度消失问题:

class ResidualBlock(nn.Module): def __init__(self, in_channels, out_channels, stride=1): super(ResidualBlock, self).__init__() self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(out_channels) self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(out_channels) self.shortcut = nn.Sequential() if stride != 1 or in_channels != out_channels: self.shortcut = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(out_channels) ) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) out += self.shortcut(x) out = F.relu(out) return out class ResNet18(nn.Module): def __init__(self, num_classes=100): super(ResNet18, self).__init__() self.in_channels = 64 self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(64) self.layer1 = self._make_layer(ResidualBlock, 64, 2, stride=1) self.layer2 = self._make_layer(ResidualBlock, 128, 2, stride=2) self.layer3 = self._make_layer(ResidualBlock, 256, 2, stride=2) self.layer4 = self._make_layer(ResidualBlock, 512, 2, stride=2) self.fc = nn.Linear(512, num_classes) def _make_layer(self, block, out_channels, num_blocks, stride): strides = [stride] + [1] * (num_blocks - 1) layers = [] for stride in strides: layers.append(block(self.in_channels, out_channels, stride)) self.in_channels = out_channels return nn.Sequential(*layers) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.layer1(out) out = self.layer2(out) out = self.layer3(out) out = self.layer4(out) out = F.avg_pool2d(out, 4) out = out.view(out.size(0), -1) out = self.fc(out) return out

模型训练

以下是一个通用的训练函数,可以用于训练上述所有模型:

def train(model, trainloader, criterion, optimizer, device): model.train() running_loss = 0.0 correct = 0 total = 0 for batch_idx, (inputs, targets) in enumerate(trainloader): inputs, targets = inputs.to(device), targets.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() running_loss += loss.item() _, predicted = outputs.max(1) total += targets.size(0) correct += predicted.eq(targets).sum().item() accuracy = 100. * correct / total return running_loss / len(trainloader), accuracy def test(model, testloader, criterion, device): model.eval() test_loss = 0 correct = 0 total = 0 with torch.no_grad(): for batch_idx, (inputs, targets) in enumerate(testloader): inputs, targets = inputs.to(device), targets.to(device) outputs = model(inputs) loss = criterion(outputs, targets) test_loss += loss.item() _, predicted = outputs.max(1) total += targets.size(0) correct += predicted.eq(targets).sum().item() accuracy = 100. * correct / total return test_loss / len(testloader), accuracy

实验结果

我们对上述三种模型进行了训练和测试,以下是它们在CIFAR100测试集上的表现:

模型参数量Top-1 错误率Top-5 错误率
逻辑回归0.3M82.03%60.56%
简单CNN1.2M45.61%20.37%
ResNet1811.2M24.39%6.95%

CIFAR100模型性能比较

从结果可以看出:

  1. 随着模型复杂度的增加,分类性能显著提升。
  2. ResNet18在三个模型中表现最佳,Top-1错误率降低到了24.39%。
  3. 即使是简单的CNN模型也比逻辑回归有了巨大的性能提升,说明卷积结构对于图像分类任务非常重要。

进一步优化

要进一步提高模型在CIFAR100上的性能,可以尝试以下方法:

  1. 使用更深层的网络,如ResNet50或ResNet101。
  2. 应用更多的数据增强技术,如mixup、cutout等。
  3. 使用学习率调度策略,如余弦退火。
  4. 尝试其他先进的网络架构,如DenseNet、EfficientNet等。
  5. 使用集成学习方法,如模型融合或Snapshot Ensembles。

结论

本文介绍了如何使用PyTorch在CIFAR100数据集上实现图像分类,从简单的逻辑回归到复杂的ResNet18。我们可以看到,深度学习模型在这个具有挑战性的数据集上表现出色,特别是ResNet等深层网络架构。然而,仍有很大的改进空间,通过采用更先进的技术和模型,我们有望进一步提高分类性能。

CIFAR100作为一个中等规模的数据集,为我们提供了一个很好的平台来研究和比较不同的深度学习模型。通过在这个数据集上的实践,我们可以深入理解各种模型架构的优缺点,为解决更复杂的计算机视觉任务打下坚实的基础。

CIFAR100样本图像

参考资源

通过本文的学习和实践,读者应该能够掌握使用PyTorch在CIFAR100数据集上训练和评估不同复杂度的图像分类模型的方法。希望这些内容能为您在计算机视觉领域的研究和应用提供有价值的参考。

编辑推荐精选

音述AI

音述AI

全球首个AI音乐社区

音述AI是全球首个AI音乐社区,致力让每个人都能用音乐表达自我。音述AI提供零门槛AI创作工具,独创GETI法则帮助用户精准定义音乐风格,AI润色功能支持自动优化作品质感。音述AI支持交流讨论、二次创作与价值变现。针对中文用户的语言习惯与文化背景进行专门优化,支持国风融合、C-pop等本土音乐标签,让技术更好地承载人文表达。

QoderWork

QoderWork

阿里Qoder团队推出的桌面端AI智能体

QoderWork 是阿里推出的本地优先桌面 AI 智能体,适配 macOS14+/Windows10+,以自然语言交互实现文件管理、数据分析、AI 视觉生成、浏览器自动化等办公任务,自主拆解执行复杂工作流,数据本地运行零上传,技能市场可无限扩展,是高效的 Agentic 生产力办公助手。

lynote.ai

lynote.ai

一站式搞定所有学习需求

不再被海量信息淹没,开始真正理解知识。Lynote 可摘要 YouTube 视频、PDF、文章等内容。即时创建笔记,检测 AI 内容并下载资料,将您的学习效率提升 10 倍。

AniShort

AniShort

为AI短剧协作而生

专为AI短剧协作而生的AniShort正式发布,深度重构AI短剧全流程生产模式,整合创意策划、制作执行、实时协作、在线审片、资产复用等全链路功能,独创无限画布、双轨并行工业化工作流与Ani智能体助手,集成多款主流AI大模型,破解素材零散、版本混乱、沟通低效等行业痛点,助力3人团队效率提升800%,打造标准化、可追溯的AI短剧量产体系,是AI短剧团队协同创作、提升制作效率的核心工具。

seedancetwo2.0

seedancetwo2.0

能听懂你表达的视频模型

Seedance two是基于seedance2.0的中国大模型,支持图像、视频、音频、文本四种模态输入,表达方式更丰富,生成也更可控。

nano-banana纳米香蕉中文站

nano-banana纳米香蕉中文站

国内直接访问,限时3折

输入简单文字,生成想要的图片,纳米香蕉中文站基于 Google 模型的 AI 图片生成网站,支持文字生图、图生图。官网价格限时3折活动

扣子-AI办公

扣子-AI办公

职场AI,就用扣子

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

堆友

堆友

多风格AI绘画神器

堆友平台由阿里巴巴设计团队创建,作为一款AI驱动的设计工具,专为设计师提供一站式增长服务。功能覆盖海量3D素材、AI绘画、实时渲染以及专业抠图,显著提升设计品质和效率。平台不仅提供工具,还是一个促进创意交流和个人发展的空间,界面友好,适合所有级别的设计师和创意工作者。

图像生成AI工具AI反应堆AI工具箱AI绘画GOAI艺术字堆友相机AI图像热门
码上飞

码上飞

零代码AI应用开发平台

零代码AI应用开发平台,用户只需一句话简单描述需求,AI能自动生成小程序、APP或H5网页应用,无需编写代码。

Vora

Vora

免费创建高清无水印Sora视频

Vora是一个免费创建高清无水印Sora视频的AI工具

下拉加载更多