【深度学习】MLP(多层感知机):神经网络基础 MLP多层感知机从零开始教程写在前面MLP 是最基础的神经网络也是理解所有后续网络CNN、RNN、Transformer的起点。这篇文档从一个神经元在做什么讲起逐步搭建到完整的 MLP 分类器最后对照本项目的代码把每一行都讲透。第一章 一个神经元——最小的决策单元1.1 神经元的灵感来源人脑有约 860 亿个神经元每个神经元的工作模式是从其他神经元接收信号把信号汇总如果汇总结果超过某个阈值就激发向下游发出信号否则保持沉默人工神经元直接模仿了这个过程。1.2 人工神经元的数学表达输入 x₁ ──→ ×w₁ ──┐ 输入 x₂ ──→ ×w₂ ──┼──→ 加权求和 z w₁x₁ w₂x₂ w₃x₃ b ──→ 激活函数 f(z) ──→ 输出 y 输入 x₃ ──→ ×w₃ ──┘符号含义直觉x₁, x₂, x₃输入从上游接收到的信号w₁, w₂, w₃权重每个输入有多重要可正可负b偏置调节激发门槛的旋钮z加权求和把所有信号汇总成一个数f激活函数决定是否激发、输出多少y输出传递给下游的信号1.3 一个具体的例子假设一个神经元用来判断今天适不适合出门输入 x₁ 温度25°C → 归一化后 0.8 x₂ 下雨概率80% → 0.8 x₃ 心情好不好好 → 1.0 权重训练学到的 w₁ 0.6 温度越高越想出门 w₂ -0.9 下雨越大越不想出门 w₃ 0.5 心情好更想出门 b -0.1 计算 z 0.6×0.8 (-0.9)×0.8 0.5×1.0 (-0.1) 0.48 - 0.72 0.50 - 0.10 0.16 ReLU(0.16) 0.16 0 → 激发输出 0.16 → 倾向出门但不太强烈权重的正负决定了这个输入是鼓励还是抑制输出。这些权重不是人工设定的而是训练过程中自动学出来的。1.4 单个神经元的局限一个神经元只能画一条直线来划分是/否。现实中的问题往往需要弯弯曲曲的分类边界。解决办法把很多神经元组合起来——这就是层和网络。第二章 从单个神经元到层2.1 什么是层把多个神经元并排放在一起它们接收相同的输入但各自有各自的权重和偏置各自输出一个值。神经元1 → y₁ 输入 x → 神经元2 → y₂ ← 这就是一个层有 4 个神经元 神经元3 → y₃ 神经元4 → y₄4 个神经元就输出 4 个数组成一个长度为 4 的向量。一个常见的误解一个神经元关注一个特性。实际上一个神经元关注的是一种输入的组合模式。它的权重决定了它对哪些输入更敏感——可能侧重某一个权重特别大也可能综合多个。比如权重[0.9, 0.01, 0.02]几乎只看第一个输入而[0.4, 0.3, 0.3]则均匀地看三个。很多神经元并排放一起就有了很多种不同的投票策略合起来覆盖各种情况。2.2 用矩阵表示把 4 个神经元的权重排成一个矩阵一层的计算就是一次矩阵乘法zW⋅xbz W \cdot x bzW⋅xbyf(z)y f(z)yf(z)比如输入有 3 个值、这一层有 4 个神经元那么 W 是 4×3 的矩阵b 是长度 4 的向量。这就是为什么深度学习离不开线性代数——一层的前向传播 一次矩阵乘法 一次激活。2.3 全连接是什么意思如果每一个输入都和每一个神经元相连就叫全连接层Fully Connected也叫 Dense 或 Linear。输入3个 全连接层4个神经元 x₁ ─────┬──→ n₁ ├──→ n₂ 每个输入到每个神经元都有一条线 全连接 x₂ ─────┼──→ n₃ 一共 3×4 12 条线12 个权重 ├──→ n₄ x₃ ─────┘为什么要全连接让每个神经元都能看到全部输入信息自己决定关注什么。如果某个神经元只连了部分输入它就永远看不到其余输入的信息哪怕那些信息很重要。全连接保证了信息不被人为截断——至于每个输入到底重不重要交给权重去学重要的权重变大不重要的趋近于 0。缺点输入一多连接数就爆炸。3072 个输入 × 1024 个神经元 300 万条线。这也是后来 CNN 用卷积代替全连接的动机——不需要每个像素都和每个神经元相连只看局部就够了。全连接层是 MLP 的唯一砖块。第三章 MLP 多层全连接网络3.1 什么是 MLPMLPMulti-Layer Perceptron多层感知机就是把多个全连接层串起来每两层之间加一个激活函数。输入层 隐藏层1 隐藏层2 输出层 (原始数据) (中间特征) (更高级特征) (分类得分) x₁ ──┐ ┌── h₁ ──┐ ┌── h₁ ──┐ ┌── y₁ x₂ ──┼──→ ├── h₂ ──┼──→ ├── h₂ ──┼──→ ├── y₂ x₃ ──┤ ├── h₃ ──┤ └── h₃ ──┘ └── y₃ ⋮ ┘ └── h₄ ──┘3.2 为什么叫深度学习只有一个隐藏层的 MLP 叫浅层网络。有两个及以上隐藏层的就算深层网络——这也是深度学习这个名字的由来。层数越多网络能表达的函数越复杂。3.3 每一层在干什么层作用比喻输入层接收原始数据把题目摆到桌上隐藏层提取中间特征画草稿、做中间推理输出层给出最终结果写下最终答案隐藏层之所以叫隐藏是因为我们只能看到输入和输出中间层学到的东西是网络自己决定的对我们是隐藏的。3.4 激活函数为什么必须存在如果去掉所有激活函数整个 MLP 就变成了yW3⋅(W2⋅(W1⋅x))(W3W2W1)⋅xW′⋅xy W_3 \cdot (W_2 \cdot (W_1 \cdot x)) (W_3 W_2 W_1) \cdot x W \cdot xyW3​⋅(W2​⋅(W1​⋅x))(W3​W2​W1​)⋅xW′⋅x多层线性变换等价于一层线性变换——深度白加了。激活函数ReLU在每层之后引入拐点才让多层叠加有了意义。常见误解激活函数是为了去掉不重要的参数。不是。激活函数的目的是引入非线性——让网络能画出弯曲的分类边界而不只是一条直线。之所以会有这个误解是因为 ReLU 恰好会把负数归零看起来像在丢东西。但换成 Tanh输出在 -1 到 1 之间不归零同样能当激活函数因为它也是非线性的。一句话激活函数 给网络装弯道没有它只能走直线。第四章 MLP 处理图片——拍平的代价4.1 图片怎么变成 MLP 能接收的输入MLP 的输入必须是一维向量。但图片是二维的宽×高还有颜色通道RGB所以是三维的。解决办法很粗暴直接拍平。一张 32×32×3 的彩色图片 R 通道32×32 G 通道32×32 B 通道32×32 ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ │ │ 32×32 │ │ 32×32 │ │ 32×32 │ │ │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ ↓ Flatten拍平 [ r₁, r₂, ..., r₁₀₂₄, g₁, g₂, ..., g₁₀₂₄, b₁, b₂, ..., b₁₀₂₄ ] └───────────────────────── 3072 个数字 ──────────────────────────────┘4.2 拍平丢掉了什么拍平后所有的空间位置关系都没了左上角的像素和右下角的像素在向量里可能相邻也可能相隔很远一只猫的眼睛和耳朵明明是邻居拍平后网络不知道它们挨着即使把图片旋转 90°、翻转拍平后得到的向量完全不同——MLP 认不出是同一张图这就是 MLP 做图像分类天生的劣势也是后来 CNN 被发明的直接原因。4.3 那 MLP 做图片分类还有什么意义作为基线baseline。在实验中先用 MLP 跑一组结果再用 CNN 跑一组对比之下就能清楚地看出 CNN 的优势有多大。第五章 本项目 MLP 的完整结构5.1 网络结构图输入: [batch, 3, 32, 32] ← 一批 32×32 的 RGB 图片 Flatten → [batch, 3072] 把图片拍成一维向量 ↓ Linear(3072 → 1024) → [batch, 1024] 第一个全连接层 ReLU → [batch, 1024] 激活负数归零 Dropout(0.3) → [batch, 1024] 随机关掉 30% 的神经元 ↓ Linear(1024 → 512) → [batch, 512] 第二个全连接层 ReLU → [batch, 512] 激活 Dropout(0.3) → [batch, 512] 再随机关掉 30% ↓ Linear(512 → 100) → [batch, 100] 输出层100 个类别各一个得分 最终: 取 100 个得分中最大的那个对应的类别作为预测结果5.2 逐层解读Flatten拍平把 32×32×3 3072 个像素值排成一行。这一步没有任何可学习的参数纯粹是数据形状变换。Linear(3072, 1024)第一个全连接层3072 个输入1024 个输出。参数量 3072×1024 1024偏置3,146,752。这一层做的事情把 3072 维的原始像素信息混合压缩成 1024 维的中间表示。你可以想象成3072 个人投票1024 个委员会成员分别统计不同维度的民意。ReLU激活把负数变成 0。没有可学习参数。作用让网络能表达非线性关系。Dropout(0.3)防过拟合训练时随机关掉 30% 的神经元。没有可学习参数。作用防止网络死记硬背训练数据。测试时所有神经元都打开PyTorch 的model.eval()自动处理。Linear(1024, 512)第二个全连接层把 1024 维进一步压缩到 512 维。参数量 1024×512 512 524,800。这一层在提取更高级的特征组合。Linear(512, 100)输出层512 维压缩到 100 维。每个输出值代表这张图属于第 i 类的得分。参数量 512×100 100 51,300。注意输出层没有激活函数——因为交叉熵损失函数内部自带 softmax不需要额外加。5.3 参数量总结层参数量占比Linear(3072→1024)3,146,75284.5%Linear(1024→512)524,80014.1%Linear(512→100)51,3001.4%总计3,722,852100%绝大多数参数集中在第一层——因为输入维度太高3072。而 CNN 用卷积的权重共享机制同样的输入只需要几千个参数就能处理这是 CNN 参数效率远高于 MLP 的根本原因。第六章 MLP 的训练过程6.1 整体流程┌──────────────────────────────────────────────────┐ │ │ │ ① 取一批图片 → ② 拍平 → ③ 前向传播得到预测 │ │ ↓ │ │ ④ 和标签比较算损失 │ │ ↓ │ │ ⑤ 反向传播算梯度 │ │ ↓ │ │ ⑥ 优化器更新参数 │ │ ↓ │ │ 回到 ① 取下一批 ────→│ │ │ └──────────────────────────────────────────────────┘ 一个 epoch 把训练集完整过一遍6.2 前向传播的数值示例用一个极简版3 个输入、2 个隐藏、2 个输出演示一轮计算输入: x [0.5, 0.3, 0.8] 第一层 Linear(3→2): W₁ [[0.1, 0.4, -0.2], b₁ [0.1, -0.1] [0.3, -0.1, 0.5]] z₁ W₁·x b₁ [0.1×0.5 0.4×0.3 (-0.2)×0.8 0.1, 0.3×0.5 (-0.1)×0.3 0.5×0.8 (-0.1)] [0.05 0.12 - 0.16 0.1, 0.15 - 0.03 0.40 - 0.1] [0.11, 0.42] ReLU: h₁ [max(0, 0.11), max(0, 0.42)] [0.11, 0.42] 都是正数不变 第二层 Linear(2→2): W₂ [[0.2, -0.3], b₂ [0.0, 0.1] [-0.1, 0.6]] z₂ W₂·h₁ b₂ [0.2×0.11 (-0.3)×0.42 0.0, (-0.1)×0.11 0.6×0.42 0.1] [-0.104, 0.341] 输出logits: [-0.104, 0.341] → 第 2 类得分更高 → 模型预测为第 2 类6.3 损失函数怎么算假设真实标签是第 1 类索引 0交叉熵损失会说“你给第 1 类打了 -0.104 分给第 2 类打了 0.341 分你打错了损失很大”然后反向传播从这个损失出发算出 W₁、b₁、W₂、b₂ 每个参数该怎么调优化器执行调整下一轮预测就会更准一点。6.4 训练多久本项目默认训练10 个 epoch每个 epoch 遍历全部训练集一次。每个 epoch 结束后在验证集上测一次准确率记录最好的那一轮模型。第七章 MLP 的弱点与 CNN 的优势对比维度MLPCNN处理图片方式拍平成向量丢掉空间信息保留二维结构用卷积扫描参数量第一层就 300 万卷积层参数很少权重共享平移不变性没有图片移动一下结果就变有同一个卷积核到处扫适合的数据表格数据、低维特征图像、音频等有空间/时间结构的数据在 CIFAR-100 上的表现较差通常 30-40%较好通常 50-70%为什么 MLP 在图片上差这么多一个核心原因MLP 学不到局部模式可以在任意位置出现这个先验。比如猫耳朵可能出现在图片的左上角也可能在右下角。CNN 用同一个卷积核在整张图上滑动只要学会猫耳朵长什么样不管它在哪都能检测到。而 MLP 把图片拍平后左上角和右下角的像素在向量里位置不同它需要分别学两套权重来识别等于同一个知识学了两遍——数据不够时就学不好。第八章 MLP 的适用场景虽然 MLP 不擅长图片但在很多其他场景它是主力场景输入为什么 MLP 够用表格数据分类年龄、收入、学历等特征没有空间结构不需要卷积推荐系统用户特征 物品特征拼接成向量后全连接就能学Transformer 的内部注意力层的输出Transformer 每个块里都有一个两层 MLP叫 FFN强化学习状态向量DQN、PPO 的 Q 网络和策略网络本质就是 MLP嵌入层之后低维表示任何网络的最后几层分类头通常就是 MLP一句话MLP 是深度学习的万金油几乎所有网络内部都在用它只是不擅长直接处理有空间结构的原始数据。总结MLP 核心概念一页纸┌─────────────────────────────────────────────────────────────┐ │ MLP 核心概念速查 │ ├─────────────┬───────────────────────────────────────────────┤ │ 神经元 │ 加权求和 偏置 激活函数 最小决策单元 │ │ 权重 w │ 每个输入的重要程度正鼓励负抑制 │ │ 偏置 b │ 调节激发门槛的旋钮 │ │ 全连接层 │ 每个输入连接每个输出一次矩阵乘法 │ │ 隐藏层 │ 输入和输出之间的中间层提取特征 │ │ ReLU │ max(0, x)引入非线性负数归零 │ │ Dropout │ 训练时随机关神经元防过拟合 │ │ Flatten │ 多维数据拍成一维向量MLP 处理图片的前提 │ │ 前向传播 │ 输入 → 逐层计算 → 输出预测 │ │ 反向传播 │ 从损失出发逆向算每个参数的梯度 │ │ 参数量 │ 全连接层参数 输入维度 × 输出维度 偏置 │ │ 局限性 │ 拍平丢掉空间信息不适合直接处理图像 │ │ 真正擅长 │ 表格数据、作为其他网络的内部组件 │ └─────────────┴───────────────────────────────────────────────┘