共计 3271 个字符,预计需要花费 9 分钟才能阅读完成。
CIFAR-10 数据集概述
CIFAR-10 是计算机视觉领域经典的基准数据集,包含 10 个类别的 60000 张 32×32 彩色图像。其特点包括:

- 小尺寸图像带来的计算效率优势
- 类别均衡(每类 6000 张)
- 涵盖常见物体(飞机、汽车、鸟类等)
这个数据集常被用于验证模型在受限计算资源下的表现能力,非常适合比较不同深度学习架构的基础性能。
方法对比
1. 传统 CNN(LeNet- 5 改进版)
作为 CNN 的早期代表,我们实现的改进版包含:
class LeNet5(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
self.features = nn.Sequential(nn.Conv2d(3, 6, 5), # 3 通道输入,6 个 5x5 卷积核
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(6, 16, 5),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.classifier = nn.Sequential(nn.Linear(16*5*5, 120),
nn.ReLU(),
nn.Linear(120, 84),
nn.ReLU(),
nn.Linear(84, num_classes)
)
特点分析:
- 仅包含 2 个卷积层和 3 个全连接层
- 参数量约 60K
- 缺乏现代 CNN 的批量归一化等组件
2. ResNet-18
残差网络通过跳接连接解决深层网络梯度消失问题:
class BasicBlock(nn.Module):
def __init__(self, in_planes, planes, stride=1):
super().__init__()
self.conv1 = nn.Conv2d(in_planes, planes, 3, stride, 1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, 3, 1, 1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
# 下采样 shortcut
self.shortcut = nn.Sequential()
if stride != 1 or in_planes != planes:
self.shortcut = nn.Sequential(nn.Conv2d(in_planes, planes, 1, stride, bias=False),
nn.BatchNorm2d(planes)
)
关键改进:
- 引入批量归一化(BatchNorm)
- 残差结构允许训练更深的网络
- 参数量约 11M
3. EfficientNet-B0
通过复合缩放实现高参数效率:
class MBConv(nn.Module):
def __init__(self, in_, expand_, out_, kernel_size, stride, se_ratio=0.25):
super().__init__()
mid_ = int(in_ * expand_)
self.expand = in_ != mid_
if self.expand:
self.expand_conv = nn.Sequential(nn.Conv2d(in_, mid_, 1, bias=False),
nn.BatchNorm2d(mid_),
nn.SiLU())
self.depthwise = nn.Sequential(
nn.Conv2d(mid_, mid_, kernel_size, stride,
kernel_size//2, groups=mid_, bias=False),
nn.BatchNorm2d(mid_),
nn.SiLU())
# SE 注意力模块
self.se = nn.Sequential(nn.AdaptiveAvgPool2d(1),
nn.Conv2d(mid_, int(mid_*se_ratio), 1),
nn.SiLU(),
nn.Conv2d(int(mid_*se_ratio), mid_, 1),
nn.Sigmoid())
设计亮点:
- 倒置瓶颈结构(MBConv)
- 深度可分离卷积
- SE 注意力机制
- 参数量约 5.3M
4. Vision Transformer(ViT-Tiny)
将 Transformer 应用于图像领域:
class PatchEmbed(nn.Module):
def __init__(self, img_size=32, patch_size=4, in_chans=3, embed_dim=192):
super().__init__()
self.proj = nn.Conv2d(in_chans, embed_dim,
kernel_size=patch_size,
stride=patch_size)
class VisionTransformer(nn.Module):
def __init__(self):
super().__init__()
self.patch_embed = PatchEmbed()
num_patches = (32//4)**2
self.pos_embed = nn.Parameter(torch.zeros(1, num_patches+1, 192))
self.cls_token = nn.Parameter(torch.zeros(1, 1, 192))
self.blocks = nn.ModuleList([TransformerBlock(192, num_heads=3) for _ in range(12)
])
创新点:
- 将图像分割为 4 ×4 的 patch
- 通过位置编码保留空间信息
- 参数量约 6M
数据增强策略
针对小尺寸图像的增强组合:
transform_train = transforms.Compose([transforms.RandomCrop(32, padding=4),
transforms.RandomHorizontalFlip(),
transforms.ColorJitter(brightness=0.2, contrast=0.2),
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465),
(0.2023, 0.1994, 0.2010))
])
注意避免使用大尺度旋转 / 裁剪(如 RandomRotation(30))等破坏性增强。
性能对比
| 模型 | 参数量 | 训练时间 /epoch | 测试准确率 | 显存占用 |
|---|---|---|---|---|
| LeNet-5 | 60K | 25s | 68.2% | 780MB |
| ResNet-18 | 11M | 1m42s | 93.5% | 1.8GB |
| EfficientNet | 5.3M | 2m15s | 94.1% | 2.1GB |
| ViT-Tiny | 6M | 3m08s | 91.7% | 2.4GB |
测试环境:Google Colab Tesla T4 GPU,batch_size=128
最佳实践
小图像优化技巧
- 使用较小的 patch 尺寸(ViT 中设为 4 ×4 而非常规 16×16)
- 降低 CNN 的初始 stride(避免过早下采样)
- 在最后特征层使用全局平均池化替代全连接
过拟合抑制
- 添加 Dropout(FC 层 0.5,CNN 层 0.2)
- 早停机制(验证损失 3 轮不降则停止)
- 标签平滑(Label Smoothing=0.1)
混合精度训练
scaler = torch.cuda.amp.GradScaler()
with torch.cuda.amp.autocast():
outputs = model(inputs)
loss = criterion(outputs, targets)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
可减少 30% 显存占用且基本不影响精度。
开放性问题
- 如何改进 ViT 在小样本场景的表现?
- 引入卷积归纳偏置(如 Hybrid 架构)
-
知识蒸馏(用 CNN 作为教师模型)
-
轻量化部署方案:
- 模型量化(8bit INT 量化)
- 通道剪枝(基于 L1-norm)
- TensorRT 优化
这些方案在实际业务场景中需要根据硬件条件和延迟要求进行权衡选择。
正文完
发表至: 未分类
近一天内
