MNIST 是机器学习的 Hello World,但正因为它太简单,反而适合用来回答一个更有价值的问题:模型复杂度增加的每一步,到底买到了什么。

我做了一个小项目:同一个数据集,同一套数据划分,依次用逻辑回归、SVM、MLP、小型卷积网络实现,记录准确率、训练时间、代码复杂度和可解释性。

项目目标。

不是追求最高准确率,而是建立对「成本—收益」的直觉:从一个线性模型到卷积网络,每一层复杂度各换来了多少百分点,值不值得在一个具体问题上继续投入。

大致结果。

逻辑回归(本质是线性分类)已经能到 92% 左右,训练几秒。
SVM 用 RBF 核到 97% 以上,训练时间明显增加。
MLP 到 98% 左右,需要调隐藏层和学习率。
小卷积网络到 99% 以上,但训练时间和工程复杂度都上了一个台阶。

关键结论不在数字,而在判断。

第一,从 92% 到 97% 的那一步最划算,因为它只需要换成核方法,成本不高。

第二,从 98% 到 99% 的那一步,需要卷积网络和更长的训练时间,收益只有一个百分点。在很多真实业务里,这一个百分点的价值远小于它带来的成本,而在 MNIST 这个任务里,很多人会下意识继续往上卷。

第三,最难的不是写模型,是保证对比公平。

为了公平,我固定了训练集测试集划分、统一了评估指标、每个模型都做了简单的超参说明,而不是为每个模型「调到最优」再比——那比的是调参运气,不是模型本身。

踩过的坑。

一开始数据没做标准化,SVM 和部分模型的收敛明显变慢;后来统一做了归一化,结果才稳定。另一个坑是混淆矩阵没看,只盯 accuracy,后来发现某些模型把 4 和 9 混淆得很厉害,而整体准确率掩盖了这一点。

下次会怎么做。

一是加入训练时间和参数量的量化对比,把「成本」变成数字;二是给每个模型写一段「适用场景」,避免把准确率当唯一答案;三是把数据处理、训练、评估拆成可复用的脚本,而不是散在 notebook 里。

这个项目最大的收获,是让我对「模型选型」有了具体的手感:准确率曲线的边际收益递减得很快,工程上的取舍往往比模型本身更重要。