人臉識別最新進展

極市導讀
?本文著重指出了人臉識別研究中存在的幾個問題,并總結(jié)了該領(lǐng)域后期研究中的創(chuàng)新點。>>加入極市CV技術(shù)交流群,走在計算機視覺的最前沿
曠視的一篇文章人臉識別中Softmax-based Loss的演化史對于人臉識別的前期發(fā)展做了充分的總結(jié),本文旨在總結(jié)一下人臉識別后期研究。
Mis-classifified Vector Guided Softmax Loss for Face Recognition
現(xiàn)有人臉識別算法存在的問題
論文創(chuàng)新點
MV-Softmax loss的設(shè)計理念和損失函數(shù)



學習這個損失,并分析一下其中的設(shè)計理念。作者認為良好分離的特征向量對學習問題的影響很小。這就意味著錯誤分類的特征向量對于提高特征的鑒別能力變得尤為關(guān)鍵。為了將訓練重點放在真正具有鑒別特性的難例樣本上(即錯誤分類向量)。作者定義了一個二值指標Ik,自適應(yīng)地表示當前階段某個樣本(特征)是否被特定分類器wk(其中k不等于其真正的類y)誤分類,具體形式如式5所示。從Eq.(5)的定義可以看出,如果一個樣本(特征)分類錯誤,即, f(m, Θwy, x) - cos(Θwk, x) < 0(例如:,在圖1的左子圖中,特征x2屬于類1,但分類器w2對其進行了錯誤分類,即f(m,Θw1, x2) - cos(Θw2, x2) < 0),該樣本x2將會被暫時強調(diào),即標Ik= 1。這樣,困難的例子就被明確的指出來,我們主要針對這些困難的例子進行區(qū)分訓練。換句話說作者認為落在間隔的樣本為難例樣本。因此作者定義了新的損失函數(shù),如公式6所示。
公式6中的h(t,Θwk,x, Ik)≥1是一個重置權(quán)重函數(shù),以強調(diào)指明的錯誤分類向量。這里我們給出了兩個候選,一個是所有錯誤分類的類的固定權(quán)重如公式7和一個自適應(yīng)的權(quán)重如公式8。

難例挖掘分析
如fig1所示,假設(shè)我們有兩個樣本(特征)x1和x2,它們都來自類1,其中x1是分類良好的,而x2不是。HM-Softmax經(jīng)驗地表示了困難樣本,拋棄了簡單樣本x1,使用困難樣本x2進行訓練。F-Softmax沒有明確表示困難樣本,但它重新加權(quán)所有的樣本,使較困難的一個x2有相對較大的損失值。這兩種策略都是直接從損失的角度出發(fā)的,難例的選擇沒有語義指導。而MV-Softmax損失卻不同。
自適應(yīng)間隔分析
假設(shè)我們有來自類1的樣本x2,且其沒有正確分類(如圖1左圖的紅點)。原始的softmax loss旨在讓

為了讓該目標函數(shù)更嚴格,基于間隔的損失函數(shù)介紹了一個來自ground truth類(即Θ1)角度的邊界函數(shù)

其中,f(m, Θ1)對于不同的類具有相同且固定的邊界,忽略了與其他非ground truth類(如:Θ2和Θ3)的潛在區(qū)別性。為了解決這些問題,我們的MV-Softmax loss試圖從其他非ground truth類的角度進一步擴大特征。具體來說,我們?yōu)殄e誤分類的特征x2引入了一個邊界函數(shù)h?(t,Θ2):

對于Θ3,因為x2被其正確分類(即判定x2不是類3),所以我們不需要對其添加額外的增強去進一步增大其的邊界。而且,我們的MV-Softmax loss也為不同的類設(shè)置了不同的可適應(yīng)邊界。以 MV-AM-Softmax(即

)為例,對于錯誤分類的類,其邊界為

