实验背景
在前面的深度学习之用CelebA_Spoof数据集搭建一个活体检测-模型搭建和训练,我们基于CelebA_Spoof数据集构建了一个用SqueezeNe框架进行训练的活体2D模型,采用了蒸馏法进行了一些简单的工作。在前面提供的训练参数中,主要用了以下几个参数:
lr=0.001, step_size=10, gamma=0.1, alpha=0.5, T=3.0, epochs=300, log_interval=5, batch_size=128, save_interval=10, eval_interval=5
但是,效果并不是很好,得到的评估指标为:
{
'Accuracy': 0.8841447074586869, 'Precision': 0.9865851252712566, 'Recall': 0.8468018456588917, 'F1': 0.9113647235700131, 'FPR': 0.027303754266211604, 'ROC_AUC': 0.9661331014932475, 'EER': 0.076691427424212, 'PR_AUC': 0.9862052738456543, 'AP': 0.9862056134292535}
对于一个好的活体检测模型来说,各项指标都不是很好。对于这个指标,就需要进一步进行全面的分析了,如:预处理、训练的各个参数的玄学调整,模型结构深度,蒸馏中的权重比等等之类。在各种折腾后都得不到比较好的改变,于是想在特征上进行改进,如果人工再加点特征试试,会是怎样?这突发奇想就想到了:傅里叶变换。为什么用它,因为非活体的照片很多都是翻拍的,那么因为相机或者屏幕的闪烁,可能会出现一些条纹或者频域上的特征,这些就有可能很好的区分这两类图片。为了提升模型对伪造攻击的识别能力,我们尝试在训练过程中加入傅里叶变换作为辅助特征。
方法对比
基线模型训练时候的训练过程(无傅里叶变换)
直接是普通的蒸馏训练过程,正常的损失计算。
# 传统RGB图像预处理
def _compute_loss(self, student_out, teacher_out, targets):
current_T = max(1.0, self.args.T * (0.95 ** (self.current_epoch/10)))
"""计算蒸馏损失"""
# KL散度损失
kl_loss = nn.KLDivLoss(reduction='batchmean')(
torch.log_softmax(student_out/self.args.T, dim=1),
torch.softmax(teacher_out/self.args.T, dim=1)
) * (current_T ** 2)
# 交叉熵损失
ce_loss = self.criterion(student_out, targets)
total_loss = self.args.alpha * kl_loss + (1 - self.args.alpha) * ce_loss
return total_loss
def train_epoch(self, train_loader, epoch):
try:
"""完整训练逻辑"""
self.student.train()
self.current_epoch = epoch
total_loss = 0.0
correct = 0
total = 0
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(self.device), target.to(self.device)
if

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



