Kaggle-Digit Recognizer 题解

题目传送门

完整代码

1. 题目大意

这道题是【模板】图像分类。给定 \(N\) 张 \(28\times 28\) 的灰度手写数字图,每张图对应一个 \(0\sim 9\) 的标签。要求对测试集中的图像分类。最终指标为 \(\text{Accuracy}\)。

项目 数值
图像尺寸 \(1 \times 28 \times 28\)
类别数 \(10\)
训练样本 \(42000\)
测试样本 \(28000\)
像素范围 \(0,255\) 整数

2. 模型

图像分类常用 CNN。我们采用改进的经典 LeNet-5 模型,加入 BatchNorm 与 Dropout 以稳定训练并抑制过拟合:

python 复制代码
class MyLeNet(nn.Module):
    def __init__(self):
        super(MyLeNet,self).__init__()
        self.cnn=nn.Sequential(
            nn.Conv2d(1,6,kernel_size=5,padding=2,stride=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2,stride=2),
            nn.Conv2d(6,16,kernel_size=5,padding=0,stride=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2,stride=2)
        )
        self.fc=nn.Sequential(
            nn.Dropout(0.3),
            nn.Linear(16*5*5,120),
            nn.ReLU(),
            nn.Linear(120,84),
            nn.ReLU(),
            nn.Linear(84,10)
        )
    def forward(self,x):
        x=self.cnn(x)
        x=x.view(x.size(0),-1)
        x=self.fc(x)
        return x

总参数量约 \(6\times 10^4\),非常轻量,在 CPU 上训练只需要几分钟。

3. 训练策略

  • 损失函数:CrossEntropyLoss
  • 优化器:Adam
  • 学习率调度器:CosineAnnealingLR(余弦退火)

余弦退火能在训练末期以极小学习率精细收敛,往往比固定学习率提高 \(0.1\%\sim0.3\%\) 的准确率。

具体的超参数详见完整代码。

4. 数据增强

手写数字的旋转、平移、缩放不改变语义,属于保标签变换,考虑使用 RandomAffine 进行在线数据增强。

我们仅对一半样本做数据增强,这往往比全部增强训练起来更稳定。