深度學習之用CelebA_Spoof數據集搭建一個活體檢測-一些模型訓練中的改動帶來的改善

實驗背景

在前面的深度學習之用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_lossreturn total_lossdef train_epoch(self, train_loader, epoch):try:"""完整訓練邏輯"""self.student.train()self.current_epoch = epochtotal_loss = 0.0correct = 0total = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(self.device), target.to(self.device)if self.gpu == 0 and batch_idx % 200 == 0:current_lr = self.optimizer.param_groups[0]['lr']print(f'當前學習率: {current_lr:.6f}')  # 添加這行打印學習率self.optimizer.zero_grad()# 前向傳播student_out = self.student(data)with torch.no_grad():teacher_out = self.teacher(data)        # 計算損失loss = self._compute_loss(student_out, teacher_out, target)# 反向傳播loss.backward()self.optimizer.step()# 統計指標total_loss += loss.item()_, predicted = student_out.max(1)total += target.size(0)correct += predicted.eq(target).sum().item()# 主進程打印日志if self.gpu == 0 and batch_idx % 200 == 0:avg_loss = total_loss / (batch_idx + 1)acc = 100. * correct / totalprint(f'Epoch {epoch} Batch {batch_idx}/{len(train_loader)} 'f'Loss: {avg_loss:.4f} | Acc: {acc:.2f}%')self.scheduler.step()return {'loss':total_loss / len(train_loader),'accuracy': 100.0 * correct / total}except Exception as e:if "NCCL" in str(e):print(f"NCCL錯誤發生,嘗試恢復訓練...")torch.distributed.destroy_process_group()torch.distributed.init_process_group(backend='nccl')return {'loss': 0, 'accuracy': 0}else:print(f"訓練過程中發生錯誤: {str(e)}")raise e

改進模型(加入傅里葉變換)

加入的傅里葉變換該怎么加呢,我們只在訓練過程中加入,那么得到的特征中具有較好區分性就行,所以不需要將輸入圖像數據都進行傅里葉變換,這樣也防止在后續的推理過程中都需要進行傅里葉變換,增加無畏的動作和減少更多的特征內卷。
訓練過程中,正常的輸入圖像數據,正常的教師學生模型的特征求取,但是同時采用傅里葉變換對圖像數據進行預處理,用于后續的損失函數加入。
訓練參數為:

lr=0.001, step_size=10, gamma=0.9, alpha=0.5, T=3.0, epochs=300, log_interval=5, batch_size=128, save_interval=10, eval_interval=5
    def _fourier_transform(self, x):x = torch.fft.fftshift(torch.fft.fft2(x, dim=(-2, -1)))  # 中心化頻譜x = torch.abs(x)# 動態調整濾波區域h, w = x.shape[-2:]crow, ccol = h//2, w//2mask = torch.ones_like(x)mask[..., crow-10:crow+10, ccol-10:ccol+10] = 0.3  # 部分保留中心低頻return torch.log(1 + 10*x*mask)  # 增強高頻特征
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#if self.gpu == 0:  # 僅主進程打印#    print(f"原始損失 - KL: {kl_loss.item():.4f} | CE: {ce_loss.item():.4f}")# 添加頻域分支損失if self.use_freq:base_weight = self.freq_weight  # 基礎權重dynamic_weight = min(0.25, 0.15 + self.current_epoch*0.001)freq_loss = self.criterion(self.freq_pred, targets) * base_weight * dynamic_weighttotal_loss += freq_loss#if self.gpu == 0:#    print(f"頻域分支損失: {freq_loss.item():.4f} (權重: {self.freq_weight})")return total_lossdef train_epoch(self, train_loader, epoch):try:"""完整訓練邏輯"""self.student.train()self.current_epoch = epochtotal_loss = 0.0correct = 0total = 0for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(self.device), target.to(self.device)if self.gpu == 0 and batch_idx % 200 == 0:current_lr = self.optimizer.param_groups[0]['lr']print(f'當前學習率: {current_lr:.6f}')  # 添加這行打印學習率self.optimizer.zero_grad()# 前向傳播student_out = self.student(data)with torch.no_grad():teacher_out = self.teacher(data)if self.use_freq:# 頻域處理with torch.no_grad():freq_data = self._fourier_transform(data)self.freq_pred = self.freq_branch(freq_data).squeeze()          # 計算損失loss = self._compute_loss(student_out, teacher_out, target)# 反向傳播loss.backward()self.optimizer.step()# 統計指標total_loss += loss.item()_, predicted = student_out.max(1)total += target.size(0)correct += predicted.eq(target).sum().item()# 主進程打印日志if self.gpu == 0 and batch_idx % 200 == 0:avg_loss = total_loss / (batch_idx + 1)acc = 100. * correct / totalprint(f'Epoch {epoch} Batch {batch_idx}/{len(train_loader)} 'f'Loss: {avg_loss:.4f} | Acc: {acc:.2f}%')self.scheduler.step()return {'loss':total_loss / len(train_loader),'accuracy': 100.0 * correct / total}except Exception as e:if "NCCL" in str(e):print(f"NCCL錯誤發生,嘗試恢復訓練...")torch.distributed.destroy_process_group()torch.distributed.init_process_group(backend='nccl')return {'loss': 0, 'accuracy': 0}else:print(f"訓練過程中發生錯誤: {str(e)}")raise e

