# Supervised Contrastive Learning for Facial Kinship Recognition [toc] ## introduction + 這篇paper在RFIW(Recognizing Families in The Wild) 2021 獲得了很好的成績 + 由中國的兩所大學以及Baidu Research團隊所提出 + 發表在FG 2021 --- + 首先介紹RFIW這個challeng所使用的dataset: FIW(Families in The Wild) + ![](https://i.imgur.com/WHx9BOE.png) + 這個dataset是kinship verification這個領域最大也最齊全的dataset + 總共有11種types: + 爸媽跟子女交叉是4種 + 同性的兄弟、同性的姊妹、異性的兄弟姊妹這樣是3種 + 祖父母跟孫子女交叉是4種 + 總共11種 + ![](https://i.imgur.com/ENtByz7.png) --- ### RFIW(Recognizing families in the Wild) + ![](https://i.imgur.com/C9cNH4M.png) + RFIW這個challenge總共有3個tasks + kinship verification: 輸入是一對input pair, output是看他們有沒有血緣關係 + tri-subject verification: 輸入是一個triplet, 看這個child跟這一對parent有沒有血緣關係 + search and retrieval: 輸入是一個probe, 這個probe可能會有一到多張images, 然後拿去跟gallery裡面的images去比較, 去看誰有可能是probe的親戚; output是一個ranked list, 依照model認為跟probe相似度由高到低的gallery images做排列 --- ### kinship verification + 如同剛剛所說, 這個task是在判斷輸入的pair有沒有血緣關係 + 有剛剛提到的11種types + 參賽組別在最後判斷有沒有血緣關係, 應該會要跟一個threshold去做比較, 那這個threshold是在validation set上看怎麼樣的threshold能夠maximize accuracy, 就拿這個threshold來用在test set上 + ![](https://i.imgur.com/BMMBwe2.png) + accuracy的話就是true positive加上true negative再除上總共有幾對pair; j代表11個types + ![](https://i.imgur.com/TFV6IVZ.png) + 這邊是一些sample pairs, 有剛剛提到的11種types跟每有血緣關係的type + easy samples跟hard samples是用cosine similarity來做區分 + easy代表cosine similarity很高 + hard代表cosine similarity很靠近threshold, 就是有點介在有跟沒有血緣關係的邊緣, 但是是positive pair, 所以hard samples就比較難判斷 + ![](https://i.imgur.com/fTShTYO.png) + 這張圖是用參賽隊伍的正確率來區分easy, hard samples + 100%代表所有隊伍都答對; 20%代表大部分隊伍都答錯 --- ### tri-subject verification + 這個task要判斷child是否屬於這對parent + negative triplet產生的方法是把positive triplet的child換成其他的child + threshold跟task I一樣要在validation set去找最好的threshold, 再用在test set上面 + 主辦單位有提供一個score的算法, 就是分別去算father child還有mother child的cosine similarity, 再相加平均得到一個score, 最後再跟threshold去比較看是否有血緣關係 + ![](https://i.imgur.com/X85Ga7A.png) + 這邊一樣是一些sample triplets, easy跟hard一樣是用cosine similarity做區分 + ![](https://i.imgur.com/vkquT2t.png) + 這邊這張圖則是用參賽隊伍的正確率做區分 + 可以看到100%的negative, 他們是不同種族, 所以很容易分辨沒有血緣關係 + 但< 20%的negative, 一列都是亞洲人, 一列都是歐美人, 就算給一段時間也沒辦法分辨他們是否有血緣關係 --- ### search and retrieval + 這個task就是在gallery(search pool)裡面用probes(search subjects)來找有沒有可能是他們血緣關係的人 + input: probe的一到多張照片, 每個probe在dataset中所擁有的照片數量不同; output: 一個ranked list, 根據model認為跟probe相似度由高到低的gallery images做排序 + 一個probe在gallery中所擁有的親戚數量從1到20個以上不等 + 這個task的評分方式有: + ![](https://i.imgur.com/9QgS67F.png) + rank@5: the average number of probes returned at least one TP in the top five gallery faces + ![](https://i.imgur.com/IUkE7HG.png) + 這邊一樣是search and retrieval的例子 + 最左邊是probe; 右邊是output的ranked list, 這邊只列出相似度前十高的照片 + 綠色是預測正確, 紅色就是預測錯誤 + P是parent, S是siblings, C是child ## related work + related work要介紹三個在RFIW 2020都獲得很好成績的方法 --- + ![](https://i.imgur.com/sR4OWJ4.png) + 第一組在第1, 2, 3個task獲得2, 3, 4名的成績 + ![](https://i.imgur.com/fB2hXOQ.png) + 上圖是他們的network架構, 他們使用兩個不同的pretrained encoders + 把一對input pair分別丟到兩個encoders之後會得到四個features, 接著會對這4個features做concatenation, 最後經過兩層fully connected layers得到output + 這篇作者說output是一個機率, 但沒有說output怎麼來的 + 這篇paper對於細節的描述比較少一點, 像是VggFace的backbone他們有嘗試ResNet50跟SENet50, 還有試過幾種不同的concantenation方法, 以及loss function嘗試BCE(binary cross entropy) loss跟focal loss, 但他沒有說是用哪些組合得到最後的結果 + task II的方式他們是把father child跟mother child分別丟入model得到兩個機率, 再相加平均得到最後的score + avg(FC, MC) + 第三個task則是用一個probe的所有images跟gallery的所有images做比較, 得到下圖的table後再把每個column都相加取平均當作最後的final score, 然後再把相似度由高排到低 + ![](https://i.imgur.com/SSx9QTw.png) --- + ![](https://i.imgur.com/CmXi4Gf.png) + 第二組在第1, 3個task都獲得第一名的成績 + 他們最主要的改變是把主辦單位所提供的baseline model: SphereFace改成ArcFace, loss function則是使用softmax loss function + ![](https://i.imgur.com/2ERh5Tc.png) + ![](https://i.imgur.com/qJmPb0e.png) + SphereFace跟ArcFace最著名的是它們對於loss function的改進, 但我有問過這篇的作者, 他只有使用ArcFace的model架構, loss function是使用剛剛提到的softmax loss function + 這邊我想強調的是: 光是model上的改進就能很有效地提升正確率 + 我去看主辦單位github上使用的SphereFace是36層的CNN + 這篇的github所使用的ArcFace是用ResNet100當作backbone, 並在最後一層convolutional layer後加上BN-Dropout-FC-BN + BN: batch normalization + FC: fully connected layer + 這篇對於第三個task的做法跟剛剛一樣, 把一個probe的所有images跟gallery的所有images做比較 + 假設probe P有m張images: $p_1, ..., p_m$; 要跟gallery image u做比較 + ![](https://i.imgur.com/p9LqdNf.png) + 會做m次的d(cosine distance) + g(‧)這個aggregation function是用max, 取當中最大的值 + 所以每個gallery image都會做一樣的事, 最後一樣把相似度由高排到低做output --- + ![](https://i.imgur.com/acVJuJz.png) + 第三組在第一個task獲得第三名, 在第一個task獲得第一名 + ![](https://i.imgur.com/Dc3Psaj.png) + 他們最大的特色就是使用了siamese network, 也就是兩個branches是做weight sharing + 經過network的feature extraction後還會把feature做fusion, 最後通過sigmoid得到一個分數來跟threshold相比, 看有無血緣關係 + ![](https://i.imgur.com/hzEisBh.png) + 他們還使用了jury system, 也就是有一個主要的model, 還有三個輔助的model + ![](https://i.imgur.com/lOHgqAG.png) + 整個流程也很直觀, 如果主要的model output小於$t_{low}$, 那就很肯定input pair沒有血緣關係 + 如果主要的model output大於$t_{high}$, 那也很肯定這對input有血緣關係 + 如果是介於0.1~0.5, 那就會啟動三個輔助的model, 用四個model來判斷有沒有超過$t_{median}$, 來決定是否有血緣關係 + ![](https://i.imgur.com/kxOSaNP.png) + 作者有對task I做ablation study, 針對backbone, loss function, feature fusion的方式 + 可以看到用ResNet50, BCE loss, 跟這樣的feature fusion方式可以得到最好的accuracy + ![](https://i.imgur.com/RTYxUQL.png) + task II基本上就是task I的延伸, 多了第三個branch, 但backbone就沒有做weight sharing, 一樣extract feature後做feature fusion, 通過兩個sigmoid得到兩個數值, 再做weighted sum得到最後的分數 + 作者有對$\lambda_1$跟$\lambda_2$做實驗, 最後發現是都設成0.5的accuracy最好 + ![](https://i.imgur.com/ZcFT4xj.png) + 作者也有對task II做ablation study + 可以看到基本上跟task I的結果一樣, 一樣是用ResNet50, BCE loss, 甚至連feature fusion的方式都一樣, 可以獲得最好的acuuracy + ![](https://i.imgur.com/P2K4qFG.png) + 剛剛task I的$t_{low}, t_{median}, t_{high}$都已經是寫死的, 但task II的threshold就要去試出來, 最後t = 0.4的情況下accuracy最高 + ![](https://i.imgur.com/LZ3dQK3.png) + 在related work這邊總結一下 + 第一組用了兩個不同的pretrained encoder, 還有feature fusion的方式 + 第二組直接把baseline model換成ArcFace來extract features + 第三組使用siamese network用weight sharing的方式, 也有使用feature fusion的方法 ## method ### task I + ![](https://i.imgur.com/ZXXeAaJ.png) + 這篇paper所使用的方法看起來跟剛剛第三組其實很像, 一樣用weight sharing的siamese network來extract features, 但後面多用了MLP來把feature project到contrastive loss要計算的space上 + MLP作者沒有說架構是什麼, 但應該是一層hidden layer加上ReLU + ![](https://i.imgur.com/ztMoLlJ.png) + contrastive loss其實很直觀, 假設我們有n對positive pairs, 那loss的計算方法就像圖中所示, 要特別注意的是, 萬了$(x_i, y_i)$之後, 還要再算$(y_i, x_i)$, 那這個原因等一下會說明 + 那$L_c(x_i, y_i)$的計算方法基本上就跟softmax loss function很像, 只是這邊的$s(x_i, y_i)$是算cosine similarity; 而$\tau$則是用來對hard samples做punishment, $\tau$越小對於hard samples的punishment就越大 + ![](https://i.imgur.com/0wmE9Kt.png) + 這邊對於$\tau$做一個例子的說明: 假設有2對positive pair, 帶入剛剛的公式就能得到圖中的算式 + 在分子是一對positive pair, 分母的前三項都是negative pairs, 最後一項是positive pair + 前面兩個negative pairs的cosine similarity是-0.8跟-0.9, 預測得還滿準確的; 但第三項的cosine similarity等於0.9, 代表這兩個人其實是不同家族, 但在feature space上卻很靠近, 所以是hard sample + 那可以看到算出來的loss是-log0.4 + 右邊我們把$\tau$換成0.1, 其他數值都一樣, 框起來的一樣是hard sample, 可以看到loss變成-log0.27 + ![](https://i.imgur.com/aLGfZgo.png) + 在-log的曲線圖中, x的值越靠近0, loss就會飆升 + 所以可以說明$\tau$越小對於hard samples的punishment就會越大 + ![](https://i.imgur.com/oAdettR.png) + 那接下來回到剛剛所說, 為什麼$(x_i, y_i)$之後, 還要再算$(y_i, x_i)$ + 假設我們有3對positive pairs, 假設我們要算$(x_1, y_1)$, 按照公式就還要再算$(y_1, x_1)$, 就會得到圖中右邊的式子 + 可以看到兩個分子都是positive pairs, 分母的部份右上角的$(x_1, y_1)$跟$(y_1, x_1)$是positive pairs, 其他都是negative pairs + 那假設我們跟softmax loss function一樣, 只看$(x_i, y_i)$這一項, 也就是兩坨-log我們先只看左邊那坨, 這樣分母我們只看到5個negative pairs + 但如果把$(y_i, x_i)$也包含進來, 我們就能看過10個negative pairs, 而且都沒有重複 + 其他contrastive loss像是triplet loss, 就只有一個anchor, 一個positive, 一個negative, 就只能形成一個positive pair跟一個negative pair + 但這個例子中, contrastive loss就能充分運用6張images的排列組合, 讓loss看過很多不一樣的negative pairs來幫助加強訓練 + ![](https://i.imgur.com/c5Y70Js.png) + prediction的部分, 是用中間這層extract出來的feature來計算similarity, 而不是拿剛剛最後一層MLP extract出來的feature + ![](https://i.imgur.com/HCNmNir.png) + 我看到這篇paper有說明原因, 這篇paper的citation次數高達將近4000次, 是在研究contrastive learning of visual representation + 他們做了研究並說明, 中間層所extract出來的feature, representation會比較好 + 而MLP只是用來把中間層的feature project到contrastive loss要運算的space上 + 結論是中間層extract出來的feature對於正確率的提升有更大的幫助 --- ### task II + ![](https://i.imgur.com/xDsF72y.png) + task II基本上一樣就是做task I的延伸, 一樣多了一個branch, 但這邊三個branch都有做weight sharing, 一樣再用MLP來project到contrastive loss的space上 + ![](https://i.imgur.com/C9WmZ9H.png) + prediction階段一樣是用中間層的feature來計算similarity, 再把兩個similarity做weighted sum, 得到最後的score --- ### task III + task III作者提到有兩種可行的做法 1. 把一個probe的所有images的feature先做fusion, 再拿去跟gallery的所有images做比較, 這樣就是一個one-to-many的問題 2. 跟前面幾組一樣, 把probe的所有images跟gallery的所有images做比較, 是many-to-many的問題 + 作者最後是採用第二種方式 + 所使用的model就是task I所使用的model ## experiment ### settings + ![](https://i.imgur.com/KHALYXH.png) + experiment的設置如上圖 + 要特別注意的是, 作者所使用的feature extraction network跟related work第二組一樣, 是使用ArcFace來extract feature --- ### influence of $\tau$ + ![](https://i.imgur.com/BOQHci8.png) + 第一個experiment是做在taskI上面, 調整$\tau$的大小來看accuracy的變化 + 可以看到比較小的$\tau$, accuracy確實比較好 + ![](https://i.imgur.com/j4Tp0fI.png) + 在task II一樣也是, 越小的$\tau$, accuracy比較好 + 但大家可以發現在task I或task II中, 都不是最小的$\tau$的accuracy最好, 對於這個作者有做解釋 + ![](https://i.imgur.com/K6oAMGe.png) + 先說明很大的$\tau$, 對照上面的公式, 如果$\tau$趨近無限大的話, 分子跟分母的項幾乎都會是一樣的, 那就無法區別easy samples跟hard samples, 這個model對於hard samples的辨識能力就很差 + 那如果$\tau$很小的話, 作者是說會讓sample在feature space中很分散, 反而讓同個家族的feature沒辦法被extract出來 + 上圖是作者把5個家族在feature space上的分布用t-SNE畫出來的結果 --- ### comparison with previous work #### task I + ![](https://i.imgur.com/pcagdzu.png) + 這邊是這個方法跟之前一些成績比較好的方法做比較 + 可以看到這個方法的accuracy是最高的 + 但可以注意到在祖父母的那幾項成績不是很好 + 我自己認為是因為祖父母的data數量在整個dataset中是很少的, 那剛剛提到contrastive loss的優勢就是可以看過很多negative pairs, 但如果data數量少的話可能contrastive loss就沒辦法有很好的發揮 #### task II + ![](https://i.imgur.com/ETDBnoB.png) + 在task II的accuracy一樣是最好的 #### task III + ![](https://i.imgur.com/B9A1yRQ.png) + 在task III一樣也是 + 這個方法在RFIW 2022的三個task中都拿到第一名的成績 + 就算跟前幾年的隊伍比較, 正確率一樣都是最好的 --- ### mispredictions #### task I + ![](https://i.imgur.com/bdyQ7w8.png) + 這邊作者列出一些predict錯誤的pairs + 可以看到這邊的例子跟introduction那邊提到的例子不一樣, introduction那邊的例子人眼就能很輕易分辨, 但這邊的例子就幾乎沒辦法用人眼分辨 + 所以model的水平已經蠻高了 #### task II + ![](https://i.imgur.com/RtbQq4h.png) + 那這邊一樣是task II預測錯誤的triplet ## conclusion + 這個方法結合了related work方法的優點 + siamese network的weight sharing + 用ArcFace來feature extraction + 最重要的是使用了contrastive learning, 有效地提升了正確率, 也在各個task都拿到第一名的成績 + 最後我自己的想法 + 有沒有可能把contrastive loss加上focal loss的想法 + 因為focal loss主要是要把easy samples的注意力變小, 讓注意力集中在hard samples + 那contrastive loss已經有對hard samples做punishment + 如果對於easy samples, $\tau$的值就大一點, 讓loss的注意力再更集中在hard samples上 + 再來就是data augmentation, 讓positive pairs的數量增加; 因為目前訓練中一個batch positive pair只會有一個