SphereFace是人脸识别领域的里程碑工作,它首次提出了角度间隔softmax(A-Softmax)的概念,把损失函数的设计从欧氏空间带入角度空间,直接影响了后续CosFace、ArcFace等一系列算法的演进。要理解SphereFace的价值,得先从传统softmax为什么不适合人脸识别说起。

传统softmax的几何缺陷
在分类任务中,softmax损失将特征向量经过全连接层得到每个类别的logit,再通过softmax归一化计算交叉熵。对于一个二分类问题,决策边界由W1x + b1 = W2x + b2决定,这个边界依赖于权重向量的模长、特征向量的模长以及偏置项,三个因素纠缠在一起,导致模型学到的特征分布并不理想。
更具体地说,训练完成后,如果只取最后一层全连接层的输入特征用于识别,会发现同一身份的特征在欧氏空间里散布较广,不同身份的特征之间也没有形成清晰的间隔。这是因为softmax损失只要求正确类别的logit最大,并不要求类别之间保持足够大的距离。在开放集人脸识别场景中,测试时遇到的大量身份是训练时从未见过的,特征必须具备足够强的判别性才能通过余弦相似度或欧氏距离正确匹配,而原始softmax给出的特征恰恰缺乏这种判别力。
作者做了一个关键观察:如果去掉偏置项,并把权重和特征都做L2归一化,logit就变成了||W|| ||x|| cos(θ),再进一步令||W|| = 1、||x||固定,logit就只依赖于夹角θ。此时决策边界变成cos(θ1) = cos(θ2),几何上正是角平分面,分类变成了在超球面上按角度划分区域,这就是角度空间分类的雏形。
角度间隔softmax的数学形式
SphereFace的核心思想是:既然决策由角度决定,那就人为地在正确类别对应的角度上施加一个惩罚,让模型必须把特征压到更靠近类别中心的位置才算分类正确。具体做法是把cos(θy)替换为cos(mθy),其中y是真实类别的下标,m是大于等于1的整数,通常取4。这个乘性间隔等价于要求同类特征与类别中心的夹角缩小为原来的1/m,类间因此形成明显的角度间隙。
import torch
import torch.nn as nn
import torch.nn.functional as F
class SphereProduct(nn.Module):
def __init__(self, in_features, out_features, m=4):
super(SphereProduct, self).__init__()
self.m = m
self.weight = nn.Parameter(torch.FloatTensor(out_features, in_features))
nn.init.xavier_uniform_(self.weight)
def forward(self, input, label):
# L2归一化权重与特征,logit退化为cos(theta)
x = F.normalize(input, p=2, dim=1)
W = F.normalize(self.weight, p=2, dim=1)
cos_theta = F.linear(x, W).clamp(-1, 1)
# 将cos(theta)转换为cos(m*theta)的等价多项式表达
cos_m_theta = self.cos_multiple(cos_theta)
# 真实类别位置使用cos(m*theta),其余类别保持不变
one_hot = F.one_hot(label, self.out_features).float()
output = one_hot * cos_m_theta + (1.0 - one_hot) * cos_theta
return output
def cos_multiple(self, cos_theta):
# 利用切比雪夫多项式展开,m=4时cos(4θ)=8cos^4θ-8cos^2θ+1
if self.m == 4:
return 8 * cos_theta.pow(4) - 8 * cos_theta.pow(2) + 1
elif self.m == 3:
return 4 * cos_theta.pow(3) - 3 * cos_theta
else:
raise ValueError('仅支持 m=3 或 m=4')
实现上有一个细节需要注意:直接计算arccos再乘m在数值上并不稳定,且梯度回传困难,所以原论文使用了切比雪夫多项式的恒等式,把cos(mθ)直接表示为cos(θ)的多项式。例如m=4时,cos(4θ) = 8cos⁴θ − 8cos²θ + 1。这样整个计算保持在余弦域内,可以直接用标准算子搭建,也便于反向传播。
从几何角度看,引入m之后,真实类别的决策条件从cos(θ1) > cos(θ2)变成了cos(mθ1) > cos(θ2)。为了满足这个更苛刻的条件,θ1必须足够小,也就是说特征必须被推得离类别中心更近。最终同一身份的特征在超球面上收缩成紧凑的簇,不同身份之间形成约m倍角度的间隔,这正是判别性特征的来源。
训练技巧与实践中的坑
SphereFace训练中最大的问题是初期不收敛。因为cos(mθ)在θ较大时的值可能非常小,甚至为负,导致真实类别的logit过小,梯度方向混乱。原论文采用了退火策略:在损失中引入一个超参数λ,用cos(mθ)与cos(θ)的加权组合来软化惩罚,λ从1000逐渐衰减到5,训练后期惩罚完全生效。
# 退火版本:lambda从1000逐步退火到5
lam = max(5.0, 1000.0 * (0.99 ** epoch))
output = one_hot * (lam * cos_theta + cos_m_theta) / (1.0 + lam) \
+ (1.0 - one_hot) * cos_theta
间隔m的取值也值得斟酌。m越大,类间间隔越大,特征判别性越强,但训练难度也急剧上升,论文实验表明m=4是较好的平衡点。此外,作者发现在角度空间建模时可以直接去掉偏置项,如果保留偏置反而会破坏角度空间的几何假设,这一点在复现时容易被忽略。
SphereFace之后,CosFace将其改进为加性间隔cos(θ) − s的形式,ArcFace则改成加性角度间隔cos(θ + m),两者都规避了乘性间隔带来的数值不稳定问题,训练更平稳、精度也更高。但理解SphereFace的角度空间建模思路依然是掌握这一系列算法的基础,它把损失函数设计从单纯的代数优化提升到了几何层面,这个视角的影响远超算法本身。
SphereFace人脸识别角度间隔softmax修改时间:2026-09-16 14:18:50