【免费下载链接】caffe-face
This branch is developed for deep face recognition
caffe-face 是基于 Caffe 的深度人脸识别(deep face recognition)训练分支,它的灵魂是一个名为Center Loss的自定义损失层:为每个人脸身份建立一个可学习的"特征中心",把同一人的特征紧凑地拉向中心,从而显著提升人脸特征的判别性,将 LFW 等验证集的单模型准确率推到 ~99% 的秘诀之一。本文从零讲清 Center Loss 的数学原理、梯度推导与工程用法。
💡 Center Loss 解决什么问题:从"单一 softmax 损失"到"双重损失"
常规人脸识别网络训练只靠 softmax loss:让分类器给正确身份输出最高概率。但它有两个短板:
- 梯度间接:softmax loss 主要修正分类器权重(fc6),对最终用于比对的人脸特征只起间接约束作用;
- 特征松散:部署时分类器通常被扔掉,剩下的只有 512 维特征向量。若同一人的特征四处发散,同人脸相似度下降,识别率直接被拖垮。
Center Loss 的思路非常直观 🎯:为每个身份 j 设一个中心点 c_j(可学习参数),再加一个损失衡量"每个样本特征离自己身份中心有多远"。训练时的总损失是两者加权和:
总损失 L = SoftmaxWithLoss + λ × CenterLoss(face 示例中 λ = 0.008)
📐 一个公式看懂 Center Loss 的数学原理
设一个 mini-batch 有 M 个人脸样本,特征维度 K,身份数 N;样本 i 的特征为 x_i,身份为 y_i,该身份的中心为 c_{y_i}:
距离项:D_i = x_i − c_{y_i}
损失函数:
L_c = (1 / 2M) × Σᵢ ‖D_i‖²
几何含义:每个人脸特征都被拉向自己身份的"聚点",loss 越小,该身份的特征团越紧。中心 c_j 本身也是可训练参数——它会像磁铁一样持续追踪类内均值,特征团移动时中心自动跟随。
🔍 三步读懂前向/反向传播实现
完整实现见 center_loss_layer.cpp,GPU 版本在 center_loss_layer.cu,层的 proto 参数(num_output、center_filler、axis)定义在 caffe.proto。
① 前向:算距离,再平方累加
对每个样本按标签取出对应中心,算出 D_i,然后对所有距离求平方和、除以 2M 输出 loss——对应代码中caffe_sub计算距离、caffe_cpu_dot求平方和的两步。
② 对特征求梯度:梯度 = 距离 ÷ M
loss 对特征 x_i 的梯度就是 D_i 缩放到 1/M 再回传给卷积主干(propagate_down[0]分支)。这正是"把特征拉向中心"的压力来源,它直接塑造 fc5 输出的 512 维嵌入。
③ 对中心求梯度:类内偏差平均
对身份 j,设 batch 中属于该身份的样本数为 n_j,则:
∂L_c / ∂c_j = (1 / (n_j + 1)) × Σ_{y_i = j} (c_j − x_i)
注意分母里的n_j + 1:这是一个工程平滑项——当某个身份在 batch 中出现次数很少时,削弱中心更新步长,避免中心剧烈震荡;batch 中完全没出现的身份梯度自然为 0,保持稳定。
🚀 为什么它能提升人脸判别性?
关键在于两个损失"分工协作":
| 损失 | 约束目标 | 几何效果 |
|---|---|---|
| SoftmaxWithLoss | 正确身份得分最高 | 类间分离:不同身份的特征团被推开 |
| CenterLoss | 特征逼近身份中心 | 类内紧凑:同一身份的特征团被压缩 |
- 直接雕刻特征:测试时网络只输出 fc5 的 512 维特征,用余弦相似度/欧氏距离比对。softmax 对这个特征向量的梯度太间接,Center Loss 才是直接"雕刻"嵌入空间的损失;
- 紧凑即判别性:同一个人特征越聚拢,"同人距离"与"异人距离"的间隔越大,判决阈值附近的误判率越小;
- 中心独立可训练:示例中给中心参数单独设置
lr_mult: 1、decay_mult: 2(face_train_test.prototxt),让中心更快跟上类内均值变化。
⚡ face_example 快速上手:3 步训练自己的人脸识别模型
第 1 步:克隆仓库并编译
git clone https://gitcode.com/gh_mirrors/ca/caffe-face # 安装方式与 Caffe 完全一致,按其官方安装文档操作第 2 步:看懂双损失网络配置
示例网络 "Face-ResNet"(10572 个身份)在 face_train_test.prototxt 尾部挂上双损失,CenterLoss 直接消费 512 维特征与标签:
layer { name: "center_loss" type: "CenterLoss" bottom: "fc5" # 512维人脸特征 bottom: "label" # 身份标签 top: "center_loss" loss_weight: 0.008 center_loss_param { num_output: 10572 # 必须与 fc6 的身份数一致 } }第 3 步:启动训练并提取特征
cd $CAFFE-FACE_ROOT ./build/tools/caffe train -solver face_example/face_solver.prototxt -gpu 0训练完成后,用 extractDeepFeature.m 基于部署网络 face_deploy.prototxt 抽取 512 维特征做 1:1 验证;超参数(base_lr 0.1、momentum 0.9、28000 迭代)见 face_solver.prototxt。
✅ 要点速览:符号与参数对照表
| 符号 / 参数 | 含义 | face 示例取值 |
|---|---|---|
| M(M_) | 批大小 | 256 |
| K(K_) | 特征维度 | 512 |
| N(N_) | 身份数量 | 10572 |
| λ(loss_weight) | Center Loss 权重 | 0.008 |
| center_filler | 中心初始化方式 | xavier |
| lr_mult / decay_mult | 中心独立学习率/衰减 | 1 / 2 |
常见疑问
- 非人脸数据集能用吗?可以。只要数据是"特征 + 类别标签"即可,仓库中 mnist_example/mnist_train_test.prototxt 就是 MNIST 上的玩具示例。
- 能否只保留 Center Loss 去掉 softmax?不建议。Center Loss 只知道"靠近自己人",没有推开异类的显式压力,必须与 softmax 搭配使用。
- λ 怎么调?太小则紧凑性约束失效,太大会挤压 softmax 的类间分离空间;0.008 量级是该实现的推荐起点。
Center Loss 的核心价值,是给深度人脸识别提供了第二条更直接的训练信号:softmax 管"区分",Center Loss 管"聚合"。读懂这层数学,再去理解后来的 triplet loss、ArcFace 等改进方法,就会发现它们大多是在同一个"类内紧凑 + 类间分离"的坐标轴上做文章。
【免费下载链接】caffe-face
This branch is developed for deep face recognition
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考