neural network中的loss function (二)

MSE损失和KL散度

1. 数学定义

MSE(均方误差)

对于两个概率分布 P 和 Q(都是离散概率向量),MSE定义为:

MSE(P,Q)=1/n∗Σ(Pi−Qi)2MSE(P, Q) = 1/n * Σ(P_i - Q_i)²MSE(P,Q)=1/nΣ(PiQi)2

其中 n 是类别数。

KL散度(Kullback-Leibler Divergence)

KL散度定义为:

KL(P∣∣Q)=ΣPi∗log(Pi/Qi)=ΣPi∗[log(Pi)−log(Qi)]KL(P || Q) = Σ P_i * log(P_i / Q_i) = Σ P_i * [log(P_i) - log(Q_i)]KL(P∣∣Q)=ΣPilog(Pi/Qi)=ΣPi[log(Pi)log(Qi)]

注意,KL散度是非对称的,即 KL(P∥Q)≠KL(Q∥P)KL(P∥Q)≠KL(Q∥P)KL(PQ)=KL(QP)

2. 特性对比

特性MSE损失KL散度
目标让两个分布"数值接近"让两个分布"形状相似"
对称性对称:MSE(P,Q)=MSE(Q,P)非对称
敏感度对所有差异平等惩罚,对离群值敏感(平方项)对零概率区域特别敏感
范围[0, ∞),单位是平方差[0, ∞),单位是信息比特
零点P=Q时为零P=Q时为零

情景1:两个分布完全一致

P = [0.5, 0.3, 0.2]
Q = [0.5, 0.3, 0.2]
  • MSE = 0
  • KL = 0
  • 两者相同

情景2:轻微差异

P = [0.5, 0.3, 0.2]
Q = [0.48, 0.31, 0.21]
  • MSE ≈ 很小值(如0.0005)
  • KL ≈ 很小值(如0.0002)
  • 两者相近

情景3:零概率区域的差异

P = [0.9, 0.1, 0.0]     # 第三类概率为0
Q = [0.8, 0.1, 0.1]     # 第三类有0.1概率

MSE计算

MSE=(0.9−0.8)2+(0.1−0.1)2+(0.0−0.1)2=0.01+0+0.01=0.02 MSE = (0.9-0.8)² + (0.1-0.1)² + (0.0-0.1)² = 0.01 + 0 + 0.01 = 0.02 MSE=(0.90.8)2+(0.10.1)2+(0.00.1)2=0.01+0+0.01=0.02

KL散度计算

KL=0.9∗log(0.9/0.8)+0.1∗log(0.1/0.1)+0.0∗log(0.0/0.1) KL = 0.9*log(0.9/0.8) + 0.1*log(0.1/0.1) + 0.0*log(0.0/0.1) KL=0.9log(0.9/0.8)+0.1log(0.1/0.1)+0.0log(0.0/0.1)

对数函数log(x)在x趋近于0时,其值趋近于负无穷大(-∞)。具体来说:
lim(x→0+)log(x)=−∞lim (x→0+) log(x) = -∞lim(x0+)log(x)=
然而,在我们的表达式中,0.0是一个精确的0,而不是趋近于0的极限。因此,可以认为:
0 * log(0) = 0 * (-∞)
这看起来是不确定的,但在许多实际应用中,尤其是在处理概率或信息论中的熵计算时,0 * log(0) 被定义为0。

洛必达法则验证:
令 y = 1/x, 则 x = 1/y, 当 x→0+, y→∞
x * log(x) = (1/y) * log(1/y) = - (log(y)) / y
当 y→∞, log(y)/y → 0
因此,lim (x→0+) x * log(x) = 0
所以,0.0 * log(0) = 0

KL 对「零区域」真正敏感的地方不在“乘出 −∞”,而在下面定义域要求:

  • 若 Q(i)=0,则 P(i) 必须 =0(否则出现 p>0 而 q=0,导致 p log(p/0)=+∞)。

