平方欧几里得距离(Squared Euclidean Distance)L2 距离(欧几里得距离,Euclidean Distance) 的主要区别在于它们的计算公式、梯度特性以及在深度学习中的应用。


1. 公式对比

对于两个向量 ( A ) 和 ( B )(维度为 ( d )):

  • ( A = (a_1, a_2, …, a_d) )
  • ( B = (b_1, b_2, …, b_d) )

(1) L2 距离(欧几里得距离)

[
d_{L2}(A, B) = \sqrt{\sum_{i=1}^{d} (a_i - b_i)^2}
]

  • 直接计算向量之间的欧几里得距离,具有平方根

(2) 平方欧几里得距离(Squared Euclidean Distance)

[
d_{\text{squared}}(A, B) = \sum_{i=1}^{d} (a_i - b_i)^2
]

  • 计算的是欧几里得距离的平方没有平方根

2. 数学和梯度特性

距离类型 是否有平方根 数值范围 梯度特性
L2 距离 ( \sqrt{\sum (a_i - b_i)^2} ) ✅ 有平方根 更小(与差值成线性比例) 梯度在远处较小,近处较陡峭
平方欧几里得距离 ( \sum (a_i - b_i)^2 ) ❌ 无平方根 较大(与差值平方成正比) 梯度变化更均匀,远处梯度更大
  • L2 距离(含平方根):

    • 远距离时,梯度较小,更新步伐变慢(因为平方根的梯度衰减)。
    • 近距离时,梯度较大,收敛快。
  • 平方欧几里得距离(不含平方根):

    • 远距离时,梯度较大,有助于优化更快收敛(平方项的梯度不会衰减)。
    • 但近距离时,梯度较小,可能导致收敛过慢。

梯度公式对比

  • L2 距离的梯度:
    [
    \frac{\partial d_{L2}}{\partial A} = \frac{A - B}{\sqrt{\sum (a_i - b_i)^2}}
    ]
    当 ( A ) 和 ( B ) 相距较远时,分母变大,导致梯度变小。

  • 平方欧几里得距离的梯度:
    [
    \frac{\partial d_{\text{squared}}}{\partial A} = 2(A - B)
    ]
    这里梯度不会因为平方根的影响而变小,梯度的大小只与点的间距成线性关系。


3. 应用场景对比

应用 使用平方欧几里得距离 使用L2距离
神经网络优化 推荐(梯度稳定) ❌ 梯度衰减过快
聚类(如 K-Means) 推荐(计算更快) ❌ 计算慢(不必要的 sqrt)
最近邻搜索(KNN) ❌ 可能会影响准确性 推荐
度量学习(Triplet Loss) 推荐(梯度更均匀) ❌ 梯度更新不稳定

4. 为什么 PyTorch TripletMarginLoss 用平方欧几里得距离?

PyTorch 默认 torch.nn.TripletMarginLoss 计算的是 平方欧几里得距离,原因是:

  1. 梯度稳定性:避免远距离时梯度消失,使得模型学习得更快、更稳定。
  2. 计算效率:平方根操作(sqrt)在神经网络训练中会增加计算成本,去掉 sqrt 可提高效率。
  3. 不会影响相对大小:L2 距离和平方欧几里得距离在 距离排序 上是等价的(即:哪个点更近,哪个更远不会改变)。

PyTorch TripletMarginLoss 实现

import torch.nn as nn

loss_fn = nn.TripletMarginLoss(margin=1.0, p=2)  # 默认 p=2 (欧几里得距离)
  • 这里 p=2 其实是计算 平方欧几里得距离 而非 L2 距离(因为 TripletMarginLoss 省略了 sqrt)。

5. 什么时候用 L2 距离?什么时候用平方欧几里得距离?

用平方欧几里得距离(不带 sqrt)的情况

  • K-Means 聚类(计算中心点时更快)
  • Triplet Loss / Contrastive Loss(梯度更稳定)
  • 深度学习优化(避免梯度消失)

用 L2 距离(带 sqrt)的情况

  • 最近邻搜索(KNN)
  • 直接计算距离排序
  • 计算物理意义上的真实距离(如 GPS 位置、视觉距离等)

6. 总结

关键点 L2 距离 平方欧几里得距离
计算公式 ( \sqrt{\sum (a_i - b_i)^2} ) ( \sum (a_i - b_i)^2 )
是否有 sqrt ✅ 有 ❌ 无
梯度变化 远处梯度变小 远处梯度稳定
计算速度 ❌ 慢(涉及 sqrt ✅ 快
适用于 最近邻搜索、物理距离计算 深度学习优化、聚类、Triplet Loss

推荐:

  1. 如果你在深度学习中优化嵌入空间(如 Triplet Loss、聚类),用 平方欧几里得距离 ✅。
  2. 如果你需要真实的几何距离(如 KNN),用 L2 距离 ✅。

🚀 结论

使用了 L2 距离,如果你的训练过程中梯度更新不稳定,可能会收敛较慢,可以考虑 改用平方欧几里得距离,即:

import torch

def contrastive_loss_v2(anchor, positive, negative, margin=1.0):
    # 计算平方欧几里得距离
    pos_dist = torch.norm(anchor - positive, p=2, dim=1) ** 2
    neg_dist = torch.norm(anchor - negative, p=2, dim=1) ** 2
    loss = torch.relu(pos_dist - neg_dist + margin)
    return loss.mean()

这样可以 提升梯度稳定性,训练更快收敛。🔥

Logo

电影级数字人,免显卡端渲染SDK,十行代码即可调用,工业级demo免费开源下载!

更多推荐