論文翻訳: 検索センターの差分畳み込みネットワークと顔検出の実装コード


元の記事とモデルのソースコード: https://github.com/ZitongYu/CDCN

まとめ

Face Liveness Detection (FAS) は、顔認識システムにおいて重要な役割を果たします。最も先進的な FAS テクノロジーのほとんど。1) 積み重ねられた畳み込み層と専門的に設計されたネットワークに依存しますが、これらは詳細な粒度の情報を記述するのが弱く、環境が変化すると (例: 異なる照明条件下で) 失敗する傾向があります。2) 動的特徴を抽出するための出力として長いシーケンスを使用する傾向があるため、高速応答が必要なシナリオでの展開が困難になります。この論文では、強度と勾配の情報を集約することで本質的に詳細なモデルをキャプチャできる、中心差分畳み込み (CDC) に基づくフレームレベルの FAS 手法を提案します。CDC を使用して構築されたネットワークは中心差分畳み込みネットワーク (CDCN) と呼ばれ、通常の畳み込みを使用して構築されたネットワークよりも強力なモデリング機能を提供できます。さらに、特別に設計された CDC 検索空間上で、ニューラル アーキテクチャ検索 (NAS) を使用して、より強力なネットワーク構造 (CDCN++) が発見されます。これをマルチスケール アテンション フュージョン モジュール (MAFM) と組み合わせることで、パフォーマンスをさらに向上させることができます。 。6 つのベンチマーク データセットに対して包括的な実験が行われ、その結果は次のことを示しています: 1) 提案された方法は、内部データセット テストで優れたパフォーマンスを達成するだけでなく (特に OULU-NPU データセットのプロトコル 1 で 0.2.% ACER)、2)クロスデータセット テストで優れた汎化パフォーマンスを示します (特に CASIA-MFSD から Replay- Attack データセットまでの HTER が 6.5%)。コードはhttps://github.com/ZitongYu/CDCNで入手できます。

1 はじめに

顔認識は、その利便性のため、多くの対話型人工知能システムで広く使用されています。ただし、プレゼンテーション攻撃 (PA) に対する脆弱性により、その信頼性の高い展開が制限されます。印刷された写真やビデオを生体認証センサーに提示するだけで、顔認識システムを騙すことができます。攻撃の典型的な例を示しながら、印刷された写真、ビデオ リプレイ、3D マスク。顔認識システムの信頼性を確保するために、このようなディスプレイ攻撃を検出する方法として、Face Liveness Detection (FAS) 手法が重要です。
ここに画像の説明を挿入

注:
VanillaConv は、正則化やその他のトリックを含まない、畳み込み層とプーリング層のみで構成される基本的な畳み込みニューラル ネットワークです。

図 1: 異なるオフセット ドメイン (照明と入力カメラ) での顔のなりすましに対するバニラ コンボリューション (VanillaConv) と中心差分コンボリューション (CDC) の特徴応答。通常の畳み込みでは一貫したスプーフィング パターンをキャプチャできませんが、CDC はラティス アーティファクトなどの不変の詳細なスプーフィング特徴を抽出できます。

近年、[7、8、15、29、45、44] および深層学習 [49、64、36、26、62、4、19、20] に基づくいくつかの方法が、表現攻撃の検出のために提案されています (パッド)。一方では、古典的な手作りの記述子 (例: ローカル バイナリ パターン (LBP) [7]) は、隣接するもの間の局所的な関係を識別特徴として利用します。これは、生きている顔と偽装された顔の間の詳細な不変情報 (例: カラー テクスチャ、モアレ パターン、ノイズ アーティファクトなど)は堅牢です。一方、畳み込みニューラル ネットワーク (CNN) は、非線形活性化を伴うスタック畳み込み演算により、リアルと PA を区別する強力な表現能力を備えています。「しかし、CNN ベースの手法は、より深い意味論的特徴に焦点を当てており、生きている顔となりすましの顔の間の詳細な粒度の細かい情報を記述するのが弱く、環境が変化すると (照明の違いなど) 簡単に無効になってしまいます。堅牢な特徴表現を実現するための畳み込み演算は、価値のある研究課題です。

最近の深層学習ベースの FAS 手法は通常、VGG [54]、ResNet [22]、DenseNet [23] などの画像分類タスク [61、62、20] に基づくバックボーン上に構築されています。ネットワークは通常、バイナリのクロスエントロピー損失によって監視されており、パターンの性質を欺く代わりに、画面の境界線などの重要でない情報を簡単に学習します。この問題に対処するために、擬似深度マップ ラベルを補助監視信号として利用する、いくつかの高度に監視された FAS 手法 [4、36] を開発しました。したがって、補助的な深い監視による FAS タスクに最適なネットワークの自動検出を考慮する必要があります。

「既存の最先端の FAS 手法 [36、56、62、32] のほとんどは、PAD の動的な時空間特徴 (モーション [36、56] や rPPG [62、32] など) を抽出するために入力として複数のフレームを必要とします。ただし、長いビデオ シーケンスは、迅速な意思決定が必要な特定の導入条件には適していない可能性があります。したがって、ビデオ レベルの方法と比べてパフォーマンスは劣りますが、フレーム レベル ベースの PAD 方法は、ユーザビリティの観点からは利点があります。パフォーマンスのフレームレベルの手法は、実際の FAS アプリケーションにとって非常に重要です。」

基于上述讨论,我们提出了一种新的卷积算子,称为中心差分卷积(CDC),它很擅长描述细粒度不变信息。如图1所示,在不同的环境中,CDC比普通的卷积更有可能提取内在的欺骗模式(例如,晶格伪影)。此外,在一个专门设计的CDC搜索空间上,利用神经结构搜索(NAS)来发现优秀的帧级网络,用于深度监督的人脸反欺骗任务。我们的贡献包括:

  1. 我们设计了一种新的卷积算子,称为中心差分卷积(CDC),由于其在不同环境中对不变细粒度特征的显著表示能力,适用于FAS任务。在不引入任何额外参数的情况下,CDC可以取代现有神经网络中普通的普通卷积和即插即用,形成具有更鲁棒建模能力的中心差分卷积网络(CDCN)。
  2. 我们提出了CDCN++,CDCN的一个扩展版本,由搜索的主干网络和多尺度注意融合模块(MAFM)组成,可以有效地聚合多级CDC特征。
  3. 据我们所知,这是第一个搜索FAS任务的神经结构的方法。与之前基于softmax损失监督的NAS分类任务不同,我们在一个专门设计的CDC搜索空间上搜索非常适合的帧级网络的深度监督FAS任务。
  4. 我们提出的方法在所有6个基准数据集上通过内部和跨数据集测试实现了最先进的性能。

2. 相关工作

人脸活体检测

传统的人脸反欺骗方法通常从面部图像中提取手工制作的特征来捕捉欺骗模式。一些经典的局部描述符,如LBP [7,15]、SIFT [44]、SURF [9]、HOG [29]和DoG [45]被用来提取帧级特征,而视频级方法通常捕获动态线索,如动态纹理[28]、微运动[53]和眼睛闪烁[41]。最近,人们提出了一些基于深度学习的帧级和视频级人脸反欺骗的方法。相比之下,引入辅助深度监督FAS方法[4,36]来有效地学习更详细的信息。另一方面,提出了几种视频级CNN方法来利用PAD的动态时空[56,62,33]或rPPG [31,36,32]特征。尽管实现了最先进的性能,基于视频级深度学习的方法需要长序列作为输入。此外,与传统的描述符相比,CNN容易过度拟合,很难在看不见的场景上很好地概括。

卷积运算符

畳み込み演算子は、深層学習フレームワークで基本的な視覚特徴を抽出するための一般的な方法です。最近、一般的な畳み込み演算子の拡張が提案されています。一方向では、古典的なローカル記述子 (LBP [2] やガボール フィルター [25] など) が畳み込み設計で考慮されます。代表的な研究には、ローカル バイナリ畳み込み [27] とガボール畳み込み [38] が含まれます。これらは、それぞれ計算コストを節約し、空間変動に耐える能力を向上させるために提案されています。もう 1 つの方向は、集約の空間範囲を変更することです。2 つの関連する研究は、ダイヤル コンボリューション [63] と変形可能なコンボリューション [14] です。ただし、これらの畳み込み演算子は、不変のきめの細かい特徴を表現する能力が限られているため、FAS タスクには適していない可能性があります。

