平方欧几里得距离(Squared Euclidean Distance) 和 L2 距离(欧几里得距离,Euclidean Distance)
这里梯度不会因为平方根的影响而变小,梯度的大小只与点的间距成线性关系。当 ( A ) 和 ( B ) 相距较远时,分母变大,导致梯度变小。的主要区别在于它们的计算公式、梯度特性以及在深度学习中的应用。,如果你的训练过程中梯度更新不稳定,可能会收敛较慢,可以考虑。PyTorch 默认。
平方欧几里得距离(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 计算的是 平方欧几里得距离,原因是:
- 梯度稳定性:避免远距离时梯度消失,使得模型学习得更快、更稳定。
- 计算效率:平方根操作(
sqrt)在神经网络训练中会增加计算成本,去掉sqrt可提高效率。 - 不会影响相对大小: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 |
推荐:
- 如果你在深度学习中优化嵌入空间(如 Triplet Loss、聚类),用 平方欧几里得距离 ✅。
- 如果你需要真实的几何距离(如 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()
这样可以 提升梯度稳定性,训练更快收敛。🔥
更多推荐



所有评论(0)