。然而對于正確分類的類,其邊界為m?;谶@些特性,我們的MV-Softmax loss解決了基于間隔損失函數(shù)的第二和第三個缺點。
class SVXSoftmax(nn.Module):
r"""Implement of Mis-classified Vector Guided Softmax Loss for Face Recognition
(https://arxiv.org/pdf/1912.00833.pdf):
Args:
in_features: size of each input sample
out_features: size of each output sample
device_id: the ID of GPU where the model will be trained by model parallel.
if device_id=None, it will be trained on CPU without model parallel.
s: norm of input feature
m: margin
cos(theta+m)
"""
def __init__(self, in_features, out_features, xtype='MV-AM', s=32.0, m=0.35, t=0.2, easy_margin=False):
super(SVXSoftmax, self).__init__()
self.xtype = xtype
self.in_features = in_features
self.out_features = out_features
self.s = s
self.m = m
self.t = t
self.weight = Parameter(torch.FloatTensor(out_features, in_features))
self.weight.data.uniform_(-1, 1).renorm_(2, 1, 1e-5).mul_(1e5)
self.easy_margin = easy_margin
self.cos_m = math.cos(m)
self.sin_m = math.sin(m)
def forward(self, input, label):
cos_theta = F.linear(F.normalize(input), F.normalize(self.weight))
cos_theta = cos_theta.clamp(-1, 1) # for numerical stability
batch_size = label.size(0)
gt = cos_theta[torch.arange(0, batch_size), label].view(-1, 1) # ground truth score
if self.xtype == 'MV-AM':
mask = cos_theta > gt - self.m
hard_vector = cos_theta[mask]
cos_theta[mask] = (self.t + 1.0) * hard_vector + self.t # adaptive
# cos_theta[mask] = hard_vector + self.t #fixed
if self.easy_margin:
final_gt = torch.where(gt > 0, gt - self.m, gt)
else:
final_gt = gt - self.m
elif self.xtype == 'MV-Arc':
sin_theta = torch.sqrt(1.0 - torch.pow(gt, 2))
cos_theta_m = gt * self.cos_m - sin_theta * self.sin_m # cos(gt + margin)
mask = cos_theta > cos_theta_m
hard_vector = cos_theta[mask]
cos_theta[mask] = (self.t + 1.0) * hard_vector + self.t # adaptive
# cos_theta[mask] = hard_vector + self.t #fixed
if self.easy_margin:
final_gt = torch.where(gt > 0, cos_theta_m, gt)
else:
final_gt = cos_theta_m
# final_gt = torch.where(gt > cos_theta_m, cos_theta_m, gt)
else:
raise Exception('unknown xtype!')
cos_theta.scatter_(1, label.data.view(-1, 1), final_gt)
cos_theta *= self.s
return cos_thetaCurricularFace
人臉識別中常用損失函數(shù)主要包括兩類,基于間隔和難樣本挖掘,這兩種方法損失函數(shù)的訓練策略都存在缺陷。
為了解決上述問題,優(yōu)圖實驗室引入了Curriculum Learning的概念來優(yōu)化損失函數(shù)。
Curriculum Learning即課程學習

CurricularFace的算法思想
將課程學習的思想嵌入到損失函數(shù)中,以實現(xiàn)一種新的深度人臉識別訓練策略。該策略主要針對早期訓練階段的易樣本和后期訓練階段的難樣本,使其在不同的訓練階段,通過一個課程表自適應(yīng)地調(diào)整簡單和困難樣本的相對重要性。也就是說,在每個階段,不同的樣本根據(jù)其相應(yīng)的困難程度被賦予不同的重要性。
CurricularFace和傳統(tǒng)課程學習的異同
CurricularFace的設(shè)計理念及損失函數(shù)
為了在整個訓練過程中實現(xiàn)自適應(yīng)課程學習的目標,優(yōu)圖實驗室設(shè)計了一種新的系數(shù)函數(shù),該函數(shù)包括以下兩個因子:
損失函數(shù)


上式的含義是:如果一個樣本是易樣本,它的Negative余弦相似度保持原始狀態(tài),即為;如果一個樣本是難樣本,它的Negative余弦相似度就變成了。
我們再來看下公式中的自適應(yīng)估計參數(shù)_t_是如何定義的。優(yōu)圖實驗室采用指數(shù)移動平均(EMA)來實現(xiàn)這個自適應(yīng)的參數(shù)。公式如下,其中的是第k個Batch的Positive余弦相似度均值,是沖量參數(shù)設(shè)為0.99。