违反则 KL 直接爆 +∞。
实际代码里常用两种办法避免“零”:

    • 加平滑(Laplace/Dirichlet):给 Q 赋一个极小伪计数 ε>0。
    • 掩码:只累加 P(i)>0 的项,其余跳过。

情景4: 梯度特性对比

MSE梯度

MSE对Q的梯度
∂MSE/∂Qi=2/n∗(Qi−Pi)∂MSE/∂Q_i = 2/n * (Q_i - P_i)MSE/Qi=2/n(QiPi)

梯度与差值成正比,稳定平滑。

KL散度梯度

** KL(P||Q)对Q的梯度**
∂KL/∂Qi=−Pi/Qi∂KL/∂Q_i = -P_i / Q_iKL/Qi=Pi/Qi

当Q_i很小时,梯度可能爆炸

3. 在知识蒸馏中的应用

在知识蒸馏中,通常使用KL散度来匹配教师和学生模型的输出分布。因为KL散度是信息论中衡量两个分布差异的自然方式,它直接对应于用学生分布Q来编码教师分布P所需的额外比特数。

  • KL散度:更常用于知识蒸馏,因为它是从信息论角度自然推导出来的,并且在实际应用中效果较好。
  • MSE:也可以使用,但可能不如KL散度效果好,因为它平等地对待所有错误,而KL散度更关注于分布的整体形状。

USNet中的loss

def ce_loss(p, alpha, c, global_step, annealing_step):
    S = torch.sum(alpha, dim=1, keepdim=True)
    E = alpha - 1
    label = F.one_hot(p, num_classes=c)
    A = torch.sum(label * (torch.digamma(S) - torch.digamma(alpha)), dim=1, keepdim=True)

    annealing_coef = min(1, global_step / annealing_step)

    alp = E * (1 - label) + 1
    B = annealing_coef * KL(alp, c)

    return (A + B)
  • alpha, “浓度”,也叫 Dirichlet 参数 α

  • annealing_coef 从训练开始 0 → 1 线性增长(“退火”)。

​ 目的:前期 抑制 KL 项 B,让网络先学好分类;后期逐渐加入 KL 正则,迫使模型对非目标类输出抑制

  • torch.digamma(x)对数伽马函数的一阶导数(ψ(x) = d/dx lnΓ(x))。

    当 x 很大时 ≈ log(x),但在 x→1 时会降到 -γ ≈ -0.577(负值),这是证据损失里常用的“近似 log” yet 可导且定义域 x>0 的函数。

KL正则

KL 正则 = Dirichlet KL 散度正则项英语发音 /dɪˈrɪʃlət/ → di-RISH-lət),用来 惩罚模型对非目标类的“多余证据”,从而

  1. 降低 不确定性
  2. 提高 OOD 检测 能力;
  3. 防止 过度自信

α' = E · (1 - y) + 1 只保留非目标类的证据
E = α - 1 是模型输出的原始证据;
y 是 one-hot 真值;
因此 目标类位置 α’=1,不会受惩罚。只对 非目标类 计算 KL,因此 不影响正确类学习

公式

给定两个 Dirichlet 分布
 Dir(α) 与 Dir(β),α, β ∈ ℝ_{>0}^C
KL[Dir(α)∣∣Dir(β)]= logΓ(Σαc)−ΣlogΓ(αc) −logΓ(Σβc)+ΣlogΓ(βc) +Σ(αc−βc)[ψ(αc)−ψ(Σαc)] KL[Dir(α) || Dir(β)] = log Γ(Σα_c) − Σlog Γ(α_c)  − log Γ(Σβ_c) + Σlog Γ(β_c)  + Σ(α_c − β_c)[ψ(α_c) − ψ(Σα_c)] KL[Dir(α)∣∣Dir(β)]=logΓ(Σαc)ΣlogΓ(αc)logΓ(Σβc)+ΣlogΓ(βc)+Σ(αcβc)[ψ(αc)ψ(Σαc)]
符号说明
 Γ  伽马函数
 ψ  digamma 函数(对数伽马的一阶导)
 Σα_c ≡ Sα 总浓度

代码里 β=ones© ⇒ Σβ_c = C, β_c = 1,公式可进一步简化。

