MLP 处理图像的局限

用 MLP 直接处理 MNIST,分析其在参数规模和位置敏感性上的问题。

知识课 · 约 25 分钟 · 更新于 2026-08-14

直接用 MLP 处理图像,可行吗?

我们已经看到, 的 MNIST 图像在 PyTorch 里就是一个 的张量。 MLP 接受的是 一维向量 ,那把这张图 展平 成 784 维向量, 丢进熟悉的 MLP,能直接进行手写数字分类吗?

从代码层面看,答案是"能跑通",MNIST 这种 28×28 的小图甚至能跑出不错的准确率。 但这种做法 背后藏着两个隐患 ,一旦输入图像变大、或者数字稍微动一动位置,问题就会显现。 本节先把 MLP 跑起来作为基线,再逐一分析这两个隐患。

基线:MLP + 展平 + MNIST

把图像张量从 展平成长度 的向量,然后接一个常规 MLP, 本节用 这个尺寸(后面课程与 CNN 对比时保持口径一致):

训练 5 轮左右,准确率能稳定到约 95% – 97% 。 看起来 MLP 处理小尺寸图像并不差。但 这个结果建立在两个前提上 : 图像尺寸很小,且数字已经预先居中。下面分别检验这两个前提是否站得住。

隐患一:图像尺寸增大,参数量随之剧增

MNIST 是 维输入。 现实里的照片通常远大于此,一张普通彩色照片可能是 万维输入。

如果照搬 MLP 的做法,第一层全连接需要把每个输入像素与每个隐藏神经元两两相连。 假设隐藏层只有 256 个神经元:

单是 一层 就需要约 2.36 亿 个参数。 不仅训练成本极高,模型也极易过拟合,且大量的连接其实在做"无用功"。 图像中相距很远的像素之间通常关联微弱,把它们用一根权重连起来纯属浪费。

隐患二:数字位置偏移,准确率明显下降

MNIST 的数字都被预先居中。但真实场景里,待识别的内容并不会自动居中。 同一个 "5",可能写在画面正中,也可能偏左、偏上、偏下。 训练好的 MLP 还能不能正确识别?我们做一个小实验来验证。

为了让效果直观、又能在浏览器里实时跑起来,下面的实验把网络的"任务规模"做了简化: 在 28 × 28 的画布上随机抽取 4 种几何形状之一 (圆环 / 竖线 / 横线 / 十字), 每种形状都是 14 × 14 大小, 居中 放在画布中央; 训练一个 的 MLP 来识别它们。 训练时,图形始终居中,这与 MNIST 一致。

训练完成后,你可以通过滑块把图形整体 左右、上下平移 若干像素, 看看 MLP 对它的预测概率怎么变化。

实际拖动可以看到,只要图形稍微偏离训练时的居中位置,预测概率就剧烈抖动, 模型甚至会把同一个图形识别成完全不同的类。 这就是位置敏感问题 :MLP 的每个权重都与某个固定的输入坐标绑定, 平移之后,原本笔画落在某些坐标上的"贡献"就转移到了另一组完全不同的权重上, 模型自然给出不同的回答。

两个隐患背后的三个共同问题

把上面两个现象拆开看,会发现它们其实指向 MLP 处理图像的 三个共同的根本问题 :

要解决这三个问题,需要重新审视图像数据本身的 结构 , 而不是把它当作一个普通的高维向量来处理。 图像有两个非常重要的性质:

处理图像的层结构应当与这两个性质对得上 。 把它落到对权重的具体约束上,两条性质各自暗示了一个朴素的设计:

  • 为了贴合 局部性 ,每个输出只看一小块邻域, 而不是把所有像素都连进来;
  • 为了贴合 平移不变性 ,同一组权重需要在画面的 不同位置 反复使用 ,也就是 参数共享 。这样一来,无论笔画落在哪个坐标, 都能由 同一组 权重检出,从而对位置变化保持稳定。

而 MLP 的全连接结构不满足这两条:它一上来就把整张图拉成一条向量, 丢掉了局部性;每个权重又只对应一个固定坐标, 不同位置之间没有任何参数复用。这正是前面两个隐患的根源。