1565 字
8 分钟
模式识别与机器学习:非线性分类-多层感知机分类器
2026-05-21
无标签

多层感知机分类器#

基本思想:通过多个隐藏层非线性变换,将输入数据映射到一个新的特征空间,使得在这个空间中数据可以被线性分割

可以同时学习:

  1. 非线性映射方式
  2. 线性判别函数

关于神经元#

单个神经元的结构如图

alt text

数学模型如下:

y=f(wTx)=f(i=0nwixi)y=f(\mathbf{w}^T\mathbf{x})=f\left( \sum_{i=0}^n w_i x_i\right)

其中 w\mathbf{w} 是权重向量(已经增广包含偏置项),x\mathbf{x} 是输入向量(已经是增广向量),ff 是激活函数。

网络设置#

多层感知机由输入层、一个或多个隐藏层和输出层组成。每层由多个神经元组成,层与层之间全连接。

通常采用三层神经网络(输入层-隐藏层-输出层)来实现非线性分类。

节点数量激活函数
输入层n=dim(x)n=\dim(\mathbf{x})线性函数
隐藏层mm,需要设定非线性函数(如ReLU、Sigmoid、Tanh)
输出层c=c= 类别数量线性函数或Sigmoid函数

前向传播的函数#

kk 个输出层神经元的输出为:

zk=gk(x)=f2(j=0nHwkj(2)f1(i=0dim(x)wji(1)xi))\mathbf{z}_k=g_k(\mathbf{x}) = f_2\left( \sum_{j=0}^{n_H} w_{kj}^{(2)} f_1\left( \sum_{i=0}^{\dim(\mathbf{x})} w_{ji}^{(1)} x_i \right) \right)

或者把偏置项提出来

zk=gk(x)=f2(j=1nHwkj(2)f1(i=1dim(x)wji(1)xi+wj0(1))+wk0(2))\mathbf{z}_k=g_k(\mathbf{x}) = f_2\left( \sum_{j=1}^{n_H} w_{kj}^{(2)} f_1\left( \sum_{i=1}^{\dim(\mathbf{x})} w_{ji}^{(1)} x_i + w_{j0}^{(1)} \right) + w_{k0}^{(2)} \right)

训练算法-BP:反向传播算法#

TIP

神经网络的其他学习机制还包括记忆学习SOM、竞争学习、Hebbian学习等。

BP 算法的实质是一个均方误差最小LMS问题,采用梯度下降法来更新权重。

符号说明#