ニューラル アーキテクチャの検索

私たちの研究は、NAS に関する最近の研究 [11、17、35、47、68、69、60] によって動機付けられていますが、顔のスプーフィング対策タスクではなく、高性能の深層教師ありモデルを見つけることに重点を置いています。既存の NAS 手法は主に 3 つのカテゴリに分類されます: 1) 強化学習ベース [68,69]、2) 進化的アルゴリズム ベース [51,52]、3) 勾配ベース [35,60,12]。ほとんどの NAS メソッドは、小規模なプロキシ タスクでネットワークを検索し、見つかったアーキテクチャを別の大きなターゲット タスクに転送します。コンピュータビジョンアプリケーションの観点から、NAS は顔認識 [67]、行動認識 [46]、人物 ReID [50]、物体検出 [21]、およびセグメンテーション [65] タスク用に開発されています。私たちの知る限り、顔のスプーフィング対策タスクに NAS ベースの方法は現在ありません。上記の欠点を克服し、ギャップを埋めるために、特別に設計された畳み込み演算子で深い教師あり FAS タスクを探索します。

3. 方法論

このセクションでは、まずセクション 3.1 で中心差分畳み込みを紹介し、次にセクション 3.2 で顔のなりすまし防止のための中心差分畳み込みネットワーク (CDCN) を紹介し、最後にセクション 3.3 でアテンション付き検索メカニズムを紹介します。 (CDCN++)。

3.1 中心差分畳み込み

最新の深層学習フレームワークでは、特徴マップと畳み込みは 3 次元形状 (2 次元の空間領域と追加のチャネル次元) で表現されます。畳み込み演算はチャネル次元全体で同じままであるため、簡単にするために、このサブセクションでは畳み込みを 2D で説明しますが、3D への拡張は簡単です。

基本的な畳み込み

2D 空間畳み込みは視覚タスクのための CNN の基本的な操作であるため、ここではそれを通常の畳み込みとして示し、最初に確認します。2 次元の畳み込みには、次の 2 つの主要な手順があります。