superpoint和superglue训练时使用的loss

1. SuperPoint 的损失函数

SuperPoint是一个自监督训练的特征点检测器和描述子提取器。它的训练分为两个阶段,损失函数也相应由两部分组成。

网络输出:

  • 特征点检测头:输出一个尺寸为 H x W x 65 的“像素粒度”热图。其中65个通道代表一个8x8的局部网格加一个“无特征点”的额外通道。
  • 描述子头:输出一个尺寸为 H x W x D(通常D=256)的稠密描述子图。

损失函数:
总损失是特征点损失和描述子损失的加权和:
L_total = L_point + λ * L_desc

a) 特征点检测损失 L_point
这是一个交叉熵损失,用于分类每个像素位置是否为“特征点”。

  • 关键:如何获得训练标签(真值)?这是SuperPoint的核心创新——Homographic Adaptation
    1. 预训练:先在合成形状数据集(如MS-COCO)上训练一个基础检测器(MagicPoint)。这个合成数据有明确角点/特征点真值。
    2. 自标注:对真实场景图像,随机生成多个随机单应性矩阵(H),将图像进行变换。用预训练的MagicPoint检测每张变换后图像上的点,再通过单应性逆变换H_inv将点映射回原始图像坐标。
    3. 聚合:对同一张原始图像,进行多次上述过程,将所有映射回来的点聚合(取平均或最大值),形成一个概率热图,作为该图像特征点检测的“伪真值”。
  • 损失计算:将网络输出的 65通道 图 reshape 成 (H*W) x 65,然后与上述方法生成的 (H*W) 真值标签计算交叉熵损失。这个损失鼓励网络在“可重复”的角点/斑块位置上输出高响应。

