
CIFAR-10 与 CIFAR-100从 10 类到 100 类的数据集迁移实战指南当你在 CIFAR-10 上训练出一个表现不错的模型后下一步自然是想挑战更复杂的任务。CIFAR-100 就是这样一个理想的进阶选择——它不仅类别数量增加了 10 倍还引入了层级标签结构。本文将带你深入理解这两个数据集的差异并提供从 CIFAR-10 迁移到 CIFAR-100 的完整技术路线。1. 理解数据集差异从简单分类到细粒度识别CIFAR-10 和 CIFAR-100 虽然都是 32x32 像素的彩色图像数据集但在结构和复杂度上存在显著差异特性CIFAR-10CIFAR-100类别数量10100每类样本数6,000600训练集总量50,00050,000测试集总量10,00010,000标签层级单层扁平结构双层结构20个超类典型应用场景基础分类任务细粒度图像识别CIFAR-100 最显著的特点是它的层级标签体系粗粒度标签Coarse Labels20 个超类如水生哺乳动物、花卉等细粒度标签Fine Labels100 个子类如海豚、鲸鱼属于水生哺乳动物超类这种结构为模型训练提供了更多可能性。你可以仅使用细粒度标签进行 100 类分类使用粗粒度标签进行 20 类分类联合训练利用层级关系提升模型表现# CIFAR-100 标签加载示例 import torchvision.datasets as datasets cifar100 datasets.CIFAR100(root./data, trainTrue, downloadTrue) print(f细粒度标签: {cifar100.targets[0]}) print(f对应粗粒度标签: {cifar100.coarse_targets[0]})2. 模型架构调整策略从 10 类扩展到 100 类模型需要做出相应调整2.1 输出层改造最直接的修改是输出层维度import torch.nn as nn # CIFAR-10 输出层 output_layer_10 nn.Linear(512, 10) # CIFAR-100 输出层改造 output_layer_100 nn.Linear(512, 100) # 修改输出维度为100但仅仅增加输出维度是不够的你还需要考虑层级分类策略class HierarchicalClassifier(nn.Module): def __init__(self, backbone): super().__init__() self.backbone backbone self.coarse_classifier nn.Linear(512, 20) # 粗粒度分类 self.fine_classifier nn.Linear(512, 100) # 细粒度分类 def forward(self, x): features self.backbone(x) coarse_logits self.coarse_classifier(features) fine_logits self.fine_classifier(features) return coarse_logits, fine_logits2.2 损失函数优化对于层级分类可以设计复合损失函数def hierarchical_loss(coarse_logits, fine_logits, coarse_labels, fine_labels, alpha0.3): coarse_loss nn.CrossEntropyLoss()(coarse_logits, coarse_labels) fine_loss nn.CrossEntropyLoss()(fine_logits, fine_labels) return alpha * coarse_loss (1-alpha) * fine_loss2.3 网络深度与容量随着类别增加建议增加网络深度如从 ResNet-18 升级到 ResNet-34扩大通道数如从 64 初始通道增加到 128添加注意力机制如 SE 模块# 通道数扩展示例 def conv3x3(in_planes, out_planes, stride1): return nn.Conv2d(in_planes, out_planes, kernel_size3, stridestride, padding1, biasFalse) # CIFAR-10 常用配置 block_64 conv3x3(64, 64) # CIFAR-100 扩展配置 block_128 conv3x3(128, 128)3. 数据增强策略升级CIFAR-100 由于每类样本更少仅 600 张需要更智能的数据增强3.1 基础增强组合from torchvision import transforms # CIFAR-10 常用增强 transform_10 transforms.Compose([ transforms.RandomHorizontalFlip(), transforms.RandomCrop(32, padding4), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) # CIFAR-100 增强升级 transform_100 transforms.Compose([ transforms.RandomHorizontalFlip(), transforms.RandomCrop(32, padding4), transforms.ColorJitter(brightness0.2, contrast0.2, saturation0.2), transforms.RandomRotation(15), transforms.RandomAffine(0, translate(0.1, 0.1)), transforms.ToTensor(), transforms.Normalize((0.5071, 0.4867, 0.4408), (0.2675, 0.2565, 0.2761)), ])注意CIFAR-100 使用不同的归一化参数这是基于其自身数据统计计算的3.2 高级增强技术Cutout随机遮挡图像区域class Cutout(object): def __init__(self, length): self.length length def __call__(self, img): h, w img.size(1), img.size(2) mask np.ones((h, w), np.float32) y np.random.randint(h) x np.random.randint(w) y1 np.clip(y - self.length // 2, 0, h) y2 np.clip(y self.length // 2, 0, h) x1 np.clip(x - self.length // 2, 0, w) x2 np.clip(x self.length // 2, 0, w) mask[y1:y2, x1:x2] 0. img img * torch.from_numpy(mask) return imgMixup图像混合增强def mixup_data(x, y, alpha1.0): if alpha 0: lam np.random.beta(alpha, alpha) else: lam 1 batch_size x.size(0) index torch.randperm(batch_size) mixed_x lam * x (1 - lam) * x[index, :] y_a, y_b y, y[index] return mixed_x, y_a, y_b, lam4. 训练技巧与调优策略4.1 学习率调度由于类别增加需要更谨慎的学习率控制# 分层学习率示例 optimizer torch.optim.SGD([ {params: model.backbone.parameters(), lr: 0.1}, {params: model.coarse_classifier.parameters(), lr: 0.2}, {params: model.fine_classifier.parameters(), lr: 0.2} ], momentum0.9, weight_decay5e-4) # 余弦退火调度 scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max200)4.2 类别不平衡处理CIFAR-100 虽然总体平衡但某些超类下子类样本可能不均衡# 焦点损失 (Focal Loss) class FocalLoss(nn.Module): def __init__(self, gamma2, alphaNone): super(FocalLoss, self).__init__() self.gamma gamma self.alpha alpha def forward(self, inputs, targets): BCE_loss F.cross_entropy(inputs, targets, reductionnone) pt torch.exp(-BCE_loss) loss (1-pt)**self.gamma * BCE_loss if self.alpha is not None: loss self.alpha[targets] * loss return loss.mean()4.3 知识蒸馏应用可以利用预训练的 CIFAR-10 模型辅助训练def distillation_loss(student_logits, teacher_logits, labels, temp3, alpha0.7): soft_teacher F.softmax(teacher_logits/temp, dim1) soft_student F.log_softmax(student_logits/temp, dim1) kl_div F.kl_div(soft_student, soft_teacher, reductionbatchmean) * (temp**2) ce_loss F.cross_entropy(student_logits, labels) return alpha * kl_div (1-alpha) * ce_loss5. 评估与结果分析5.1 评估指标除了常规的准确率对于 CIFAR-100 建议关注各类别准确率特别是相似类别间混淆矩阵分析粗粒度与细粒度准确率对比from sklearn.metrics import confusion_matrix, classification_report def evaluate(model, loader): model.eval() all_preds [] all_labels [] with torch.no_grad(): for inputs, labels in loader: outputs model(inputs) _, preds torch.max(outputs, 1) all_preds.extend(preds.cpu().numpy()) all_labels.extend(labels.cpu().numpy()) print(classification_report(all_labels, all_preds)) cm confusion_matrix(all_labels, all_preds) plt.figure(figsize(20,20)) sns.heatmap(cm, annotTrue, fmtd) plt.show()5.2 典型性能基准模型架构CIFAR-10 准确率CIFAR-100 准确率ResNet-1895.2%76.5%ResNet-3495.8%78.3%EfficientNet-B095.1%77.8%MobileNetV394.5%75.2%提示这些结果基于标准数据增强和训练方案使用本文技巧通常可以获得 2-5% 的提升6. 实战完整迁移案例以下是一个完整的 PyTorch 实现示例import torch import torchvision import torch.nn as nn import torch.optim as optim from torchvision import transforms, datasets from torch.utils.data import DataLoader # 1. 数据准备 train_transform transforms.Compose([ transforms.RandomResizedCrop(32, scale(0.8, 1.0)), transforms.RandomHorizontalFlip(), transforms.ColorJitter(0.2, 0.2, 0.2), transforms.ToTensor(), transforms.Normalize((0.5071, 0.4867, 0.4408), (0.2675, 0.2565, 0.2761)), Cutout(16) ]) test_transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5071, 0.4867, 0.4408), (0.2675, 0.2565, 0.2761)) ]) train_set datasets.CIFAR100(root./data, trainTrue, downloadTrue, transformtrain_transform) test_set datasets.CIFAR100(root./data, trainFalse, downloadTrue, transformtest_transform) train_loader DataLoader(train_set, batch_size128, shuffleTrue, num_workers4) test_loader DataLoader(test_set, batch_size100, shuffleFalse, num_workers4) # 2. 模型定义 class CIFAR100Model(nn.Module): def __init__(self): super().__init__() self.backbone torchvision.models.resnet34(pretrainedFalse, num_classes100) self.backbone.conv1 nn.Conv2d(3, 64, kernel_size3, stride1, padding1, biasFalse) self.backbone.maxpool nn.Identity() def forward(self, x): return self.backbone(x) model CIFAR100Model().cuda() # 3. 训练配置 criterion nn.CrossEntropyLoss() optimizer optim.SGD(model.parameters(), lr0.1, momentum0.9, weight_decay5e-4) scheduler optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max200) # 4. 训练循环 for epoch in range(200): model.train() for inputs, targets in train_loader: inputs, targets inputs.cuda(), targets.cuda() # Mixup 增强 inputs, targets_a, targets_b, lam mixup_data(inputs, targets, alpha1.0) outputs model(inputs) loss lam * criterion(outputs, targets_a) (1-lam) * criterion(outputs, targets_b) optimizer.zero_grad() loss.backward() optimizer.step() scheduler.step() # 评估 model.eval() correct 0 total 0 with torch.no_grad(): for inputs, targets in test_loader: inputs, targets inputs.cuda(), targets.cuda() outputs model(inputs) _, predicted outputs.max(1) total targets.size(0) correct predicted.eq(targets).sum().item() print(fEpoch {epoch}: Acc {100.*correct/total:.2f}%)从 CIFAR-10 迁移到 CIFAR-100 不仅是类别数量的增加更是对模型理解能力的全面提升。通过合理调整模型架构、优化训练策略并应用高级增强技术你可以在 CIFAR-100 上获得具有竞争力的结果。记住细粒度分类的关键在于让模型学会区分细微的视觉差异这需要数据、模型和训练策略的精心配合。