1) 入力特徴マップ x 上の局所受容領域領域 R をサンプリングします;
2) 重み付き合計によってサンプリングされた値を集計します。したがって、出力特徴マップ y は、
y ( p 0 ) = ∑ pn ∈ R w ( pn ) x ( p 0 + pn ) ( 1 ) y(p_0)=\sum_{p_n\in R}w( p_n) x(p_0+p_n)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (1)そして( p0=pRw ( p) x ( p0+p) ( 1 )                   

ここで、p0 は入力および出力特徴マップ上の現在位置を示し、pn は R 内の位置を列挙します。たとえば、3×3 カーネルの局所受容野領域 1 は R = {(−1, −1), (−1, 0), . . , (0, 1), (1, 1)} となります。 。

基本的な畳み込みと中心差分演算の組み合わせ

バイナリを中心とした差分で局所的な関係を記述する、よく知られたローカル バイナリ パターン (LBP) [7] からインスピレーションを得て、基本的な畳み込みに中心差分演算を導入して、その表現と汎化機能を強化します。
同様に、中心差分畳み込みにも、サンプリングと集計という 2 つのステップが含まれます。サンプリング ステップ サイズは基本コンボリューションと似ていますが、集計ステップは異なります。図 2 に示すように、中心差分コンボリューションは、サンプリングされた値の中心方向の勾配を集計する傾向が強くなります。式 (1) は次のようになります。
y ( p 0 ) = ∑ pn ∈ R w ( pn ) ( x ( p 0 + pn ) − x ( p 0 ) ) ( 2 ) y(p_0)=\sum_{p_n\in R }w(p_n)(x(p_0+p_n)-x(p_0))\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (2)そして( p0=pRw ( p) ( x ( p0+px ( p0)) ( 2 )                  pn = ( 0 , 0 )
の場合p=( 0 ,0 )、中心位置p 0 p_0p0それ自体では、勾配値は常に 0 に等しくなります。

図 2 は次のとおりです。ここに画像の説明を挿入

中心差分
畳み込みニューラル ネットワークでは、畳み込みカーネルに差分カーネルを導入することで中心差分演算を実装できます。具体的には、差分カーネルをコンボリューション カーネルの中心に追加して、中心ピクセルと隣接ピクセルの差を計算し、この値を元のコンボリューション カーネルの重みに追加して、より適切にキャプチャする効果を実現します。画像ピクセルの変化傾向。
一次差分を例として、畳み込みカーネルのサイズが3 × 3 3\times 3であると仮定します。3×3の場合、差分カーネルのサイズも3 × 3 3\times 33×3、中心ピクセルの重みは0 00、残りのピクセルの重みは− 1 -11または1 11、具体的には次のようになります:
[ − 1 0 1 − 1 0 1 − 1 0 1 ] \begin{bmatrix} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \end { b行列} 11 1000111
コンボリューション演算を実行する場合、差分カーネルとコンボリューション カーネルを特定の方法で重ね合わせてから、画像に対してコンボリューション演算を実行します。具体的には、畳み込みカーネルの重み行列がWWであるとします。Wの場合、畳み込み演算の出力は次のように表すことができます。
y ( p 0 ) = ∑ pn ∈ R ( ∑ i , j W ( i , j ) K ( pn + i , pn + j ) ) x ( p 0 + pn ) y(p_0)=\sum_{p_n\in R}\left(\sum_{i,j}W(i,j)K(p_n+i,p_n+j)\right)x(p_0+p_n )そして( p0=pR(jW (j ) K ( p+p+x ( p0+p)
ここでKKK は差動コア、W ( i , j ) W(i,j)W (j )は、コンボリューション カーネルの重み値x ( p 0 + pn ) x(p_0+p_n)x ( p0+p) は、入力画像の座標がp 0 + pn p_0+p_np0+py ( p 0 )のピクセル値y(p_0)そして( p0)は畳み込み演算の出力を表します。

ライブ顔検出のタスクでは、それが強度レベルの意味論的情報であれ、勾配レベルでの詳細情報であれ、本物の顔を詐欺的な顔から区別する上で重要な役割を果たします。これは、通常の畳み込みと中心の組み合わせの組み合わせが重要であることを示しています。差分畳み込み より強力なモデリング機能を提供する実行可能な方法である可能性があります。したがって、中心差分畳み込みを次のように一般化します。
y ( p 0 ) = θ ∑ pn ∈ R w ( pn ) ( x ( p 0 + pn ) − x ( p 0 ) ) + ( 1 − θ ) ∑ pn ∈ R w ( pn ) x ( p 0 + pn ) ( 3 ) y(p_0)=\theta \sum_{p_n\in R}w(p_n)(x(p_0+p_n)-x(p_0))\\+ ( 1-\theta)\sum_{p_n\in R}w(p_n)x(p_0+p_n) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (3)そして( p0=pRw ( p) ( x ( p0+px ( p0))+ ( 1pRw ( p) x ( p0+p) ( 3 )                 

前半は中心差分コンボリューション、後半は基本コンボリューションで、それぞれ勾配レベルの詳細とセマンティック情報を取得します。

その中で、ハイパーパラメータ θ ∈ [0,1] は、強度レベルと勾配レベル情報の間の寄与を重み付けします。θ の値が大きいほど、中心微分勾配情報の重要性が高くなります。以降、この一般化された中心差畳み込みを CDC と呼びますが、これはコンテキストから簡単に識別できるはずです。

中心差分畳み込みの実装

最新の深層学習フレームワークで CDC を効率的に実装するために、式 (3) を分解して追加の中心差分項を含む基本的な畳み込みにマージします: y ( p 0 ) = ∑ pn ∈ R w ( pn ) x ( p 0 +
pn ) + θ ( − x ( p 0 ) ∑ pn ∈ R w ( pn ) ) ( 4 ) y(p_0)= \sum_{p_n\in R}w(p_n)x(p_0+p_n )+\theta(- x(p_0)\sum_{p_n\in R}w(p_n)) \ \ \ \ \ (4)そして( p0=pRw ( p) x ( p0+p+θ ( x ( p0pRw ( p)) ( 4 )     

式 (4) によると、CDC は PyTorch [42] と TensorFlow [1] の数行のコードで簡単に実装できます。式 (4) の導出は、次のような Pytorch コードに基づいています。
ここに画像の説明を挿入

import torch . nn as nn
import torch . nn. functional as F
class CDC (nn.Module):
	def __init__ (self,IC,OC,K=3,P=1,theta =0.7):
		# IC, OC: in channels , out channels
		# K, P: kernel size , padding
		# theta : hyperparameter in CDC
		super(CDC, self).init ()
		self.vani = nn.Conv2d(IC,OC,kernel_size=K, padding=P)
		self.theta = theta
		def forward(self,x):
			# x: input features with shape [N,C,H,W]
			out vanilla = self.vani (x)
			kernel diff = self.conv.weight.sum(2).sum(2)
			kernel diff = kernel diff [:, :, None, None]
			out CD = F.conv2d(input=x, weight= kernel_diff , padding=0)
			return out vanilla − self.theta ∗ out CD

このコードは、中心差分畳み込み (CDC) PyTorch モデル クラスを定義します。これには主に次のコンポーネントが含まれます。

initメソッド: CDC クラスの初期化関数を定義します。入力パラメータには、入力チャネル IC の数、出力チャネル OC の数、コンボリューション カーネルのサイズ K、パディング P、CDC ハイパーパラメータが含まれます。シータなど この関数では、最初に nn.Module の初期化関数を呼び出し、次に通常の畳み込み vani を定義し、ハイパーパラメーター theta を保存します。

forward メソッド: CDC モデルの順伝播関数を定義します。入力パラメーター x は入力特徴テンソル、その形状は [N,C,H,W] です。ここで、N はバッチ サイズ、C は入力の数ですチャネル、H と W はそれぞれ入力特徴マップの高さと幅です。順伝播プロセスでは、まず入力特徴に対して通常の畳み込み演算 vani(x) を実行して out_vanilla を取得し、次に self.conv.weight によって差分カーネル kernel_diff を計算し、入力特徴 x に適用して、中央差分体積 積 out_CD の結果。最後に、out_vanilla から theta * out_CD を減算して、最終出力を取得します。

このうち、F.conv2d は PyTorch のコンボリューション関数、self.conv.weight は CDC モデルのコンボリューション カーネルを表し、None はこの位置に新しいディメンションを挿入することを表します。super(CDC, self).init() は親クラス nn.Module のinit関数を呼び出し、nn.Conv2d は通常の畳み込みの演算を定義します。

self.conv.weight は CDC モデルの通常の畳み込み演算の畳み込みカーネルを表し、sum(2).sum(2) はそれぞれ 3 番目と 4 番目の次元 (つまり、高さと幅の次元) での合計演算を表します。 kernel_diff は差分カーネルです。このうち、3次元目の合計は差分カーネルが幅方向に1列のみとなり、4次元目の合計は差分カーネルが高さ方向に1行のみとなり、[OC, IC]の形になります。 , 1, 1] テンソル。

次に、kernel_diff[:, :, None, None] を使用して、kernel_diff テンソルの 3 番目と 4 番目の次元に新しい次元を追加します。つまり、形状は [OC, IC, 1, 1] になり、これは次と同じです。入力特徴は同じ形状を持ち、中心差分畳み込み演算に適用できます。

前作との関係性

この論文では、CDC と基本畳み込み、ローカル バイナリ畳み込み [27]、およびガボール畳み込み [38] との関係について説明します。これらは同様の設計思想を持ちますが、重点が異なります。セクション 4.3 のアブレーション研究では、顔のなりすまし対策タスクにおける CDC の優れたパフォーマンスが示されています。

基本的な畳み込みとの関係。CDC はより一般的です。式 (3) から、基本的な畳み込みは、θ = 0 の場合、つまり勾配情報なしで局所強度情報を集約する場合の CDC の特殊なケースであることがわかります。

ガボール畳み込みとの関係 [38]。ガボール畳み込み (GaborConv) は空間変換 (方向やスケールの変更など) の表現能力を強化することに重点を置いていますが、CDC はさまざまな環境でのきめの細かいロバストな特徴を表現することに重点を置いています。

3.2 女性の健康

高度に監視された顔の生存検出方法 [36、4] は、スプーフィングされた顔と生きている顔の 3D 形状ベースの識別を利用し、FAS モデルがスプーフィングの手がかりを捕捉するためのピクセルレベルの詳細を提供します。これに基づいて、この論文はベースラインとして同様の深い監視付きネットワークの深さ「[36]」を構築します。よりきめ細かく堅牢な特徴を抽出して顔深度マップを推定するために、CDC が導入されて中心差分畳み込みネットワーク (CDCN) が形成されます。DepthNet は、すべての CDC 演算子に θ = 0 が使用される場合の、提案された CDCN の特殊なケースであることに注意してください。

CDCN の詳細を表 1 に示します。サイズ 3×256×256 の単一の RGB 顔画像が与えられると、マルチレベル (低、中、高レベル) 融合特徴が抽出され、サイズ 32×32 のグレースケールの顔の深度が予測されます。デフォルト設定として θ = 0.7 を使用します。θ に関するアブレーションの研究はセクション 4.3 で示されます。
ここに画像の説明を挿入

表1。DeepNet と CDCN のアーキテクチャ。角括弧内はフィルターのサイズと機能の寸法です。すべての畳み込み層は stride=1 で、その後に BN-ReLU 層が続きますが、最大プーリング層は stride=2 です。

損失関数には、平均二乗誤差損失LMSE L_{MSE}を使用します。LMSEピクセルレベルの監視を実行します。さらに、FAS タスクにおけるきめ細かい監視要件については、コントラスト深度損失LCDL L_{CDL}を考慮してください。LCDL _ _[56] は、ネットワークがより詳細な機能を学習するのに役立ちます。したがって、全体の損失は、L total = LMSE + LCDL として表すことができます。L_{全体} = L_{MSE} + L_{CDL}。Lすべてにわたって_ _ _=LMSE+LCDL _ _

LCDL L_{CDL}LCDL _ _
CDL 損失関数は、深層学習画像分類タスク用の損失関数です。正式名称は「中心差損」で、中国語訳は中心差損となります。

CDL 損失関数の目的は、分類モデルが異なるカテゴリ間の類似性を記述する能力を向上させ、分類中にモデルが異なるカテゴリをより適切に区別できるようにすることです。具体的には、CDL 損失関数は、モデル予測結果と実際のラベル間の差を測定するハイパーパラメーター (つまり、中心差分係数) を導入することによって、異なるカテゴリ間の類似性を測定します。CDL 損失関数では、特徴空間内で 2 つのクラスが近い場合、それらの類似性はより強くペナルティを受け、モデルの分類精度が向上します。

具体的には、CDL 損失関数の計算プロセスは次のとおりです。まず、入力サンプルに対するモデルの予測結果を計算し、次に実際のラベルと予測結果の差に応じて分類損失を計算します。次に、モデルの中間層の特徴マップに対して中心差分演算を実行することにより、異なるカテゴリ間の類似度が計算され、最後に類似度が分類損失に加算されて、最終的な CDL 損失関数が得られます。

LCDL = − 1 N ∑ i = 1 N ∑ j = 1 K yi , j log ⁡ ( exp ⁡ ( si , j / τ ) ∑ k = 1 K exp ⁡ ( si , k / τ ) ) \mathcal{L_{ CDL}}=-\frac{1}{N} \sum{i=1}^{N} \sum_{j=1}^{K} y_{i, j} \log \left(\frac{\ exp \left(s_{i, j} / \tau\right)}{\sum_{k=1}^{K} \exp \left(s_{i, k} / \tau\right)}\right)LCDL _ _=N1=1Nj = 1Ky jログ_(k = 1K経験値( s/ t 経験値( s j/ t)。)
ここで、LDL \mathcal{L_{CDL}}LCDL _ _CDL、 NNの損失関数を表します。N はサンプルサイズを表し、KKK はカテゴリの数を表します、yi 、 jy{i,j}はい、はい_j はiiを意味しますiサンプル番目jカテゴリの実ラベル (値 0 または 1)、si 、 j s_{i,j}s jiiを示しますiサンプル番目jカテゴリτ \tauτ は温度パラメータexp ⁡ \expexp は指数関数、∑ \sum∑ は合計演算、log ⁡ \loglog は自然対数を表します。

3.3 CNDC++

表 1 から、CDCN には大まかなアーキテクチャ設計 (たとえば、異なるレベルで同じブロック構造を単純に繰り返す) があり、顔のスプーフィング対策タスクには準最適化されている可能性があることがわかります。古典的な視覚オブジェクト理解モデル [40] に触発されて、我々は CDCN++ の拡張バージョン (図 5 を参照) を提案します。これは、NAS ベースのバックボーン ネットワークと、選択的注意能力を備えたマルチスケール アテンション フュージョン モジュール (MAFM) で構成されます。構成。

顔のスプーフィング対策タスクのバックボーン ネットワーク検索

私たちの検索アルゴリズムは 2 つの勾配ベースの NAS メソッド [35、60] に基づいており、技術的な詳細については元の論文を参照してください。ここでは主に、FAS タスク検索のバックボーンに関する新しいコントリビューションを紹介します。

NASとはNeural Architecture Searchの略で、中国語訳はニューラルネットワークアーキテクチャサーチです。これは、最適なニューラル ネットワーク アーキテクチャを検索することで深層学習モデルのパフォーマンスを向上させる、自動化された深層学習手法です。NAS では、ヒューリスティック アルゴリズム、進化的アルゴリズム、強化学習などの手法を使用して、多数のニューラル ネットワーク構造空間を探索し、最もパフォーマンスの高いネットワーク構造を選択します。NAS を通じて、深層学習モデルの設計と最適化を加速し、特定のタスクやデータセットにより適したものにすることができます。

ここに画像の説明を挿入
図 3. CDC を使用したアーキテクチャ検索スペース。(a) 3 つのスタックされたセルで構成されるネットワーク。ステム層とヘッド層は 3x3 カーネルと θ = 0.7 の CDC を使用します。(b) セルには、入力ノード、4 つの中間ノード B1、B2、B3、B4、および出力ノードを含む 6 つのノードが含まれます。
(c) 2 つのノード間のエッジは可能な操作を表します。演算空間には 8 つの候補が含まれます。ここで、CDC_2_r は、まず 2 つのスタックされた CDC を使用して比率 r だけチャネル数を増やし、その後、元のチャネル サイズに戻すことを意味します。合計の検索スペースのサイズは 3 × 8 × 10 = 240 です。

ここに画像の説明を挿入

図 3(a) に示すように、その目標は、FAS タスクのネットワーク バックボーンを形成する 3 つのレベル (低レベル、中レベル、および高レベル) でセルを検索することです。人間の視覚系の専用の階層的に組織されたニューロン [40] にヒントを得て、私たちは、より柔軟で一般化されたこれらの多層細胞 (つまり、異なる構造を持つ細胞) を自由に検索することを好みます。この構成を「可変セル」と名付け、その影響についてはセクション 2 で検討します。4.3 (表 2 を参照) 以前の研究 [35、60] とは異なり、最新の入力ユニットの 1 つの出力のみを現在のユニットの入力として採用します。

ユニットレベル構造の場合、図 3(b) は、各ユニットが N ノード{ X } i = 0 N − 1 {\{X\}}^{N-1}_{i=0} として表されることを示しています。{ X }i = 0N 1の有向非巡回グラフ (DAG)。各ノードはネットワーク層を表します。操作空間をOOと表記しますO、図 3© は、設計された 8 つの候補操作 (なし、スキップ接続、CDC 接続) を示しています。特に、各エッジ( i , j ) (i, j)( i , j )は関数o ˜ ( i , j ) o˜^{(i,j)} をo (i,j)来表示,其中 o ˜ ( i , j ) ( x i ) = ∑ o ∈ O η o ( i , j ) ⋅ o ( x i ) o˜^{(i,j)}(xi)=\sum_{o∈O}η^{(i,j)}_o·o(x_i) o ( i , j ) (xi)=ああ( i j )o ( x私はSoftmax 関数は、アーキテクチャ パラメーターα ( i , j ) \alpha^{(i,j)} をある( i , j )は演算重みo ∈ O o ∈ OああO , つまりη o(i,j) = exp(α(i,j)) ∑ o′ ∈ O exp(αo′(i,j)) η^{(i,j)}_o=\frac{ exp (\alpha^{(i,j)})}{\sum{o'\in O}exp(\alpha^{(i,j)}_{o'})}ああ( i , j )=ああ'Oexp(aああ( i , j )e x p ( a( i , j ) )中間ノードは、xj = ∑ i < jo ˜ ( i , j ) ( xi ) x_j=\sum_{i<j}o˜^{(i,j)}(x_i) として表すことができます。バツj=< jo ( i , j ) (x私は)、一方、出力ノードx N − 1 x_{N−1}バツN 1次に、すべての中間ノードxi x_iバツ私はの加和、つまりx N − 1 = ∑ 0 < i < N − 1 β i ( xi ) x_{N-1}=\sum_{0<i<N-1}β_i(x_i)バツN 1=0 < i < N 1b私は( ×私はここでは、中間ノード間の重要度の重み β を学習するためのノード アテンション戦略を提案します。つまり、β i = exp ( β ′ i ) ∑ 0 < j < N − 1 exp ( β i ′ ) \beta_i =\frac{exp( \beta'i)}{\sum{0<j<N-1}exp(\beta'_i)}b私は=0 < j < N 1 e x p ( βe x p ( b)」,其中 β i β_i b私はは中間ノードxi x_iですバツ私は元の学習可能な重みβ i ' β'_ibソフトマックス。

検索フェーズでは、L train L_{train}L電車_ _およびL val L_{val}Lv a lそれぞれトレーニング損失と検証損失を示します。どちらも、セクション 3.2 で説明されている深く監視された損失関数L total L_{overall}に基づいています。Lすべてにわたって_ _ _ネットワーク パラメーター w とアーキテクチャ パラメーター α は、次の 2 レベルの最適化問題によって学習されます:
min α L val ( w ∗ ( α ) , α ) s . t . w ∗ ( α ) = argminw L train ( w , α ) ( 5 ) min_\alpha \ \ \ \ \ \ \ L_{val}(w^*(\alpha),\alpha)\\ st \ \ \ w^*(\alpha)=argmin_w \ L_{train }(w, \alpha)\ \ \ \ \ \ \ (5)_ある        Lv a l( w (a)_s w    (a)=平均_ _ _ _ L電車_ _( w a ) ( 5 )       

この定式化は、外側の問題が検証損失L val ( w ∗ ( α ) , α ) L_{val}(w^*(\alpha),\alpha) を最小化する 2 レベルの最適化問題を記述します。Lv a l( w (a)a )、その中にw ∗ ( a ) w^*(\alpha)w (α)は、内層問題の解決法、つまりトレーニング損失L train ( w , α ) L_{train}(w,\alpha) をL電車_ _( w α )見つかったパラメータ、つまりw ∗ ( α ) = argminw L train ( w , α ) w^*(\alpha)=argmin_w L_{train}(w,\alpha)w (a)=平均_ _ _ _L電車_ _( w α )内部問題の解決策は通常、勾配降下法などの最適化アルゴリズムによって達成されます。したがって、ネットワークパラメータww は、内層問題を解くことによって学習されます。wは、検証損失L val L_{val}Lv a lこのタイプの最適化は「学習方法の学習」と呼ばれます。

収束後、最終的な離散アーキテクチャは次の手順で取得されます。 1) Set o ( i , j ) = argmaxo ∈ O , o ≠ nonepo ( i , j ) o^{(i,j)}=argmax_{ o\ in O,o\neq none} p_o^{(i,j)}ああ( i , j )=最大_ _ _o O o=なし_ _ _pああ( i , j );2) 各中間ノードについて、最大値maxo ∈ O , o ≠ nonepo ( i , j ) max_{o \in O,o\neq none}p_o^{(i,j)} を持つノードを選択します。×o O o=なし_ _ _pああ( i , j )の入力エッジ、3) 各出力ノードに対して、最大値max 0 < i < N − 1 β i max_{0<i<N-1}\beta_{i} を選択します。×0 < i < N 1b私は(「ノード アテンション」として示されます) は中間ノードを入力として受け取ります。対照的に、最後の中間ノードを出力ノードとして選択する方が直感的です。セクション 4.3 でこれら 2 つの設定を比較します (表 2 を参照)。

MAFM

低レベル、中レベル、高レベルの特徴を単純に融合することで、検索された CDC アーキテクチャのパフォーマンスを向上させることができますが、重要な領域を見つけることは依然として困難であり、より多くの識別特徴を学習するのには役立ちません。人間の視覚系における選択的注意に触発されて [40、55]、さまざまなレベルのニューロンは、その受容野内にさまざまな注意刺激を与える可能性があります。したがって、空間的注意を介して低、中、高レベルの CDC 機能を洗練および融合できるマルチスケール アテンション フュージョン モジュール (MAFM) を提案します。
ここに画像の説明を挿入
図4に示すように、さまざまなレベルの特徴Fは、受容野に関連するカーネルサイズを通過します(つまり、私たちの場合、高/意味レベルは小さな注意カーネルサイズを持つ必要がありますが、低レベルは大きな注意を持つ必要があります)カーネル サイズ)は、空間的注意 [58] によって調整され、結合されます。洗練された機能F'F'F'は次のように表すことができます。
F i ' = F i ⊙ ( σ ( C i ( [ A ( F i ) , M ( F i ) ] ) ) ) , i ∈ { low , middle , high } ( 6 ) F'_i =F_i\odot (σ(C_i([A(F_i),M(F_i)]))),i\in\{低、中、高\} \ \ \ \ \ \ \ (6)F=F私は( p ( C私は([ A ( F私はM ( F私は)]))) { 低い, _ __hi g h } ( 6 )       
ここで、⊙ \odot⊙ はアダマール積を意味します。A と M は、それぞれ平均プーリング層と最大プーリング層を示します。σ はシグモイド関数を表し、C は畳み込み層を表します。Clow の場合は 7×7 の通常の畳み込みカーネルを使用し、C の場合は Mid C_{mid} をC、5×5 の通常の畳み込みカーネルを使用、C の場合、high C_{high}Cこんにちは_ _では、3×3 の通常のコンボリューション カーネルが使用されます。CDC は、空間的注意において非常に重要であるグローバル意味認識能力が限られているため、ここでは選択されませんでした。対応するアブレーション研究はセクション 4.3 で実行されます。

4. 実験

このセクションでは、アプローチの有効性を実証するために広範な実験を実施します。次に、使用したデータセットとメトリクス (セクション 4.1)、実装の詳細 (セクション 4.2)、結果 (セクション 4.3 ~ 4.5)、分析 (セクション 4.6) について順に説明します。

4.1 データセットと指標

データベース

私たちの実験では、OULU-NPU [10]、SiW [36]、CASIA-MFSD [66]、Replay- Attack [13]、MSU-MFSD [57]、SiW-M [37] という 6 つのデータベースを使用します。OULU-NPU と SiW は、内部テスト用にモデルの一般化 (目に見えない照明や攻撃ベクトルなど) を検証するための、それぞれ 4 つと 3 つのプロトコルを含む高解像度データベースです。CASIA-MFSD、Replay- Attack、および MSU-MFSD は、クロステスト用の低解像度ビデオを含むデータベースです。SiW-M は、最大 13 種類の攻撃を含む未知の攻撃に対する堅牢性を検証するためのクロスタイプ テストを実施するように設計されています。

パフォーマンス

OULU-NPU および SiW データセットでは、公正な比較のために、元のプロトコルとメトリクス、つまり攻撃プレゼンテーション分類エラー率 (APCER)、真のプレゼンテーション分類エラー率 (BPCER)、および ACER [24] に従います。ケースと繰り返される攻撃のクロステストでは、合計エラー率 (HTER) の半分が採用されています。CASIA-MFSD、Replay- Attack、および MSU-MFSD は、曲線下面積 (AUC) を使用してデータベース内のタイプ全体でテストされました。SiW-M のクロスタイプ テストには、APCER、BPCER、Acer、および Equal Error Rate (EER) が使用されました。

4.2 実装の詳細

深い世代

高密度顔位置合わせ PRNet [18] を使用して、生きている顔の 3D 形状を推定し、サイズ 32×32 の顔深度マップを生成します。詳細と例については、[56] を参照してください。本物の顔をスプーフィングされた顔と区別するために、トレーニング段階で実際の深度マップを [0,1] の範囲に正規化し、スプーフィングされた顔を 0 に設定します。これは [36] と同様です。

トレーニングとテストのセットアップ

提案手法は Pytorch を使用して実装されます。トレーニング フェーズでは、モデルは Adam オプティマイザーを使用して、初期学習率 (lr) と重み減衰 (wd) がそれぞれ 1e-4 と 5e-5 でトレーニングされます。最大 1300 エポックでトレーニングし、500 エポックごとに学習率を半分にします。バッチ サイズは 56 で、8 つの 1080Ti GPU が使用されます。テスト段階では、予測された深度マップの平均を最終スコアとして計算します。

検索設定

[60] と同様に、部分的なチャネル接続とエッジ正規化が採用されています。ネットワークの初期チャネル数は {32, 64, 128, 128, 128, 64, 1} で、検索後には 2 倍になります (図 3(a) を参照)。モデルの重みをトレーニングする場合は、lr=1e-4 および wd=5e-5 の Adam オプティマイザーが使用されます。アーキテクチャ パラメーターは、lr=6e-4 および wd=1e-3 で Adam オプティマイザーを使用してトレーニングされます。OULU-NPU のプロトコル 1 では、60 エポックの検索にバッチ サイズ 12 が使用され、最初の 10 エポックではアーキテクチャ パラメーターは更新されません。3 台の 1080Ti でこのプロセス全体に 1 日かかりました。

4.3 アブレーション実験

このサブセクションでは、提案された CDC、CDCN、および CDCN++ ですべてのアブレーション実験を実行し、その詳細を調査します。すべての実験は、トレーニング セットでトレーニングされた OULU-NPU [10] のプロトコル 1 で実行されます。照明条件とテストセット間の位置。

私はCDCNに対するθの影響

式 (3) によると、θ は勾配ベースの詳細の寄与を制御します。つまり、θ が大きいほど、より多くの局所的な詳細が含まれます。図 6(a) に示すように、θ > 0.3 の場合、CDC は通常の畳み込み (θ = 0、ACER = 3.8%) よりも常に優れたパフォーマンスを達成します。これは、きめの細かい情報に基づく中心差が非常に重要であることを示しています。 FAS タスク。非常に役に立ちます。θ = 0.7 のときに最高のパフォーマンス (ACER = 1.0%) が得られるため、以下の実験ではこの設定を使用します。すべての層で θ を一定に保つことに加えて、付録 B に示すように、各層の θ を学習する適応 CDC 手法も検討します。

ここに画像の説明を挿入
図6. (a) CDCN における θ への影響。(b) 異なる畳み込み間の比較 (最高のパフォーマンスを発揮するハイパーパラメータのみを表示)。ACER のパフォーマンスが低いほど、パフォーマンスは高くなります。

CDC と他の畳み込み

CDC と以前の畳み込みの関係についてはセクション 3.1 で説明します。さまざまな環境における詳細な不正アーティファクトは勾配ベースの不変特徴によって表現される必要があるため、顔のなりすまし対策タスクには CDC の方が適していると考えられます。図 6(b) は、CDC が他の畳み込みより 2% ACER 以上優れていることを示しています。LBConv がバニラ畳み込みよりも優れていることは興味深いことであり、FAS タスクではローカル勾配情報が重要であることを示唆しています。GaborConv は、空間的に不変の特徴をキャプチャするように設計されているため、パフォーマンスが最悪であり、顔のスプーフィング対策タスクには役に立ちません。

NAS 構成の影響

ここに画像の説明を挿入
表 2 は、セクション 3.3 で説明した 2 つの NAS 構成、つまり異なるセルとノードに注目した場合のアブレーション研究を示しています。どちらの構成でも、ベースライン設定 (セルを共有し、出力ノードとして最後の中​​間ノード) と比較して検索パフォーマンスが向上します。理由は 2 つあります: 1) より柔軟な検索制約を使用することで、NAS は人間の視覚システムに近い、さまざまなレベルで特殊なセルを見つけることができます [40]。2) 最後の中間ノードを取得するのは最適ではない可能性があります。出力として、最も重要なものを選択しながら、より合理的です。

NASベースのバックボーンとMAFMの有効性

提案された CDCN++ には、図 5 に示すように、NAS ベースのバックボーン ネットワークと MAFM が含まれています。明らかに、複数の層のセルは大きく異なり、中間層のセルにはより深い (4 CDC) 層があります。表 3 は、NAS ベースのバックボーンと MAFM に関するアブレーション研究を示しています。最初の 2 行からわかるように、直接マルチステージ フュージョンを備えた NAS を備えたベース ネットワークは、NAS を備えていないベース ネットワーク (0.3% ACER) よりも優れたパフォーマンスを示しており、検索したアーキテクチャの有効性を示しています。一方、MAFM を使用したバックボーン ネットワークの ACER は、直接多層融合を使用したバックボーン ネットワークの ACER より 0.5% 低く、MAFM の有効性が示されています。また、MAFM の畳み込みタイプとカーネル サイズも分析し、通常の畳み込みが意味論的な空間的注意を捕捉するのに適していることを発見しました。さらに、アテンション コンボリューション カーネルのサイズは、低レベルの機能に対しては十分に大きく (7x7)、高レベルの機能に対しては十分に小さく (3x3) する必要があります。
ここに画像の説明を挿入

4.4 内部テスト

内部テストは、OULU-NPU と SiW データセットの両方で実行されます。OULU-NPU の 4 つのプロトコルと SiW の 3 つのプロトコルに従って評価を行っています。STASN [62] を含むすべての比較方法は、公平な比較のために追加のデータセットなしでトレーニングされます。

OULU-NPU の結果

ここに画像の説明を挿入
表 4 では、私たちが提案した CDCN++ が 4 つのプロトコルすべてで第 1 位にランクされており (ACER が 0.2%、1.3%、1.8%、および 5.0%)、この方法が外部環境、攻撃ベクトル、入力カメラに対して非常に効果的であることが示されています。バリエーションのパフォーマンスが良好です。マルチフレームの動的特徴を抽出する他の最先端の方法 (Auxiliary [36]、STASN [62]、GRADIANT [6]、および FAS-TD [56]) とは異なり、私たちの方法はフレームレベルの入力のみを必要とします。これは実際の展開に非常に適しています。注目に値するのは、NAS インフラストラクチャは Protocol-1 で検索されますが、すべてのプロトコルに転送可能であり、汎用性が高いということです。
SiWの結果。表 5 は、SiW データセットに対する私たちの手法のパフォーマンスを、Auxiliary [36]、STASN [62]、および FAS-TD [56] という 3 つの最先端の手法と比較しています。表 5 からわかるように、私たちの方法は 3 つのプロトコルすべてで最高のパフォーマンスを発揮し、(1) 顔のポーズと表情の変化、(2) さまざまなスプーフィング ベクトルの変化、および (3) 交差/未知の表現における CDC を明らかにします。 優れた一般化能力攻撃面では。

SiWの結果

ここに画像の説明を挿入
表 5 は、SiW データセットに対する私たちの手法のパフォーマンスを、Auxiliary [36]、STASN [62]、および FAS-TD [56] という 3 つの最先端の手法と比較しています。表 5 からわかるように、私たちの方法は 3 つのプロトコルすべての中で最も優れたパフォーマンスを発揮し、(1) 顔のポーズと表情のバリエーション、(2) さまざまなスプーフィング媒体に対する CDC の優れた一般化能力を明らかにしています。攻撃が提示されました。

4.5 クロステスト

モデルの一般化能力をさらに実証するために、タイプ間テストとデータセット間テストをそれぞれ実施し、未知の表現攻撃と目に見えない環境に対するモデルの一般化能力を検証します。

クロスタイプテスト

ここに画像の説明を挿入
[3] で提案されたプロトコルに従って、CASIA-MFSD [66]、Replay- Attack [13]、および MSU-MFSD [57] を使用して、リプレイ攻撃とプリント攻撃の間のデータセット内のクロスタイプ テストを実行します。表 6 に示すように、私たちが提案した CDC ベースの手法は全体的なパフォーマンスで最高のパフォーマンスを示し (ゼロショット学習ベースの手法である DTN [37] をも上回っています)、未知の攻撃に対して一貫して優れた一般化能力があることを示しています。さらに、最新の SiW-M [37] データセットでクロスタイプ テストも実施し、13 件の攻撃の中で最高の平均 ACER (12.7%) と EER (11.9%) を達成しました。詳細な結果については、付録 C を参照してください。

データセット全体でテストする

ここに画像の説明を挿入

この実験では、データセット全体で 2 つのプロトコルがテストされています。1 つは、CASIA-MFSD でトレーニングしてから Replay- Attack でテストすることで (プロトコル CR と呼ばれます)、2 つ目はトレーニング データ セットとテスト データ セットを交換することで (プロトコル RC と呼ばれます) ます。表 7 に示すように、私たちが提案する CDCN++ はプロトコル CR で 6.5% の HTER を達成しており、これは以前の最先端の方法と比較して 11% という大きな利点です。プロトコル RC についても、最先端のフレームレベルの手法を上回っています (表 7 の後半を参照)。パフォーマンスは、Auxiliary [36] と FAS-TD [56] に同様の時間動的機能を導入することでさらに改善される可能性があります。

4.6 分析と視覚化

このサブセクションでは、CDC のパフォーマンスが優れている理由の分析を示す 2 つの視点を提供します。

ドメインドリフトに対する堅牢性。

ここに画像の説明を挿入

OULU-NPU のプロトコル 1 は、ドメイン ドリフト (つまり、トレーニング/開発セットとテスト セット間の大きな照明差) が発生した場合の CDC の堅牢性を検証するために使用されます。図 7 は、通常の畳み込みを使用するネットワークの開発セットでは低い ACER (青い曲線) があり、テスト セットでは高い ACER (灰色の曲線) を示しています。これは、通常の畳み込みが既知の領域では簡単であることを示しています。照明が変わるとき。対照的に、CDC を使用したモデルは、開発セット (赤い曲線) とテスト セット (黄色の曲線) でより一貫したパフォーマンスを達成でき、CDC がドメイン ドリフトに対して堅牢であることを示しています。

機能の視覚化

ここに画像の説明を挿入
図 8 は、OULU-NPU プロトコル 1 で t-SNE [39] を使用したテスト ビデオのマルチレベル フュージョン機能の分布を示しています。図 8(a) から、CDC を使用した特徴は単純な畳み込みを使用した特徴よりも優れたクラスタリング動作を示すことがわかりますが、図 8(b) はその逆を示しています。これは、CDC が本物の顔を偽物の顔と区別できることを示しています。MAFM の機能マップ (CDC あり/なし) とアテンション マップの視覚化は、付録 D にあります。

5. まとめと今後の課題

この論文では、Central Difference Convolution (CDC) と呼ばれる、顔スプーフィング対策タスク用の新しい演算子を提案します。CDC に基づいて、中心差分畳み込みネットワーク (CDCN) が設計されています。また、検索された CDC バックボーンとマルチスケール アテンション フュージョン モジュール (MAFM) を含む CDCN++ も提案します。広範な実験により、提案された方法の有効性が実証されています。CDC の研究はまだ初期段階にあることに注意してください。将来の方向性としては、1) 各層/チャネルのコンテキスト認識適応型 CDC の設計、2) 他のプロパティ (例: ドメインの汎化) の探索、および他の視覚タスク (例: 画質評価 [34] や顔の不審さの検出) のパフォーマンスの向上が挙げられます。の 。

6. 謝辞

この研究は、フィンランド アカデミーの MiGA プロジェクト (助成金番号 316765)、ICT 2023 プロジェクト (助成金番号 328115)、および Infotech Oulu の支援を受けました。さらに、コンピューティング リソースを提供してくださったフィンランド CSC IT センターに感謝いたします。

引用

参考文献が多すぎるため、ここには表示されません。詳細については、記事の原文とモデルのソースコードを参照してください: https://github.com/ZitongYu/CDCN **

付録

A. CDC の導出とコード

ここでは、式 (7) の CDC の詳細な導出 (ドラフトの式 (4) を参照) と、Pytorch の CDC のコード (図 9 を参照) を示します。
ここに画像の説明を挿入
再現可能なコードは上記を参照
ここに画像の説明を挿入

B. CDC の適応θ

顔のなりすまし防止タスクでは、最適なハイパーパラメータ θ = 0.7 を手動で測定できますが、中心差分コンボリューション (CDC) を他のデータセット/タスクに適用する場合、最適な θ を見つけるのは依然として面倒です。ここで、θ を各層のデータ駆動型の学習可能な重みとみなします。これを実装する簡単な方法は、Sigmoid(θ) を使用して出力範囲が [0,1] 内に収まるようにすることです。

図 10(a) に示すように、興味深いことに、低レベル (第 2 層から第 4 層) と高レベル (第 8 層から第 10 層) の学習重みが比較的小さいのに対し、中レベル (第 5 層から第 7 層) の学習重みは大きくなっています。レベルはもっと大きいです。これは、中間レベルの特徴については、中心差の勾配情報がより重要である可能性があることを示唆しています。性能の比較に関しては、図 10(b) から、CDC は定数 θ = 0.7 を使用しているのに対し、適応 CDC は同等の結果 (1.8% 対 1.0% ACER) を示していることがわかります。

ここに画像の説明を挿入

C. SiW-M データセットでのクロスタイプ テスト

ここに画像の説明を挿入
SiW-M データセット [37] 上で、同じクロスタイプ テスト プロトコル (13 の攻撃を別々にテスト) に従って、私たちの提案方法を 3 つの最先端の顔スプーフィング対策方法 [10、36、37] と比較します。 . 目に見えない攻撃に対する一般化能力を検証するための比較。表 8 に示すように、当社の CDCN++ は、以前の最先端の方法 [37] と比較して、それぞれ 24% および 26% 優れた ACER および EER を達成しています。具体的には、ほぼすべての「ID 偽装」攻撃と「部分的ペーパー」攻撃 (EER = 0%) を検出しましたが、これまでの方法は「ID 偽装」攻撃ではあまりパフォーマンスが良くありませんでした。明らかに、マスク攻撃 (「HalfMask」、「SiliconMask」、「TransparentMask」、および「MannquinHead」) の EER と ACER が大幅に減少しています。これは、CDC ベースの手法が 3D 非平面攻撃の性別に対して適切に一般化していることを示しています。

D. 機能の視覚化

ここに画像の説明を挿入
図 11 は、MAFM の低レベルの機能と、対応する空間アテンション マップを示しています。実写の顔と偽装された顔では、特徴とアテンション マップが大きく異なることは明らかです。1) 低レベルの特徴 (図 11 の 2 行目と 3 行目を参照) の場合、なりすまし顔からの神経活性化は顔と背景領域の間でより均一であるように見えますが、生きている顔からの神経活性化は顔に集中しています。領域。CDC の機能を使用すると、詳細な不正パターン (「Print1」のグリッド アーティファクトや「Replay2」の反射アーティファクトなど) を簡単にキャプチャできることは注目に値します。2) MAFM の空間注意マップ (図 11 の 4 行目を参照) の場合、生きている顔のすべての領域 (髪、顔、背景) は比較的強い活性化を持ちますが、スプーフィングされた顔の顔領域は活性化への寄与が弱くなります。

コード

CDCブロック

たとえば、CDC の公式:
y ( p 0 ) = ∑ pn ∈ R w ( pn ) x ( p 0 + pn ) + θ ( − x ( p 0 ) ∑ pn ∈ R w ( pn ) ) y(p_0) = \sum_{p_n\in R}w(p_n)x(p_0+p_n)+\theta(-x(p_0)\sum_{p_n\in R}w(p_n))そして( p0=pRw ( p) x ( p0+p+θ ( x ( p0pRw ( p))

コードは以下のように表示されます。

class Conv2d_cd(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1,
                 padding=1, dilation=1, groups=1, bias=False, theta=0.7):

        super(Conv2d_cd, self).__init__() 
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)
        self.theta = theta

    def forward(self, x):
        out_normal = self.conv(x)

        if math.fabs(self.theta - 0.0) < 1e-8:
            return out_normal 
        else:
            #pdb.set_trace()
            [C_out,C_in, kernel_size,kernel_size] = self.conv.weight.shape
            kernel_diff = self.conv.weight.sum(2).sum(2)
            kernel_diff = kernel_diff[:, :, None, None]
            out_diff = F.conv2d(input=x, weight=kernel_diff, bias=self.conv.bias, stride=self.conv.stride, padding=0, groups=self.conv.groups)

            return out_normal - self.theta * out_diff

空間注意メカニズム

class SpatialAttention(nn.Module):
    def __init__(self, kernel = 3):
        super(SpatialAttention, self).__init__()


        self.conv1 = nn.Conv2d(2, 1, kernel_size=kernel, padding=kernel//2, bias=False)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        x = torch.cat([avg_out, max_out], dim=1)
        x = self.conv1(x)
        
        return self.sigmoid(x)

まず、平均プーリング操作と最大プーリング操作が入力 x に対して実行され、平均特徴マップ avg_out と最大特徴マップ max_out が取得されます。これら 2 つの特徴マップは、チャネル次元に沿って形状 (N、2、H、W) のテンソル x に連結されます。

次に、畳み込み層 self.conv1 に x を入力して畳み込み演算を行い、形状 (N, 1, H, W) のテンソルを取得します。最後に、畳み込み結果をシグモイド関数に入力して活性化し、各画素の注目重み、すなわち出力結果を求める。

この操作は、入力特徴マップの各ピクセルに対して重み付け処理を実行し、より重要なピクセルに高い重みを割り当てることで、モデルの認識精度を向上させると理解できます。具体的には、空間注意メカニズムは、モデルが画像内の重要な領域に焦点を合わせやすくし、無関係な情報の干渉を軽減し、モデルの堅牢性と汎化能力を向上させるのに役立ちます。

CDCN

ここに画像の説明を挿入
次のコードは CDCN ニューラル ネットワーク アーキテクチャを実装します。

class CDCN(nn.Module):

    def __init__(self, basic_conv=Conv2d_cd, theta=0.7):   
        super(CDCN, self).__init__()
        
        
        self.conv1 = nn.Sequential(
            basic_conv(3, 64, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(64),
            nn.ReLU(),    
        )
        
        self.Block1 = nn.Sequential(
            basic_conv(64, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),   
            basic_conv(128, 196, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(196),
            nn.ReLU(),  
            basic_conv(196, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),   
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
            
        )
        
        self.Block2 = nn.Sequential(
            basic_conv(128, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),   
            basic_conv(128, 196, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(196),
            nn.ReLU(),  
            basic_conv(196, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),  
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
        )
        
        self.Block3 = nn.Sequential(
            basic_conv(128, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),   
            basic_conv(128, 196, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(196),
            nn.ReLU(),  
            basic_conv(196, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),   
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
        )
        
        self.lastconv1 = nn.Sequential(
            basic_conv(128*3, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),    
        )
        
        self.lastconv2 = nn.Sequential(
            basic_conv(128, 64, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(64),
            nn.ReLU(),    
        )
        
        self.lastconv3 = nn.Sequential(
            basic_conv(64, 1, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.ReLU(),    
        )
        
        
        self.downsample32x32 = nn.functional.interpolate(size=(32, 32), mode='bilinear')

 
    def forward(self, x):	    	# x [3, 256, 256]
        
        x_input = x
        x = self.conv1(x)		   
        
        x_Block1 = self.Block1(x)	    	    	# x [128, 128, 128]
        x_Block1_32x32 = self.downsample32x32(x_Block1)   # x [128, 32, 32]  
        
        x_Block2 = self.Block2(x_Block1)	    # x [128, 64, 64]	  
        x_Block2_32x32 = self.downsample32x32(x_Block2)   # x [128, 32, 32]  
        
        x_Block3 = self.Block3(x_Block2)	    # x [128, 32, 32]  	
        x_Block3_32x32 = self.downsample32x32(x_Block3)   # x [128, 32, 32]  
        
        x_concat = torch.cat((x_Block1_32x32,x_Block2_32x32,x_Block3_32x32), dim=1)    # x [128*3, 32, 32]  
        
        #pdb.set_trace()
        
        x = self.lastconv1(x_concat)    # x [128, 32, 32] 
        x = self.lastconv2(x)    # x [64, 32, 32] 
        x = self.lastconv3(x)    # x [1, 32, 32] 
        
        map_x = x.squeeze(1)
        
        return map_x, x_concat, x_Block1, x_Block2, x_Block3, x_input

入力 x のサイズは 3×256×256 で、RGB 画像を表します。まず畳み込み演算のために self.conv1 に x を入力し、64×256×256 の形状のテンソル x を取得します。

次に、畳み込みブロック self.Block1 に x を入力して畳み込み演算を行い、128×128×128 の形状のテンソル x_Block1 を取得します。次に、x_Block1 が 32×32 のサイズにアップサンプリングされ、128×32×32 の形状のテンソル x_Block1_32x32 が生成されます。

x_Block1 を畳み込みブロック self.Block2 に入力して畳み込み演算を行い、128×64×64 の形状のテンソル x_Block2 を取得します。次に、x_Block2 が 32×32 のサイズにアップサンプリングされ、128×32×32 の形状のテンソル x_Block2_32x32 が生成されます。

畳み込みブロック self.Block3 に x_Block2 を入力して畳み込み演算を行い、128×32×32 の形状のテンソル x_Block3 を取得します。次に、x_Block3 が 32×32 のサイズにアップサンプリングされ、128×32×32 の形状のテンソル x_Block3_32x32 が生成されます。

x_Block1_32x32、x_Block2_32x32、および x_Block3_32x32 をチャネル次元に沿って 128×3×32×32 の形状のテンソル x_concat に連結します。self.lastconv1 に x_concat を入力して畳み込み演算を行い、128×32×32 の形状のテンソル x を取得します。

self.lastconv2 に x を入力して畳み込み演算を行うと、64×32×32 の形状のテンソル x が得られます。self.lastconv3 に x を入力して畳み込み演算を行い、1×32×32 の形状のテンソル x を取得します。

最後に、x の最初の次元が圧縮され、32×32 の形状のテンソル map_x が得られます。同時に、x_concat、x_Block1、x_Block2、x_Block3、x_input を返します。

CDCN++

ネットワーク構造は次のとおりです。
ここに画像の説明を挿入

class CDCNpp(nn.Module):

    def __init__(self, basic_conv=Conv2d_cd, theta=0.7 ):   
        super(CDCNpp, self).__init__()
        
        
        self.conv1 = nn.Sequential(
            basic_conv(3, 64, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(64),
            nn.ReLU(),    
            
        )
        
        self.Block1 = nn.Sequential(
            basic_conv(64, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),  
            
            basic_conv(128, int(128*1.6), kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(int(128*1.6)),
            nn.ReLU(),  
            basic_conv(int(128*1.6), 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(), 
            
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
            
        )
        
        self.Block2 = nn.Sequential(
            basic_conv(128, int(128*1.2), kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(int(128*1.2)),
            nn.ReLU(),  
            basic_conv(int(128*1.2), 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),  
            basic_conv(128, int(128*1.4), kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(int(128*1.4)),
            nn.ReLU(),  
            basic_conv(int(128*1.4), 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),  
            
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
        )
        
        self.Block3 = nn.Sequential(
            basic_conv(128, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(), 
            basic_conv(128, int(128*1.2), kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(int(128*1.2)),
            nn.ReLU(),  
            basic_conv(int(128*1.2), 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(), 
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
        )
        
        # Original
        
        self.lastconv1 = nn.Sequential(
            basic_conv(128*3, 128, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            basic_conv(128, 1, kernel_size=3, stride=1, padding=1, bias=False, theta= theta),
            nn.ReLU(),    
        )
        
      
        self.sa1 = SpatialAttention(kernel = 7)
        self.sa2 = SpatialAttention(kernel = 5)
        self.sa3 = SpatialAttention(kernel = 3)
        self.downsample32x32 = nn.Upsample(size=(32, 32), mode='bilinear')

 
    def forward(self, x):	    	# x [3, 256, 256]
        
        x_input = x
        x = self.conv1(x)		   
        
        x_Block1 = self.Block1(x)	    	    	
        attention1 = self.sa1(x_Block1)
        x_Block1_SA = attention1 * x_Block1
        x_Block1_32x32 = self.downsample32x32(x_Block1_SA)   
        
        x_Block2 = self.Block2(x_Block1)	    
        attention2 = self.sa2(x_Block2)  
        x_Block2_SA = attention2 * x_Block2
        x_Block2_32x32 = self.downsample32x32(x_Block2_SA)  
        
        x_Block3 = self.Block3(x_Block2)	    
        attention3 = self.sa3(x_Block3)  
        x_Block3_SA = attention3 * x_Block3	
        x_Block3_32x32 = self.downsample32x32(x_Block3_SA)   
        
        x_concat = torch.cat((x_Block1_32x32,x_Block2_32x32,x_Block3_32x32), dim=1)    
        
        #pdb.set_trace()
        
        map_x = self.lastconv1(x_concat)
        
        map_x = map_x.squeeze(1)
        
        return map_x, x_concat, attention1, attention2, attention3, x_input
		

コードの各部分の説明は次のとおりです。

initメソッド: CDCNpp クラスを初期化します。このメソッドは、ネットワークのレイヤーとサブモジュールを作成します。

Basic_conv パラメータはカスタム畳み込み層で、デフォルトは Conv2d_cd です。
theta パラメーターは、カスタム畳み込み層に渡されるハイパーパラメーターです。
conv1: 畳み込み層、バッチ正規化 (BatchNorm2d) 層、および活性化関数 (ReLU) を含む畳み込み層シーケンスを定義します。

Block1、Block2、および Block3: 3 つの同様のサブネットワークが定義されており、各サブネットワークには複数の畳み込み層、バッチ正規化層、活性化関数、およびプーリング層が含まれています。

lastconv1: 3 つのサブネットワークの結果を処理するための一連の畳み込み層を定義します。

sa1、sa2、sa3: 3 つの空間注意モジュールが定義されています。

downsample32x32: フィーチャ マップのサイズを 32x32 に変更するアップサンプリング レイヤーを定義します。

forward メソッド: ネットワークの順方向伝播プロセスを定義します。

入力 x を conv1 層に渡します。
結果を Block1、Block2、および Block3 サブネットワークに渡します。
空間アテンション モジュールが各サブネットワークの出力に適用され、結果は 32x32 サイズにアップサンプリングされます。
3 つのサブネットワークの出力をチャネル次元に沿って連結します。
連結結果をlastconv1層に渡します。
最終出力テンソルを 1 つのチャネルに圧縮します。
forward メソッドは 6 つの出力を返します。

map_x: 最終的な深度推定マップ。
x_concat: スプライシング後の特徴マップ。
アテンション 1、アテンション 2、アテンション 3: 3 つのサブネットワークの空間アテンション モジュール出力。
x_input: 生の入力画像。

おすすめ

転載: blog.csdn.net/qq_51957239/article/details/129776820