class CurricularFace(nn.Module):
r"""Implement of CurricularFace (https://arxiv.org/pdf/2004.00288.pdf):
Args:
in_features: size of each input sample
out_features: size of each output sample
device_id: the ID of GPU where the model will be trained by model parallel.
if device_id=None, it will be trained on CPU without model parallel.
m: margin
s: scale of outputs
"""
def __init__(self, in_features, out_features, m = 0.5, s = 64.):
super(CurricularFace, self).__init__()
self.in_features = in_features
self.out_features = out_features
self.m = m
self.s = s
self.cos_m = math.cos(m)
self.sin_m = math.sin(m)
self.threshold = math.cos(math.pi - m)
self.mm = math.sin(math.pi - m) * m
self.kernel = Parameter(torch.Tensor(in_features, out_features))
self.register_buffer('t', torch.zeros(1))
nn.init.normal_(self.kernel, std=0.01)
def forward(self, embbedings, label):
embbedings = l2_norm(embbedings, axis = 1)
kernel_norm = l2_norm(self.kernel, axis = 0)
cos_theta = torch.mm(embbedings, kernel_norm)
cos_theta = cos_theta.clamp(-1, 1) # for numerical stability
with torch.no_grad():
origin_cos = cos_theta.clone()
target_logit = cos_theta[torch.arange(0, embbedings.size(0)), label].view(-1, 1)
sin_theta = torch.sqrt(1.0 - torch.pow(target_logit, 2))
cos_theta_m = target_logit * self.cos_m - sin_theta * self.sin_m #cos(target+margin)
mask = cos_theta > cos_theta_m
final_target_logit = torch.where(target_logit > self.threshold, cos_theta_m, target_logit - self.mm)
hard_example = cos_theta[mask]
with torch.no_grad():
self.t = target_logit.mean() * 0.01 + (1 - 0.01) * self.t
cos_theta[mask] = hard_example * (self.t + hard_example)
cos_theta.scatter_(1, label.view(-1, 1).long(), final_target_logit)
output = cos_theta * self.s
return outputCircle Loss
詳情參見:
https://zhuanlan.zhihu.com/p/117716663
AM-LFS:AutoML for Loss Function Search
論文創(chuàng)新點
回顧之前的損失函數(shù)
softmax

Margin-based Softmax Loss
和 之間能夠插入一個可微變換函數(shù)t(?)t(?)來調(diào)節(jié)角度,進而得到margin可變的softmax loss:
不同的t(?)t(?)可以得到不同的損失函數(shù),原文中總結(jié)了如下幾種:

Focal Loss
除了在概率上做變化外,F(xiàn)ocal Loss對softmax loss做了如下變化:

Loss函數(shù)分析
Focal Loss
Focal loss的提出主要是為了解決imbalanced的問題。相對于原始的softmax loss,focal loss在求導之后等于原始的softmax loss求導結(jié)果再乘以 ,換言之 用來緩解imbalance的問題。
Margin-based Softmax Loss
為方便說明,我們可以假設(shè)所有的矢量是單位矢量,即 和
我們使用公式(4)中的損失函數(shù)來分別對 (類內(nèi),intra-class)和 (類間,inter-class)求導,得到:

文中進一步將類內(nèi)距離與類間距離的相對重要性定義為 和 的梯度范數(shù)相對于margin-based softmax loss的比率

同理相對于原始的softmax loss(公式1)的重要性比率是:

進一步可以求得:

t(?)的導函數(shù)實際上是具有控制類內(nèi)距離對于類間距離顯著性的作用,這也是用數(shù)學推導的方式證明了間隔的重要性。
搜索空間
由前面的損失函數(shù)分析我們對softmax做如下變換,得到新的損失函數(shù)如下,

其中

M表示間隔數(shù),即

所以t(?)函數(shù)由三個超參數(shù)組成 , 和 組成。
ττ同理由三個超參數(shù)組成: , 和 組成。
因此搜索空間為,

參數(shù)優(yōu)化
雙層(Bilevel)優(yōu)化定義如下:

具體優(yōu)化過程如下圖所示:


推薦閱讀

