習(xí)人臉識別畢設(shè)全流程:從數(shù)據(jù)集到系統(tǒng)落地)
人臉識別這四個(gè)字放在畢設(shè)選題里屬于那種“看起來門檻不高、真做起來處處是坑”的典型。每年到這個(gè)季節(jié)總有一批同學(xué)拿著“深度學(xué)習(xí)機(jī)器視覺人臉識別系統(tǒng)”這個(gè)題目來找我聊問題高度集中數(shù)據(jù)集怎么搞、模型選哪個(gè)、為什么自己訓(xùn)出來的模型在攝像頭前跟抽風(fēng)一樣、答辯時(shí)老師問“你這個(gè)和現(xiàn)成開源項(xiàng)目有什么區(qū)別”該怎么接。這篇就把這套系統(tǒng)從零到能跑、從能跑到能講清楚完整拆一遍。我先把話說在前面這篇不是讓你去復(fù)制一個(gè)現(xiàn)成倉庫改個(gè)界面交差而是幫你建立一套“我知道每一層在干什么”的認(rèn)知。人臉識別系統(tǒng)本質(zhì)上是一條流水線——檢測、對齊、特征提取、比對每一環(huán)都有它的脾氣。你只有把每一環(huán)的輸入輸出、失敗模式、調(diào)參邏輯摸清楚答辯的時(shí)候才不會被問穿系統(tǒng)也才真的穩(wěn)。適合正在做相關(guān)畢設(shè)的本科生、剛轉(zhuǎn)機(jī)器視覺方向的初學(xué)者以及想把這套東西落到實(shí)際小項(xiàng)目里的開發(fā)者。1. 先想清楚“識別”到底指哪件事很多人一上來就說“我要做人臉識別”但這個(gè)詞在工程語境里其實(shí)覆蓋了三件完全不同的事混在一起做項(xiàng)目必然擰巴。我見過太多同學(xué)把這三件事塞進(jìn)一個(gè)腳本里最后連自己都說不清系統(tǒng)到底在干嘛。1.1 檢測、識別、驗(yàn)證是三碼事人臉檢測回答的是“畫面里有沒有臉、在哪”。輸出是一堆矩形框加置信度它不關(guān)心這張臉是誰。人臉識別更準(zhǔn)確叫身份識別回答的是“這張臉對應(yīng)庫里哪個(gè)人”本質(zhì)是一個(gè)多分類或檢索問題。人臉驗(yàn)證回答的是“這兩張臉是不是同一個(gè)人”是一個(gè)二分類的相似度判斷問題。這三者的技術(shù)棧有重疊但側(cè)重點(diǎn)完全不同。檢測用的大多是單階段或兩階段的目標(biāo)檢測網(wǎng)絡(luò)識別和驗(yàn)證則依賴特征提取網(wǎng)絡(luò)加度量學(xué)習(xí)。你的畢設(shè)如果寫“人臉識別系統(tǒng)”通常要的是“檢測 識別”的組合先框出人臉再判斷是誰。而門禁、考勤這類場景往往用的是“檢測 驗(yàn)證”因?yàn)樗悄卯?dāng)前臉和登記照做一對一比對。提示開題報(bào)告里一定要把“識別”和“驗(yàn)證”寫清楚否則答辯時(shí)老師一句“你這是分類還是比對”就能把你問住。我建議默認(rèn)做“檢測 識別小規(guī)模閉集分類”工作量可控演示效果也直觀。1.2 閉集識別和開集識別決定了你的系統(tǒng)上限閉集識別假設(shè)測試時(shí)的每一張臉都在訓(xùn)練庫里出現(xiàn)過模型只需要在已知的 N 個(gè)人里挑一個(gè)。開集識別則要處理“陌生人”系統(tǒng)得有能力說“這個(gè)人我不認(rèn)識”。這兩者的難度差了一個(gè)量級。畢設(shè)階段我強(qiáng)烈建議先做閉集把 N 控制在 10 到 50 人之間這樣準(zhǔn)確率好看、演示穩(wěn)定。如果你非要碰開集那就必須引入閾值機(jī)制特征距離小于閾值判為已知身份大于閾值判為未知。這個(gè)閾值怎么定后面第 4 節(jié)會細(xì)講它是開集系統(tǒng)能不能用的命門。1.3 你的系統(tǒng)邊界該畫在哪一個(gè)能答辯、能演示、邏輯自洽的系統(tǒng)邊界建議這樣畫輸入是攝像頭實(shí)時(shí)畫面或本地圖片系統(tǒng)完成人臉檢測、人臉對齊、特征提取、與本地人臉庫比對、輸出身份標(biāo)簽和置信度附帶一個(gè)簡單的登記入口錄入新人員。超出這個(gè)范圍的東西比如活體檢測、口罩遮擋識別、跨年齡識別可以作為“未來工作”提一句但別真做做不完也做不深。把邊界畫清楚的好處是你的每一行代碼都能對應(yīng)到系統(tǒng)框圖上的一個(gè)模塊答辯時(shí)指著圖講邏輯鏈完整老師也很難挑刺。2. 數(shù)據(jù)集這道坎沒有數(shù)據(jù)模型就是空殼做視覺項(xiàng)目數(shù)據(jù)決定了天花板。我見過太多人卡在這一步要么找不到數(shù)據(jù)要么拿到的數(shù)據(jù)臟得沒法用。這一節(jié)把數(shù)據(jù)來源、清洗、劃分講透。2.1 公開數(shù)據(jù)集怎么選、怎么用常見的人臉數(shù)據(jù)集有幾個(gè)方向。一類是身份標(biāo)注數(shù)據(jù)集每張圖帶人名標(biāo)簽適合做閉集分類訓(xùn)練規(guī)模從幾千張到幾十萬張不等。另一類是人臉驗(yàn)證數(shù)據(jù)集成對給出“同人/不同人”的標(biāo)簽適合訓(xùn)練度量學(xué)習(xí)模型。還有一類是檢測數(shù)據(jù)集只標(biāo)注人臉框用來訓(xùn)檢測器。對畢設(shè)來說我的建議是檢測環(huán)節(jié)直接用成熟的開源檢測器后面會講不自己訓(xùn)識別環(huán)節(jié)用一個(gè)小規(guī)模身份數(shù)據(jù)集或者自己采集。自己采集其實(shí)很現(xiàn)實(shí)——找同學(xué)幫忙每人拍 20 到 30 張涵蓋不同光照、角度、表情10 個(gè)人就是兩三百張夠跑通一個(gè) demo 了。采集的時(shí)候有幾個(gè)細(xì)節(jié)必須注意光照要多樣白天窗邊、晚上室內(nèi)燈、背光角度要有變化正臉為主但要有左右各 15 到 30 度的偏轉(zhuǎn)表情要自然別全是證件照式的僵臉加點(diǎn)微笑、說話狀態(tài)。這些變化直接決定模型泛化能力全是正臉證件照訓(xùn)出來的模型一到攝像頭前就廢。2.2 數(shù)據(jù)清洗比想象中重要十倍拿到數(shù)據(jù)第一件事不是訓(xùn)練是清洗。常見臟數(shù)據(jù)包括重復(fù)圖片同一個(gè)人同一張圖存了多份、錯標(biāo)文件名和人對不上、低質(zhì)量圖嚴(yán)重模糊、過曝、人臉占比過小、非人臉圖混進(jìn)來的風(fēng)景照。清洗流程我一般這么走先用感知哈?;蚝唵蔚奈募笮〖映叽缛ブ卦儆萌四槞z測器過一遍把檢測不到人臉的圖挑出來人工看一眼最后按身份統(tǒng)計(jì)每人的樣本數(shù)樣本數(shù)明顯偏少的比如少于 8 張考慮剔除或補(bǔ)采。這一步花的時(shí)間絕對值回票價(jià)臟數(shù)據(jù)訓(xùn)出來的模型你調(diào)參調(diào)到天亮也救不回來。2.3 訓(xùn)練集、驗(yàn)證集、測試集怎么切才不泄漏劃分?jǐn)?shù)據(jù)集有個(gè)大坑叫數(shù)據(jù)泄漏同一個(gè)人同一個(gè)場景拍的多張圖被隨機(jī)分到了訓(xùn)練集和測試集模型在測試集上準(zhǔn)確率虛高實(shí)際一用就露餡。正確做法是按身份劃分——某些人的圖全進(jìn)訓(xùn)練集另一些人的圖全進(jìn)測試集這樣測試集里的身份模型訓(xùn)練時(shí)從沒見過評估才真實(shí)。如果你的身份數(shù)很少比如就 10 個(gè)人按身份劃分會導(dǎo)致測試集身份太少評估不穩(wěn)定。折中方案是按采集批次劃分同一個(gè)人在不同時(shí)間、不同地點(diǎn)拍的圖分到不同集合模擬真實(shí)使用中“訓(xùn)練時(shí)見過的臉換環(huán)境再認(rèn)”的場景。這個(gè)細(xì)節(jié)寫進(jìn)論文是很加分的工程考量。劃分方式優(yōu)點(diǎn)風(fēng)險(xiǎn)適用場景隨機(jī)按圖劃分實(shí)現(xiàn)簡單嚴(yán)重?cái)?shù)據(jù)泄漏指標(biāo)虛高不推薦按身份劃分評估真實(shí)身份少時(shí)測試集不穩(wěn)定身份數(shù)較多按采集批次劃分兼顧真實(shí)與穩(wěn)定需要采集時(shí)做好記錄自采數(shù)據(jù)首選3. 流水線拆解檢測、對齊、特征提取各干什么活系統(tǒng)跑起來是一條鏈每一環(huán)的輸出是下一環(huán)的輸入。這一節(jié)把每個(gè)模塊的原理和選型邏輯講清楚讓你知道為什么這么搭。3.1 人臉檢測為什么我不建議你從零訓(xùn)檢測器檢測器的任務(wù)是在圖里找臉。主流方案分兩派兩階段檢測先出候選區(qū)域再分類回歸精度高但慢單階段檢測一步到位快但小臉容易漏。對人臉這種目標(biāo)業(yè)界有專門優(yōu)化過的輕量檢測器速度快、對小人臉友好非常適合實(shí)時(shí)系統(tǒng)。畢設(shè)階段從零訓(xùn)檢測器是典型的“投入產(chǎn)出不成正比”。檢測模型的訓(xùn)練需要大量帶框標(biāo)注的數(shù)據(jù)標(biāo)注成本高而且通用檢測器已經(jīng)足夠好。我的建議是直接用成熟的開源檢測方案把精力放在識別環(huán)節(jié)。你需要在論文里說明的是“為什么選這個(gè)檢測器”——比如它的推理速度滿足實(shí)時(shí)要求、對側(cè)臉和小臉召回率好、模型體積適合部署這些理由比“我自己訓(xùn)了一個(gè)”更有說服力。檢測環(huán)節(jié)有個(gè)參數(shù)值得調(diào)置信度閾值和非極大值抑制NMS閾值。置信度閾值調(diào)低漏檢少但誤檢多調(diào)高則相反。NMS 閾值控制重疊框的合并力度人臉密集場景比如合影要適當(dāng)調(diào)高否則相鄰的臉會被誤合并。這兩個(gè)參數(shù)沒有標(biāo)準(zhǔn)答案拿你的實(shí)際場景試出來。3.2 人臉對齊這一步省了識別率直接掉一截檢測出來的框里人臉可能是歪的、斜的、大小不一的。人臉對齊就是根據(jù)關(guān)鍵點(diǎn)眼角、鼻尖、嘴角把臉旋轉(zhuǎn)、縮放、裁剪到一個(gè)標(biāo)準(zhǔn)姿態(tài)通常是 112×112 或 160×160 的固定尺寸。為什么必須做因?yàn)樘卣魈崛【W(wǎng)絡(luò)是在對齊后的標(biāo)準(zhǔn)臉上訓(xùn)練的你喂給它一張歪臉?biāo)崛〉奶卣鞣植季推吮葘ψ匀徊粶?zhǔn)。對齊依賴關(guān)鍵點(diǎn)檢測常見是 5 點(diǎn)雙眼、鼻尖、雙嘴角或 68 點(diǎn)。5 點(diǎn)足夠做仿射變換對齊速度快是實(shí)時(shí)系統(tǒng)的首選。對齊的實(shí)現(xiàn)邏輯是根據(jù) 5 個(gè)關(guān)鍵點(diǎn)算出仿射變換矩陣把眼睛和嘴巴的位置映射到標(biāo)準(zhǔn)模板的固定坐標(biāo)上然后裁剪。這一步用現(xiàn)成的庫幾行代碼就能搞定但一定要做我實(shí)測過加了對齊比不加以外同人比對的特征距離能明顯拉開。3.3 特征提取度量學(xué)習(xí)才是識別的靈魂特征提取網(wǎng)絡(luò)把對齊后的人臉圖映射成一個(gè)高維向量常見 128 維或 512 維這個(gè)向量就是這張臉的“數(shù)字指紋”。核心要求是同一個(gè)人的不同照片向量要靠近不同人的向量要遠(yuǎn)離。這個(gè)“靠近/遠(yuǎn)離”的約束就是度量學(xué)習(xí)要解決的問題。經(jīng)典的損失函數(shù)設(shè)計(jì)思路是類內(nèi)緊湊、類間分離。早期用 softmax 直接分類但 softmax 只保證分對類不保證類內(nèi)距離小、類間距離大導(dǎo)致特征判別力不夠。后來出現(xiàn)了各種改進(jìn)的度量損失核心思想都是給特征空間加約束讓同類特征聚成一團(tuán)不同類之間留出間隔。你不需要自己發(fā)明損失函數(shù)選一個(gè)成熟的主干網(wǎng)絡(luò)加成熟的損失配置就行但論文里要能講清楚“為什么用度量學(xué)習(xí)而不是純分類”。主干網(wǎng)絡(luò)選型上輕量網(wǎng)絡(luò)如 MobileNet 系列思路的骨干適合實(shí)時(shí)和邊緣部署深層網(wǎng)絡(luò)精度高但慢。畢設(shè)演示通常在普通筆記本上跑我建議選輕量骨干保證攝像頭幀率流暢演示體驗(yàn)比多那一兩個(gè)點(diǎn)準(zhǔn)確率重要得多。4. 訓(xùn)練與調(diào)參那些文檔里不會寫的實(shí)戰(zhàn)細(xì)節(jié)模型結(jié)構(gòu)定了接下來是訓(xùn)練。這一節(jié)講的是真正會卡住你的東西——學(xué)習(xí)率、數(shù)據(jù)增強(qiáng)、過擬合、閾值。4.1 學(xué)習(xí)率與優(yōu)化器先穩(wěn)后快訓(xùn)練人臉特征網(wǎng)絡(luò)優(yōu)化器用帶動量的隨機(jī)梯度下降或自適應(yīng)方法都行。學(xué)習(xí)率是第一個(gè)要調(diào)的太大損失震蕩不收斂太小訓(xùn)到天荒地老。我的經(jīng)驗(yàn)是先用一個(gè)中等學(xué)習(xí)率跑幾個(gè) epoch 看損失曲線如果損失下降平滑就保持如果震蕩就減半如果幾乎不動就翻倍。還有個(gè)常用技巧是學(xué)習(xí)率預(yù)熱和衰減前幾個(gè) epoch 用小學(xué)習(xí)率 warmup避免一開始就把權(quán)重帶偏訓(xùn)練后期逐步衰減讓模型在最優(yōu)點(diǎn)附近精細(xì)收斂。這套組合拳在數(shù)據(jù)量不大時(shí)尤其管用能明顯提升最終精度。4.2 數(shù)據(jù)增強(qiáng)小數(shù)據(jù)集的生命線自采數(shù)據(jù)往往只有幾百張不加增強(qiáng)必然過擬合。人臉場景有效的增強(qiáng)包括隨機(jī)水平翻轉(zhuǎn)人臉近似左右對稱翻轉(zhuǎn)是安全的、隨機(jī)亮度對比度擾動模擬不同光照、小角度旋轉(zhuǎn)模擬頭部輕微偏轉(zhuǎn)、隨機(jī)裁剪縮放模擬距離變化。但增強(qiáng)要有度。垂直翻轉(zhuǎn)絕對不能用倒過來的人臉是另一個(gè)分布訓(xùn)進(jìn)去就是噪聲。大角度旋轉(zhuǎn)也要謹(jǐn)慎超過 30 度且沒有對應(yīng)真實(shí)樣本時(shí)增強(qiáng)出來的圖和對齊邏輯會打架。我的做法是增強(qiáng)參數(shù)從保守開始看驗(yàn)證集表現(xiàn)再逐步放開每次只改一個(gè)維度方便定位是哪個(gè)增強(qiáng)起了作用。4.3 過擬合的識別與應(yīng)對過擬合的典型信號訓(xùn)練損失持續(xù)下降驗(yàn)證損失先降后升驗(yàn)證準(zhǔn)確率停滯甚至回落??吹竭@個(gè)曲線說明模型開始背訓(xùn)練集了。應(yīng)對手段按優(yōu)先級排先加數(shù)據(jù)增強(qiáng)再加正則化權(quán)重衰減、dropout再考慮減小模型容量最后才是早停。早停是個(gè)很實(shí)用的策略監(jiān)控驗(yàn)證集指標(biāo)連續(xù)若干個(gè) epoch 不提升就停止訓(xùn)練保留驗(yàn)證集表現(xiàn)最好的那版權(quán)重。這樣既省時(shí)間又避免訓(xùn)過頭。我一般設(shè) patience 為 8 到 10 個(gè) epoch配合學(xué)習(xí)率衰減一起用。4.4 閾值開集系統(tǒng)的生死線如果你做的是驗(yàn)證或開集識別最終判定要靠特征距離閾值。兩張臉的特征向量算余弦相似度或歐氏距離超過閾值判為同一人。這個(gè)閾值怎么定不能拍腦袋要在驗(yàn)證集上掃一遍把閾值從低到高遍歷畫出誤接受率把不同人判成同一人和誤拒絕率把同一人判成不同人隨閾值變化的曲線選一個(gè)兩者平衡的點(diǎn)。實(shí)際系統(tǒng)里安全優(yōu)先的場景比如門禁要把誤接受率壓到很低寧可多拒幾次體驗(yàn)優(yōu)先的場景可以放寬。這個(gè)取舍寫進(jìn)論文體現(xiàn)你懂工程權(quán)衡比單純報(bào)一個(gè)準(zhǔn)確率有深度得多。5. 從腳本到系統(tǒng)工程化落地與演示穩(wěn)定性模型訓(xùn)好了只是半成品能穩(wěn)定演示、能講清楚架構(gòu)才算一個(gè)完整的畢設(shè)系統(tǒng)。這一節(jié)講工程側(cè)的事。5.1 系統(tǒng)架構(gòu)怎么分層我建議按“采集層—算法層—業(yè)務(wù)層—展示層”來分。采集層負(fù)責(zé)讀攝像頭或圖片做預(yù)處理算法層封裝檢測、對齊、特征提取、比對業(yè)務(wù)層管人臉庫的增刪查、識別結(jié)果記錄展示層做界面。這樣分層的好處是每層職責(zé)單一換攝像頭、換模型、換界面都不影響其他層答辯時(shí)講架構(gòu)圖也清晰。人臉庫的存儲小規(guī)模直接用本地文件加索引就行每個(gè)身份存一個(gè)特征向量文件加若干原圖。規(guī)模大了再考慮向量檢索庫但畢設(shè)階段沒必要別為了炫技引入一堆依賴最后環(huán)境都配不起來。5.2 實(shí)時(shí)性優(yōu)化幀率是演示體驗(yàn)的核心攝像頭實(shí)時(shí)識別最容易翻車的是卡頓。優(yōu)化思路檢測不必每幀都跑可以隔幾幀檢測一次中間幀用跟蹤算法跟住人臉框這樣能省大量算力特征提取只對檢測到的人臉做且可以緩存已識別身份的結(jié)果短時(shí)間內(nèi)不重復(fù)計(jì)算輸入分辨率適當(dāng)降低檢測和對齊不需要原圖那么高的分辨率。還有一個(gè)細(xì)節(jié)攝像頭讀取和算法處理放在不同線程用隊(duì)列緩沖幀避免算法慢導(dǎo)致畫面堆積延遲。這個(gè)多線程結(jié)構(gòu)在演示時(shí)特別重要否則你一動畫面延遲半秒觀感很差。5.3 演示腳本與容錯答辯演示最怕現(xiàn)場出意外。提前準(zhǔn)備本地圖片兜底攝像頭萬一不工作用圖片演示全流程、預(yù)錄視頻網(wǎng)絡(luò)或環(huán)境問題時(shí)的備份、人臉庫預(yù)置提前錄入幾個(gè)演示身份別現(xiàn)場錄入手忙腳亂。系統(tǒng)里加基本的異常捕獲攝像頭打不開給提示而不是直接崩這些細(xì)節(jié)體現(xiàn)工程素養(yǎng)。6. 答辯會被問什么把技術(shù)選擇講成故事最后聊聊怎么講。老師問的往往不是“你用了什么”而是“你為什么這么選”。6.1 高頻問題的應(yīng)答邏輯“為什么用這個(gè)檢測器”——答速度、召回率、部署體積的權(quán)衡結(jié)合你的實(shí)時(shí)需求。“為什么不用更大的模型”——答演示環(huán)境算力限制和幀率要求精度和速度的取舍?!皽?zhǔn)確率怎么算的”——答清楚是閉集分類準(zhǔn)確率還是驗(yàn)證準(zhǔn)確率測試集怎么劃分的有沒有數(shù)據(jù)泄漏?!昂烷_源項(xiàng)目有什么區(qū)別”——答你的系統(tǒng)邊界、你的數(shù)據(jù)、你的工程整合和場景適配別硬說算法創(chuàng)新。6.2 把“調(diào)參”講成“實(shí)驗(yàn)設(shè)計(jì)”你調(diào)過的每一個(gè)參數(shù)都是實(shí)驗(yàn)。論文里別只寫“最終學(xué)習(xí)率設(shè)為某值”要寫“對比了若干學(xué)習(xí)率下的收斂曲線選定某值因?yàn)槭諗孔罘€(wěn)”。把調(diào)參過程寫成對照實(shí)驗(yàn)體現(xiàn)方法論這是本科畢設(shè)里很容易做出差異化的地方。6.3 誠實(shí)地講局限性主動說局限反而加分自采數(shù)據(jù)規(guī)模小、身份數(shù)有限、未做活體檢測、跨年齡和遮擋場景表現(xiàn)下降。說清楚局限再給出可行的改進(jìn)方向老師會覺得你對自己的系統(tǒng)有清醒認(rèn)知而不是盲目吹噓。我個(gè)人在做這類系統(tǒng)時(shí)最大的體會是算法決定下限工程決定上限。一個(gè)用成熟模型但流水線搭得干凈、異常處理到位、演示穩(wěn)定的系統(tǒng)評價(jià)往往高于一個(gè)算法花哨但跑起來磕磕絆絆的系統(tǒng)。把檢測、對齊、特征提取這條鏈的每一環(huán)都吃透把數(shù)據(jù)清洗和劃分做扎實(shí)把實(shí)時(shí)性和容錯處理好這個(gè)畢設(shè)就已經(jīng)贏了大半。剩下的就是把它講成一個(gè)邏輯自洽的故事。