b) 描述子损失 L_desc
这是一个基于间隔(Margin)的对比损失,旨在使匹配的描述子更接近,不匹配的描述子更远离。

  • 采样:在一对经过单应性变换的图像 (I, I') 中,假设我们知道它们之间的单应性矩阵 H。在图像 I 中提取特征点位置 p,通过 H 可以计算出其在 I' 中的准确对应位置 p'
  • 正负样本对
    • 正样本:点 p 和其对应点 p’ 的描述子 (d, d’_pos)
    • 负样本:点 pI' 中另一个非对应点 q’ 的描述子 (d, d’_neg)
  • 损失形式:通常采用 Hinge-loss(三元组损失的一种形式)
    L_desc = max(0, m + ||d - d‘_pos||² - ||d - d’_neg||²)
    其中 m 是一个大于0的间隔超参数(例如 1.0)。这个损失要求正样本对的距离至少比负样本对的距离小一个间隔 m
  • 工程细节:实际中会用到“描述子图的双线性插值”来获取亚像素位置的描述子,并且在所有可能点对上进行困难负样本挖掘,以提升训练效率。

2. SuperGlue 的损失函数

SuperGlue是一个图神经网络,它接受两组来自SuperPoint(或其他检测器)的特征点(位置+描述子),输出一个“匹配矩阵”和一个“未匹配分数”。它的损失函数是监督学习的,需要真实匹配标签。

网络输出:

  • 匹配矩阵 P:尺寸为 M x N,其中 P[i, j] 表示图A中点 i 与图B中点 j 匹配的概率。
  • 未匹配向量:每个点还有一个“不与任何点匹配”的分数。

损失函数:
这是一个最大似然估计的负对数似然损失,通常基于 最优传输理论Sinkhorn算法 来构造。损失函数鼓励给真值匹配分配高概率,给非匹配点分配低概率。

具体形式可以表述为:
L_match = - Σ_{(i, j) ∈ M} log(P[i, j]) - Σ_{i ∈ I} log(P[i, N+1]) - Σ_{j ∈ J} log(P[M+1, j])

解释:

  1. 真值匹配对:对于所有已知的真值匹配对 (i, j),最大化其对应的匹配概率 P[i, j](即最小化其负对数)。
  2. 未匹配点:这是关键!P[i, N+1] 表示图A中点 i “未匹配”的概率(N+1 是一个虚拟的“未匹配”节点)。对于图A中实际上没有对应点的特征点 i,我们需要最大化 P[i, N+1]
  3. 对称性:同样地,对于图B中未匹配的点 j,我们需要最大化 P[M+1, j]

如何获得训练标签?
SuperGlue的训练需要图像对以及它们之间的真值几何变换(在室内数据集上通常是深度图计算出的相机位姿,在室外数据集上可能是GPS/IMU标定或SfM稀疏重建结果)。

  • 给定变换关系,可以计算图A中的点 i 在图B上的极线距离重投影误差
  • 如果误差小于一个阈值(例如几个像素),则 (i, j) 被视为一个正样本匹配对。
  • 如果一个点在图B中没有足够近的对应点,则被标记为“未匹配”。

核心思想:SuperGlue的损失不仅学习如何匹配,更重要的是学习何时拒绝匹配。它通过图神经网络和注意力机制,结合外观(描述子)和几何(相对位置)信息,对上下文进行推理,最终解决一个局部特征匹配中最优分配问题。

总结对比

模型训练方式损失函数核心目标
SuperPoint自监督1. 交叉熵损失(特征点) 2. 对比损失(描述子)提取可重复可区分的特征点和描述子。
SuperGlue监督学习负对数似然损失(基于最优传输)给定两组特征点,输出一个最优的、考虑上下文的匹配分配,包括识别未匹配点。
### 关于神经网络中梯度下降法的学习原理 在神经网络训练过程中,梯度下降是一种常用的优化算法。该方法旨在最小化损失函数 \(L(\theta)\),通过调整模型参数 \(\theta\) 来减少预测误差。具体来说,对于给定的数据集以及初始权重设置,梯度下降会按照负梯度方向更新这些权重,从而逐步逼近全局最优解或局部极小值。 为了有效执行这一过程,现代深度学习框架提供了自动微分功能来高效地计算相对于某些参数的梯度[^2]。这意味着开发者无需手动推导复杂的偏导数表达式;相反,只需定义前向传播逻辑即可让库自动生成对应的反向传播路径并完成必要的求导操作。 然而值得注意的是,在初始化阶段如果简单地将所有的\(\Theta\)矩阵元素设为零,则可能导致所有节点在同一轮次内被相同数值覆盖而无法正常工作。为了避免这种情况发生,建议采用随机方式赋予各层连接权值不同的初值[^3]。 ### 实现神经网络中的梯度下降 下面给出一段简单的Python代码片段作为例子展示如何利用PyTorch实现基于mini-batch SGD(Mini-Batch Stochastic Gradient Descent)策略下的线性回归模型: ```python import torch from torch import nn, optim class LinearRegressionModel(nn.Module): def __init__(self): super().__init__() self.linear = nn.Linear(1, 1) def forward(self, x): return self.linear(x) model = LinearRegressionModel() criterion = nn.MSELoss() # Mean Squared Error Loss Function optimizer = optim.SGD(model.parameters(), lr=0.01) # Learning Rate Set To 0.01 for epoch in range(num_epochs): # Number Of Epochs Defined By User running_loss = 0.0 for inputs, targets in dataloader: # DataLoader Provides Mini-Batches From Dataset optimizer.zero_grad() # Clear Previous Gradients outputs = model(inputs) # Forward Pass Through The Network loss = criterion(outputs, targets) loss.backward() # Backward Propagation And Compute Gradients With Respect To Parameters optimizer.step() # Update Weights Using Computed Gradients According To Optimizer Rule print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss:.4f}') ``` 这段程序首先构建了一个单输入单输出的一元线性回归器,并指定了均方差作为衡量标准。接着选择了SGD作为优化手段之一,设置了适当的学习率以控制每一步变化幅度大小。最后进入循环体内部完成了整个训练流程——即依次读取小型批次样本、清空旧有梯度信息、正向传递获取当前估计结果、依据实际标签评估差异程度、沿逆序路线累积敏感度直至起点处形成完整的梯度链表结构、最终依照选定规则修正各个待调参项的具体数值。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值