3、神经网络基础(二):多层感知机(MLP)结构、前向传播算法、反向传播算法(BP)、梯度下降法(SGD、Momentum、Adam)、损失函数(MSE、Cross-Entropy)

各位同学,咱们接着聊神经网络。上一节我们把神经元和感知机讲透了,今天要上点硬菜——多层感知机(MLP)。

说实话,单层感知机有个致命缺陷:它连异或(XOR)问题都解决不了。我当年刚入行时,导师让我用感知机做分类,结果死活分不开异或数据。后来才知道,加一层隐藏层就搞定了。这就是MLP的价值所在。

3.1 多层感知机(MLP)结构

MLP说白了就是堆叠了多个全连接层。每一层包含若干神经元,层与层之间全连接。结构上分三部分:

  • 输入层:接收原始特征,神经元个数等于特征维度
  • 隐藏层:可以有一层或多层,每层神经元数量可自定义
  • 输出层:输出结果,分类任务用Softmax,回归任务用线性激活

我习惯把隐藏层叫做"特征提取器"。你想想看,输入数据经过隐藏层的非线性变换,原本线性不可分的问题就变得可分。嗯,这里要注意:隐藏层太少,模型欠拟合;隐藏层太多,容易过拟合。我在项目中踩过这个坑,后面会细说。

核心公式:第l层的输出 a[l] = σ(W[l] · a[l-1] + b[l])

其中σ是激活函数,W是权重矩阵,b是偏置向量。

MLP 三层结构示意图 x1 x2 x3 输入层 隐藏层 输出层

3.2 前向传播算法

前向传播就是数据从输入层一路算到输出层。过程很简单:

  1. 输入层接收特征向量 x
  2. 逐层计算 z = W·a + b,再经过激活函数得到 a = σ(z)
  3. 最后一层输出预测值 ŷ

举个例子,假设输入是 [0.5, -0.2],隐藏层有4个神经元,输出层2个神经元。代码实现如下:

import numpy as np

def forward_propagation(X, W1, b1, W2, b2):
    # 隐藏层
    z1 = np.dot(W1, X) + b1
    a1 = np.tanh(z1)  # 激活函数用tanh
    
    # 输出层
    z2 = np.dot(W2, a1) + b2
    a2 = np.exp(z2) / np.sum(np.exp(z2))  # Softmax
    
    return a2

我个人习惯把前向传播写成矩阵形式,这样代码简洁,GPU加速也方便。你想想看,一次矩阵乘法就处理了整个batch的数据,多爽。

3.3 反向传播算法(BP)

反向传播是MLP的核心。说白了就是链式法则的工程应用。我当年学BP时,总觉得它很玄乎。后来自己手推了一遍,发现其实就是求导的链式法则。

BP的四个核心公式(以均方误差为例):

公式 含义
δ[L] = ∇aC ⊙ σ'(z[L]) 输出层误差
δ[l] = (W[l+1])Tδ[l+1] ⊙ σ'(z[l]) 隐藏层误差反向传播
∂C/∂b[l] = δ[l] 偏置梯度
∂C/∂W[l] = δ[l] · (a[l-1])T 权重梯度

避坑指南:我曾经在写BP时,忘记对激活函数求导,结果梯度一直不收敛。调试了整整两天才发现。记住:反向传播一定要对激活函数求导!

3.4 梯度下降法

有了梯度,怎么更新参数?这就轮到梯度下降法登场了。我给大家介绍三种最常用的:

3.4.1 SGD(随机梯度下降)

SGD每次只用一个样本更新参数。优点是快,缺点是震荡厉害。公式很简单:

W = W - learning_rate * dW

3.4.2 Momentum(动量法)

Momentum引入了"惯性"概念。我习惯把它想象成一个小球从山坡滚下来,遇到小坑能冲过去。更新公式:

v = beta * v - learning_rate * dW
W = W + v

beta通常取0.9。嗯,这里要注意:动量太大可能冲过头,太小又没效果。

3.4.3 Adam(自适应矩估计)

Adam是目前最常用的优化器。它结合了Momentum和RMSProp的优点。我个人项目里90%的情况都用Adam,省心。

m = beta1 * m + (1 - beta1) * dW   # 一阶矩估计
v = beta2 * v + (1 - beta2) * (dW**2)  # 二阶矩估计
m_hat = m / (1 - beta1**t)
v_hat = v / (1 - beta2**t)
W = W - learning_rate * m_hat / (np.sqrt(v_hat) + epsilon)

警告:Adam虽然好用,但有时会收敛到局部最优。我建议先用Adam快速找到好区域,再切到SGD微调。这叫"先粗调后精调"策略。

3.5 损失函数

损失函数衡量模型预测值和真实值的差距。选对损失函数,训练事半功倍。

3.5.1 均方误差(MSE)

MSE = (1/n) * Σ(y - ŷ)²。适合回归问题。我做过一个房价预测项目,用的就是MSE。但要注意:MSE对异常值敏感,一个离群点就能把模型带偏。

3.5.2 交叉熵(Cross-Entropy)

交叉熵适合分类问题。二分类公式:

CE = -[y * log(ŷ) + (1 - y) * log(1 - ŷ)]

多分类用Categorical Cross-Entropy。为什么分类用交叉熵?因为它的梯度形式简单,收敛快。你想想看,MSE配合Sigmoid时梯度会饱和,交叉熵不会。

经验之谈:我建议分类任务无脑用交叉熵,回归任务用MSE或MAE。如果数据有异常值,MAE比MSE更鲁棒。

好了,这一章的内容就到这里。MLP是深度学习的基石,前向传播、反向传播、梯度下降、损失函数,这四个概念必须吃透。下一章我们聊聊激活函数和正则化,到时候见。


公众号:蓝海资料掘金营,微信deep3321