如何计算三层MLP分类器中数据点到决策边界的符号距离?
三层MLP计算数据点到决策边界的符号距离方法
核心原理:MLP的决策边界定义
MLP的决策边界由模型输出的「类别切换点」决定:
- 二分类(sigmoid输出):决策边界对应模型输出概率为0.5的点,而sigmoid函数
σ(z)=0.5等价于输出层的线性输出z=0(z是隐藏层输出经过最后一层权重、偏置计算后的结果)。 - 二分类(softmax输出):决策边界对应两类输出概率相等的点,即
z1=z2(z1、z2为两个类别的线性输出),等价于z1-z2=0。 - 多分类:任意两类i和j的决策边界是
zi=zj,即zi-zj=0。
符号距离的正负代表数据点落在决策边界的哪一侧(对应模型的预测倾向),绝对值代表远离边界的程度,全程无需依赖真实标签。
计算步骤
1. 获取输出层的线性输出
要计算距离,首先需要拿到模型输出层的线性输出(而非经过激活函数后的概率输出)。因为sigmoid/softmax是单调变换,线性输出的符号和绝对值直接对应到与决策边界的位置关系。
比如在PyTorch中,需要把模型拆分为「特征提取+输出层线性变换」和「激活层」两部分,从而单独获取线性输出z。
2. 未归一化的符号距离(直接计算)
这是最简便的方式,无需梯度计算:
- 二分类(sigmoid):直接用线性输出
z作为未归一化符号距离。z>0时模型预测正类,z<0时预测负类,z=0正好落在决策边界上。 - 二分类(softmax):用
z1-z2作为未归一化符号距离,值为正倾向第一类,负则倾向第二类。 - 多分类:计算任意两类的
zi-zj,得到对应类别边界的符号距离。
3. 归一化的几何符号距离(可选)
如果需要类似SVM的几何距离(即欧氏空间中到决策边界的垂直距离),需要结合梯度计算:
- 对输入数据
x开启梯度追踪,计算线性输出z(或zi-zj)。 - 反向传播计算
z对x的梯度∇x z,该梯度就是决策边界在该点的法向量方向。 - 归一化距离 = 未归一化距离 / 梯度的L2范数(
||∇x z||)。
这个值的正负代表方向,绝对值是真实的几何距离。
代码示例(PyTorch)
以二分类sigmoid输出的MLP为例:
import torch import torch.nn as nn # 定义可拆分输出线性层的MLP class MLP(nn.Module): def __init__(self, input_dim, hidden_dim): super().__init__() # 特征提取到输出层线性变换 self.feature_extractor = nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, 1) # 输出层线性变换,得到z ) self.sigmoid = nn.Sigmoid() def forward(self, x): z = self.feature_extractor(x) return self.sigmoid(z) # 初始化并加载训练好的模型 model = MLP(input_dim=2, hidden_dim=16) # model.load_state_dict(torch.load("trained_mlp.pth")) # 加载预训练权重 model.eval() # 计算单个数据点的符号距离 x = torch.tensor([[0.5, 1.2]], requires_grad=True) # 输入数据,开启梯度 # 步骤1:获取线性输出z z = model.feature_extractor(x) # 步骤2:未归一化符号距离 unnorm_dist = z.item() print(f"未归一化符号距离: {unnorm_dist}") print(f"预测倾向: {'正类' if unnorm_dist > 0 else '负类'}") # 步骤3:归一化几何符号距离 z.backward() # 计算z对x的梯度 grad_norm = x.grad.norm().item() norm_dist = unnorm_dist / grad_norm print(f"归一化几何符号距离: {norm_dist}")
多分类场景扩展
对于k类分类任务:
- 计算每一对类别(i,j)的
zi-zj,得到所有两两边界的未归一化符号距离。 - 若要找离该点最近的决策边界,取所有
|zi-zj|中的最小值,对应的符号距离就是该点到最近边界的距离。 - 同样可以通过梯度计算归一化的几何距离。
内容的提问来源于stack exchange,提问作者Hoin
相关产品推荐
相关产品推荐