符号含义维度/说明
dd输入特征维数标量
nHn_H隐藏层节点数标量
cc输出节点数(类别数)标量
x=(x1,x2,...,xd)T\mathbf{x} = (x_1, x_2, ..., x_d)^T一个训练样本的输入特征向量d×1d \times 1
t=(t1,...,tc)T\mathbf{t} = (t_1, ..., t_c)^T样本对应的期望输出(标签)c×1c \times 1,分类任务常用 one-hot 编码
wjiw_{ji}输入层 → 隐藏层的连接权重ii 输入节点,jj 隐藏节点
wj0w_{j0}隐藏层第 jj 个节点的偏置(bias)可视为输入固定为 1 时的权重
netjnet_j隐藏层第 jj 个节点的加权输入和,理解为输入层的净输出,隐藏层的净输入netj=i=1dwjixi+wj0net_j = \sum_{i=1}^{d} w_{ji} x_i + w_{j0}
yjy_j隐藏层第 jj 个节点的输出yj=f1(netjy_j = f_1(net_j),f1f_1 为隐藏层激活函数
wkjw_{kj}隐藏层 → 输出层的连接权重jj 隐藏节点,kk 输出节点
wk0w_{k0}输出层第 kk 个节点的偏置
netknet_k输出层第 kk 个节点的加权输入和,理解为隐藏层的净输出,输出层的净输入netk=j=1nHwkjyj+wk0net_k = \sum_{j=1}^{n_H} w_{kj} y_j + w_{k0}
zkz_k输出层第 kk 个节点的实际输出zk=f2(netkz_k = f_2(net_k),f2f_2 为输出层激活函数
JJ损失函数(误差平方和的一半)J=12k=1c(tkzk)2J = \frac{1}{2} \sum_{k=1}^{c} (t_k - z_k)^2
η\eta学习率正标量,控制权重调整步长
δk\delta_k输出层第 kk 节点的局部梯度δk=(tkzk)f2(netk\delta_k = (t_k - z_k) f_2'(net_k)
δj\delta_j隐藏层第 jj 节点的局部梯度δj=f1(netj)k=1cδkwkj\delta_j = f_1'(net_j) \sum_{k=1}^{c} \delta_k w_{kj}

BP 算法是梯度下降在多层神经网络上的具体实现,分为三步:
前向传播 → 输出层梯度计算 → 反向传播 → 权重更新

步骤 1:前向传播(计算所有节点输出)#

对于单个训练样本 (x,t(\mathbf{x}, \mathbf{t}):

  1. 计算隐藏层每个节点的加权输入和

    netj=i=1dwjixi+wj0,j=1,2,...,nHnet_j = \sum_{i=1}^{d} w_{ji} x_i + w_{j0}, \quad j = 1, 2, ..., n_H
  2. 通过激活函数 f1f_1 得到隐藏层输出

    yj=f1(netj)y_j = f_1(net_j)
  3. 计算输出层每个节点的加权输入和

    netk=j=1nHwkjyj+wk0,k=1,2,...,cnet_k = \sum_{j=1}^{n_H} w_{kj} y_j + w_{k0}, \quad k = 1, 2, ..., c
  4. 通过激活函数 f2f_2 得到网络最终输出

    zk=f2(netk)z_k = f_2(net_k)
  5. 计算当前样本的损失(单个样本)

    J=12k=1c(tkzk)2J = \frac{1}{2} \sum_{k=1}^{c} (t_k - z_k)^2

步骤 2:反向传播(计算梯度)#

目的是求出损失函数对每个权重的偏导数 Jw\dfrac{\partial J}{\partial w}

2.1 输出层局部梯度 δk\delta_k#

根据链式法则:

Jwkj=Jzkzknetknetkwkj\frac{\partial J}{\partial w_{kj}} = \frac{\partial J}{\partial z_k} \cdot \frac{\partial z_k}{\partial net_k} \cdot \frac{\partial net_k}{\partial w_{kj}}
  • Jzk=(tkzk\dfrac{\partial J}{\partial z_k} = -(t_k - z_k)

  • zknetk=f2(netk\dfrac{\partial z_k}{\partial net_k} = f_2'(net_k)

  • netkwkj=j=1nHwkjyj+wk0wkj=yj\dfrac{\partial net_k}{\partial w_{kj}} =\dfrac{\partial\sum_{j=1}^{n_H}w_{kj} y_j + w_{k0}}{\partial w_{kj}} = y_j

因此:

Jwkj=(tkzk)f2(netk)yj\frac{\partial J}{\partial w_{kj}} = -(t_k - z_k) f_2'(net_k) \, y_j

定义输出层局部梯度:

δk(tkzk)f2(netk)Jwkj=δkyj\delta_k \triangleq (t_k - z_k) f_2'(net_k) \quad \Rightarrow \quad \frac{\partial J}{\partial w_{kj}} = -\delta_k y_j

2.2 隐藏层局部梯度 δj\delta_j#

对于隐藏层权重 wjiw_{ji}

Jwji=Jyjyjnetjnetjwji\frac{\partial J}{\partial w_{ji}} = \frac{\partial J}{\partial y_j} \cdot \frac{\partial y_j}{\partial net_j} \cdot \frac{\partial net_j}{\partial w_{ji}}
  • yjnetj=f1(netj\dfrac{\partial y_j}{\partial net_j} = f_1'(net_j)

  • netjwji=xi\dfrac{\partial net_j}{\partial w_{ji}} = x_i

难点是 Jyj\dfrac{\partial J}{\partial y_j},因为 yjy_j 会影响所有输出 z1...zcz_1...z_c

Jyj=k=1cJzkzknetknetkyj\frac{\partial J}{\partial y_j} = \sum_{k=1}^{c} \frac{\partial J}{\partial z_k} \cdot \frac{\partial z_k}{\partial net_k} \cdot \frac{\partial net_k}{\partial y_j}

已知:

  • Jzk=(tkzk\dfrac{\partial J}{\partial z_k} = -(t_k - z_k)

  • zknetk=f2(netk\dfrac{\partial z_k}{\partial net_k} = f_2'(net_k)

  • netkyj=wkj\dfrac{\partial net_k}{\partial y_j} = w_{kj}

所以:

Jyj=k=1c(tkzk)f2(netk)wkj=k=1cδkwkj\frac{\partial J}{\partial y_j} = -\sum_{k=1}^{c} (t_k - z_k) f_2'(net_k) w_{kj} = -\sum_{k=1}^{c} \delta_k w_{kj}

代入原式:

Jwji=(k=1cδkwkj)f1(netj)xi\frac{\partial J}{\partial w_{ji}} = \left( -\sum_{k=1}^{c} \delta_k w_{kj} \right) \cdot f_1'(net_j) \cdot x_i

定义隐藏层局部梯度:

δjf1(netj)k=1cδkwkj\delta_j \triangleq f_1'(net_j) \sum_{k=1}^{c} \delta_k w_{kj}

于是:

Jwji=δjxi\frac{\partial J}{\partial w_{ji}} = -\delta_j x_i

步骤 3:权重更新(梯度下降)#

对于输出层权重:

wkjwkjηJwkj=wkj+ηδkyjw_{kj} \leftarrow w_{kj} - \eta \frac{\partial J}{\partial w_{kj}} = w_{kj} + \eta \,\delta_k y_j

对于隐藏层权重:

wjiwji+ηδjxiw_{ji} \leftarrow w_{ji} + \eta \,\delta_j x_i

偏置(wj0,wk0w_{j0}, w_{k0})的更新:
将偏置视为输入为 +1 的权重,只需把上面公式中的 xix_iyjy_j 换为 1 即可。


BP 算法的批量版本(BGD)#

实际中通常使用批量更新(一次处理多个样本后累加梯度):

Terminal window
初始化所有权重为小的随机值
repeat (epoch):
Δw_kj = 0, Δw_ji = 0 // 累积梯度变量
for each 样本 (x, t) in 训练集:
// 前向传播
计算所有 y, z
// 反向传播计算当前样本的梯度分量
计算输出层 δ_k
计算隐藏层 δ_j
// 累加梯度
Δw_kj += η * δ_k * y_j
Δw_ji += η * δ_j * x_i
end
// 批量更新
w_kj = w_kj + Δw_kj
w_ji = w_ji + Δw_ji
until 终止条件(如验证集误差不再下降 达到最大迭代次数)

关键点总结#

  1. 前向传播得到网络输出和损失。
  2. 反向传播利用链式法则,将输出层的误差“传播”回隐藏层,从而计算出每一层权重的梯度。
  3. 局部梯度 δ\delta 扮演核心角色:
    • 输出层 δk\delta_k 直接由预测误差和激活函数导数决定。
    • 隐藏层 δj\delta_j 依赖于输出层的 δk\delta_k 和连接权重 wkjw_{kj}
  4. 权重更新沿负梯度方向,使损失下降。
模式识别与机器学习:非线性分类-多层感知机分类器
https://biscuit0613.github.io/posts/ml/nonlinear-mlpclf/
作者
Biscuit
发布于
2026-05-21
许可协议
CC BY-NC-SA 4.0