共计 2421 个字符,预计需要花费 7 分钟才能阅读完成。
CIFAR-10 数据集简介
CIFAR-10 是深度学习领域广泛使用的基准数据集,包含 10 个类别的 6 万张 32×32 彩色图像(5 万训练 + 1 万测试)。每类有 6000 张图像,涵盖飞机、汽车、鸟类等常见对象。其特点包括:

- 低分辨率图像(32×32 像素)适合快速实验
- 类别平衡便于评估模型性能
- 已划分标准训练 / 测试集
- 常用于验证 CNN 架构有效性
CNN 模型结构详解
1. 输入层设计
输入尺寸需匹配 CIFAR-10 的 32×32×3(宽×高×RGB 通道)。常见预处理方式:
- 像素值归一化到 [0,1] 或[-1,1]
- 数据增强(随机水平翻转 / 裁剪)
2. 卷积层原理
核心操作:通过滑动窗口(kernel)提取局部特征。关键参数:
- kernel_size:常用 3×3 或 5×5
- stride:控制滑动步长(默认为 1)
- padding:保持特征图尺寸(如 padding= 1 时 3×3 卷积不改变尺寸)
- out_channels:决定提取的特征图数量
3. 池化层作用
降低空间维度同时保留重要特征。Max Pooling 最常用:
- 典型窗口 2×2,stride=2
- 输出尺寸减半
- 增强平移不变性
4. 全连接层设计
将最终特征图展平后分类:
- 通常配合 Dropout 防止过拟合
- 最后一层神经元数 = 类别数(CIFAR-10 为 10)
PyTorch 完整实现
数据准备
import torch
from torchvision import datasets, transforms
# 定义预处理
transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
# 加载数据集
train_set = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
test_set = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_set, batch_size=64, shuffle=False)
模型定义
import torch.nn as nn
import torch.nn.functional as F
class BasicCNN(nn.Module):
def __init__(self):
super().__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, 10)
self.dropout = nn.Dropout(0.25)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x))) # 输出 16×16×32
x = self.pool(F.relu(self.conv2(x))) # 输出 8×8×64
x = torch.flatten(x, 1) # 展平为 4096 维
x = self.dropout(F.relu(self.fc1(x)))
x = self.fc2(x)
return x
训练流程
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = BasicCNN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
for epoch in range(10):
model.train()
running_loss = 0.0
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}')
调优与改进建议
性能提升技巧
- 学习率调整:
- 使用学习率调度器(如 ReduceLROnPlateau)
-
初始学习率尝试 0.01~0.0001
-
正则化强化:
- 增加 Dropout 比例(0.3~0.5)
-
添加 L2 权重衰减
-
模型结构调整:
- 增加卷积层深度
- 尝试残差连接
常见错误排查
- 输入维度不匹配:检查 transform 是否一致
- 梯度爆炸:添加梯度裁剪(grad_clip)
- 过拟合:早停法 + 更多数据增强
模型改进方向
- 现代架构借鉴:
- 引入 ResNet 的残差块
-
尝试 MobileNet 的深度可分离卷积
-
注意力机制:
- 添加 SE(Squeeze-and-Excitation)模块
-
使用 CBAM 空间注意力
-
自监督预训练:
- 采用 SimCLR 对比学习
- 使用 MAE 掩码自编码
结语
通过这个基础 CNN 实现,我们完成了从数据加载到模型训练的完整流程。建议读者尝试调整超参数、增加网络深度或引入 BN 层来进一步提升性能。当准确率达到 80% 以上时,可以开始探索更复杂的模型架构。
正文完
发表至: 未分类
近两天内
