コンペティション背景
グローバルDeepfake攻防チャレンジは、人工知能時代におけるデジタルセキュリティの課題に取り組む重要な競技です。近年、ディープラーニング技術の急速な進歩に伴い、Deepfake(ディープフェイク)技術は目覚ましい発展を遂げ、非常にリアルな偽の画像、動画、音声コンテンツを生成できるようになりました。この技術の進歩はクリエイティブなコンテンツ制作に新たな可能性をもたらす一方で、情報の信頼性、個人のプライバシー、そして公共の安全に対する前例のない脅威をもたらしています。
このような背景から、本チャレンジはDeepfake検出技術の開発と最適化に焦点を当てています。参加者は、様々なタイプのDeepfakeコンテンツを効果的に識別できるアルゴリズムモデルを設計・実装する必要があります。主な目標は以下の通りです。
- 不断に進化する偽造技術に対応し、Deepfake検出の精度とロバスト性を向上させる。
- 実際のシナリオで迅速かつ効率的に動作する検出モデルを開発する。
- 新しい検出方法や技術を探求し、Deepfake防御分野の革新を推進する。
- Deepfake技術の潜在的なリスクに対する公衆の認識を高め、責任あるAIの発展を促進する。
ベースラインアルゴリズム
- データ処理:
- カスタムのFFDIDatasetクラスを使用してデータをロードします。
- 画像に対して基本的な前処理を行い、224x224にリサイズし、ランダムな水平・垂直反転、および標準化を適用します。
- コードは、トレーニングセットと検証セットの最初の1000サンプルのみを使用しています(.head(1000))。これは、迅速な検証やデバッグのために使用された可能性があります。
- モデル選択:
- 事前学習済みのresnet18を使用します。
- 損失関数:
- 分類タスクの標準的な選択である交差エントロピー損失(nn.CrossEntropyLoss)を使用します。
- 最適化アルゴリズム:
- Adam最適化アルゴリズムを採用し、初期学習率を0.005に設定します。
- 学習率スケジューラ:
- StepLRスケジューラを使用し、4エポックごとに学習率を0.85倍にします。
- トレーニングプロセス:
- トレーニングループは10エポックに設定されています。
- 各エポックの終了後に、検証セットでモデルのパフォーマンスを評価します。
- 現在のモデルが検証セットでの精度がこれまでの最高記録を上回った場合、モデルの重みを保存します。
- データロード:
- トレーニングセットにはバッチサイズ40、検証セットには16を使用します。
- データロードを高速化するために、両方とも4つのワーカースレッド(num_workers=4)とメモリロック(pin_memory=True)を設定しています。
- モデル評価:
- validate関数を使用して、モデルの検証セットにおけるパフォーマンスを評価します。
この初期バージョンは、データロード、モデルトレーニング、検証、および最良のモデルの保存を含む完全なトレーニングフローを提供します。データ拡張、学習率スケジューリング、モデルチェックポイントなどの基本的なディープラーニングのベストプラクティスが採用されています。
改善の試み
- データセットの利用:
- 1000サンプルのみのサブセットを使用するのではなく、完全なトレーニングセットと検証セットを使用するように拡張しました。これにより、モデルの学習リソースが大幅に増加しました。
- モデルアーキテクチャ:
- より強力なEfficientNet-B5モデルにアップグレードしました。これにより、より強力な特徴抽出能力が得られます。
# 変更後のコード neural_network = timm.create_model('efficientnet_b5', pretrained=True, num_classes=2) - 画像前処理とデータ拡張:
- 画像サイズを224x224から384x384(EfficientNet-B5に最適化)に増やしました。
- ランダムな回転、色のジッター、ランダムな消去などのより多くのデータ拡張技術を追加しました。これにより、モデルの汎化能力が向上します。
# 変更後のコード data_transforms = transforms.Compose([ transforms.Resize((384, 384)), transforms.RandomHorizontalFlip(), transforms.RandomVerticalFlip(), transforms.RandomRotation(15), transforms.ColorJitter(brightness=0.1, contrast=0.1, saturation=0.1, hue=0.1), transforms.RandomErasing(p=0.2), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) - 損失関数:
- 標準的な交差エントロピー損失関数からFocal Lossに変更しました。これにより、クラスの不均衡問題を解決し、モデルが難しいサンプルにさらに焦点を当てやすくなります。
# 変更後のコード class FocalLoss(nn.Module): def forward(self, inputs, targets): ce_loss = F.cross_entropy(inputs, targets, reduction='none') pt = torch.exp(-ce_loss) focal_loss = self.alpha * (1 - pt) ** self.gamma * ce_loss return focal_loss.mean() - 最適化アルゴリズム:
- Adam最適化アルゴリズムからAdamWに切り替えました。これは重み減衰を追加し、過学習を減らすのに役立ちます。
- より大きなモデルに適応するために、より小さい初期学習率(0.0001)を使用しました。
# 変更後のコード optimizer_instance = torch.optim.AdamW(neural_network.parameters(), lr=0.0001, weight_decay=1e-5) - 学習率スケジューラ:
- StepLRからCosineAnnealingLRに変更しました。これにより、より滑らかな学習率減衰カーブが提供されます。
# 変更後のコード scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer_instance, T_max=20) - トレーニング戦略:
-
li>トレーニングのエポック数を10から20に増やし、モデルにさらに学習の時間を与えました。
- バッチサイズの調整:
- モデルのサイズとメモリ制限に応じて、バッチサイズを適切に調整しました。
# 変更後のコード train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True, num_workers=4, pin_memory=True) - 検証とテスト戦略:
- テスト段階でテスト時拡張(TTA)を導入しました。複数回の予測の平均を取ることで、予測の安定性と精度を向上させます。
# 変更後のコード tta_times = 5 for _ in range(tta_times): outputs = neural_network(inputs) batch_predictions.append(torch.softmax(outputs, dim=1)[:, 1].cpu().numpy()) final_predictions = np.mean(batch_predictions, axis=0) - メモリ最適化:
- バッチサイズの調整や混合精度トレーニングの使用など、GPUメモリの使用を最適化し、より大きなモデルをトレーニングできるようにしました。
# 変更後のコード scaler = GradScaler() with autocast(): outputs = neural_network(inputs) loss = criterion(outputs, targets) scaler.scale(loss).backward() scaler.step(optimizer_instance) scaler.update()