性能指標對比

指標基線模型傅里葉增強模型提升幅度
Accuracy88.41%93.40%+4.99%
Precision98.66%98.52%-0.14%
Recall84.68%91.86%+7.18%
F1 Score91.14%95.08%+3.94%
ROC AUC96.61%97.83%+1.22%
EER7.67%5.84%-1.83%

關鍵發現

  1. 召回率顯著提升:傅里葉變換幫助模型更好地捕捉偽造痕跡,使召回率提高了7.18%

  2. 等錯誤率降低:EER從7.67%降至5.84%,表明系統整體性能更均衡

  3. 特征互補性:雖然單獨看頻域特征效果有限,但與空間特征結合產生了協同效應

實現建議

在本次實驗,我是保留了中心低頻,增強了高頻特征,當然也可以不這么干,畢竟有些低頻的信息也有用,需要多次驗證采取最好的。代碼中添加的過濾如下:

        # 動態調整濾波區域h, w = x.shape[-2:]crow, ccol = h//2, w//2mask = torch.ones_like(x)mask[..., crow-10:crow+10, ccol-10:ccol+10] = 0.3  # 部分保留中心低頻return torch.log(1 + 10*x*mask)  # 增強高頻特征

結論

傅里葉變換的引入使模型在保持高精確度的同時,顯著提升了召回能力。這只是在調整模型過程中的一點小改善,當然還有其他更好的方法,SqueezeNe的模型結構還是淺,如果沒有更多的限制,可以加深加大,這樣效果會更好。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906106.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906106.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906106.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025年PMP 學習二十 第13章 項目相關方管理

第13章 項目相關方管理 序號過程過程組過程組1識別相關方啟動2規劃相關方管理規劃3管理相關方參與與執行4監控相關方參與與監控 相關方管理,針對于團隊之外的相關方的,核心目標是讓對方為了支持項目,以達到項目目標。 文章目錄 第13章 項目相…

GO語言語法---For循環、break、continue

文章目錄 1. 基本for循環(類似其他語言的while)2. 經典for循環(初始化;條件;后續操作)3. 無限循環4. 使用break和continue5 . 帶標簽的循環(可用于break/continue指定循環)1、break帶標簽2、continue帶標簽…

CSS- 4.4 固定定位(fixed) 咖啡售賣官網實例

本系列可作為前端學習系列的筆記,代碼的運行環境是在HBuilder中,小編會將代碼復制下來,大家復制下來就可以練習了,方便大家學習。 HTML系列文章 已經收錄在前端專欄,有需要的寶寶們可以點擊前端專欄查看! 點…

分布式微服務系統架構第132集:Python大模型,fastapi項目-Jeskson文檔-微服務分布式系統架構

加群聯系作者vx:xiaoda0423 倉庫地址:https://webvueblog.github.io/JavaPlusDoc/ https://1024bat.cn/ https://github.com/webVueBlog/fastapi_plus 這個錯誤是由于 Python 3 中已經將線程的 isAlive() 方法更名為 is_alive(),但你的調試工…

react路由中Suspense的介紹

好的,我們來詳細解釋一下這個 AppRouter 組件的代碼。 這個組件是一個在現代 React 應用中非常常見的模式,特別是在使用 React Router v6 進行路由管理和結合代碼分割(Code Splitting)來優化性能時。 JavaScript const AppRout…

C語言內存函數與數據在內存中的存儲

一、c語言內存函數 1、memcpy函數是一個標準庫函數,用于內存復制。功能上是用來將一塊內存中的內容復制到另一塊內存中。用戶需要提供目標地址、源地址以及要復制的字節數。例如結構體之間的復制。 memcpy函數的原型是:void* memcpy(void* …

層次原理圖

層次原理圖簡介 層次原理圖(Hierarchical Schematic)是一種常用于電子工程與系統設計的可視化工具,通過分層結構將復雜系統分解為多個可管理的子模塊。它如同“設計藍圖”,以樹狀結構呈現整體與局部的關系:頂層展現系…

流程編輯器Bpmn與LogicFlow學習

工作流技術如何與用戶交互結合(如動態表單、任務分配)處理過 XML 與 JSON 的轉換自定義過 bpmn.js 的樣式(如修改節點顏色、形狀、圖標)擴展過上下文菜單(Palette)或屬性面板(Properties Panel&…

LWIP的NETCONN接口

NETCONN接口簡介 NETCONN API 使用了操作系統的 IPC 機制, 對網絡連接進行了抽象,使用同一的接口完成UDP和TCP連接 NETCONN API接口是在RAW接口基礎上延申出來的一套API接口 NETCONN實現原理 2.1,NETCONN控制塊 2.2,NETCONN收…

Linux搜索

假如我們要搜索 struct sockaddr_in 我們在命令終端輸入 cd/usr/include/ //進入頭文件目錄地址 /usr/include/ grep " struct sockaddr_in { " *-nir (*是在當前目錄,n 是找出來顯示行數…

2025長三角杯數學建模B題思路模型代碼:空氣源熱泵供暖的溫度預測,賽題分析與思路

2025長三角杯數學建模B題思路模型代碼,詳細內容見文末名片 空氣源熱泵是一種與中央空調類似的設備,其結構主要由壓縮主機、熱交換 器以及末端構成,依靠水泵對末端房屋提供熱量來實現制熱。空氣源熱泵作為熱 慣性負載,調節潛力巨…

ssh免密碼登錄

創建秘鑰和公鑰 ssh-keygen -t rsa 輸入上述命令后,直接按回車即可,完成后會在上面信息顯示,生成的文件路徑信息 id_rsa:秘鑰 id_rsa.pub: 公鑰 將公鑰的內容copy到遠端 將id_rsa.pub的內容拷貝到~/.ssh下的authori…

基于Bootstrap 的網頁html css 登錄頁制作成品

目錄 前言 一、網頁制作概述 二、登錄頁面 2.1 HTML內容 2.2 CSS樣式 三、技術說明書 四、頁面效果圖 前言 ?Bootstrap?是一個用于快速開發Web應用程序和網站的前端框架,由Twitter的設計師Mark Otto和Jacob Thornton合作開發。 它基于HTML、CSS和JavaScri…

20倍云臺球機是一種高性能的監控設備

20倍云臺球機是一種高性能的監控設備,其主要特點包括20倍光學變焦能力和云臺旋轉功能。以下是對20倍云臺球機的詳細分析: 一、主要特點 20倍光學變焦 : 攝像機鏡頭能夠在保持圖像清晰度的前提下,將監控目標放大20倍。 這一功能…

大型語言模型應用十大安全風險

40多頁LLM應用的十大風險 這是一份關于LLM應用的十大風險(2025版),有一定的參考價值。 如果你時間充裕,可以聽聽播客,詳細了解: 如果你只想快速了解10條分別是什么,可以直接看重點摘錄&#xff…

一文掌握工業相機選型計算

目錄 一、基本概念 1.1 物方和像方 1.2 工作距離和視場 1.3 放大倍率 1.4 相機芯片尺寸 二、公式計算 三、實例應用 一、基本概念 1.1 物方和像方 在光學領域,物方(Object Space)是與像方(Image Space)相對的…

《虛擬即真實:數字人驅動技術在React Native社交中的涅槃》

當React Native與數字人驅動技術相遇,它們將如何攜手塑造社交應用中智能客服與虛擬主播的自然交互呢?這正是本文要深入探討的話題。 React Native是Facebook開源的一個用于構建原生移動應用的框架,它允許開發者使用JavaScript和React編寫代碼…

使用AI 生成PPT 最佳實踐方案對比

文章大綱 一、專業AI生成工具(推薦新手)**1. 推薦工具詳解****2. 操作流程優化****3. 優勢與局限**二、代碼生成方案(開發者推薦)**1. Python-pptx進階用法****2. GitHub推薦**三、混合工作流(平衡效率與定制)**1. 工具鏈升級****2. 示例Markdown結構**四、網頁轉換方案(…

前端-HTML元素

目錄 HTML標簽是什么? 什么是HTML元素? HTML元素有哪些分類方法? 什么是HTML頭部元素 更換路徑 注:本文以leetbook為基礎 HTML標簽是什么? HTML標簽是HTML語言中最基本單位和重要組成部分 雖然它不區分大小寫&a…

菱形繼承原理

在C中,菱形繼承的內存模型會因是否使用虛繼承產生本質差異。我們通過具體示例說明兩種場景的區別: 一、普通菱形繼承的內存模型 class A { int a; }; class B : public A { int b; }; class C : public A { int c; }; class D : public B, public C { i…