从零入门CV图像竞赛Deepfake攻防
比赛背景
全球Deepfake攻防挑战赛是一项旨在应对人工智能时代数字安全挑战的重要竞赛。随着深度学习技术的快速发展,Deepfake(深度伪造)技术在近年来取得了显著进步,能够生成高度逼真的虚假图像、视频和音频内容。这种技术的进步不仅为创意内容制作带来了新的可能性,同时也对信息真实性、个人隐私和公共安全构成了前所未有的威胁。
在这样的背景下,本次挑战赛聚焦于Deepfake检测技术的开发和优化。参赛者需要设计和实现能够有效识别各种类型Deepfake内容的算法模型。比赛的主要目标包括:
- 提高Deepfake检测的准确性和鲁棒性,以应对不断evolving的伪造技术。
- 开发能够在实际场景中快速、高效运行的检测模型。
- 探索新的检测方法和技术,推动Deepfake防御领域的创新。
- 提高对Deepfake技术潜在风险的公众意识,促进responsible AI的发展。
baseline的算法
-
数据处理:
- 使用了自定义的FFDIDataset类来加载数据。
- 对图像进行了基本的预处理,包括调整大小到224x224,随机水平和垂直翻转,以及标准化。
- 值得注意的是,代码只使用了训练集和验证集的前1000个样本(通过.head(1000)),这可能是为了快速验证或调试。
-
模型选择:
- 使用了预训练的resnet18。
-
损失函数:
- 使用了交叉熵损失(nn.CrossEntropyLoss),这是分类任务的标准选择。
-
优化器:
- 采用了Adam优化器,初始学习率设置为0.005。
-
学习率调度:
- 使用了StepLR调度器,每4个epoch将学习率乘以0.85。
-
训练过程:
- 训练循环设置为10个epoch。
- 在每个epoch结束后,都会在验证集上评估模型性能。
- 如果当前模型在验证集上的准确率超过了之前的最佳记录,就保存模型权重。
-
数据加载:
- 训练集使用了batch size为40,而验证集使用了16。
- 都设置了4个工作线程(num_workers=4)和内存锁定(pin_memory=True)来加速数据加载。
-
模型评估:
- 使用了单独的validate函数来评估模型在验证集上的性能。
这个初始版本提供了一个完整的训练流程,包括数据加载、模型训练、验证和保存最佳模型。它采用了一些基本的深度学习最佳实践,如数据增强、学习率调度和模型检查点。
尝试改进
-
数据集使用:
- 从仅使用1000个样本的子集扩展到使用完整的训练和验证数据集,这大大增加了模型的学习资源。
-
模型架构:
- 升级到更强大的EfficientNet-B5模型,相比初始可能使用的较小模型,这提供了更强的特征提取能力。
model = timm.create_model('efficientnet_b5', pretrained=True, num_classes=2)
-
图像预处理和数据增强:
- 增加了图像尺寸,从224x224提升到384x384(针对EfficientNet-B5优化)。
- 添加了更多的数据增强技术,如随机旋转、颜色抖动、随机擦除等,这有助于提高模型的泛化能力。
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) F_loss = self.alpha * (1-pt)**self.gamma * CE_loss return F_loss.mean()
-
优化器:
- 从Adam优化器切换到AdamW,后者增加了权重衰减,有助于减少过拟合。
- 调整了学习率,使用了较小的初始学习率(0.0001)以适应更大的模型。
optimizer = torch.optim.AdamW(model.parameters(), lr=0.0001, weight_decay=1e-5)
-
学习率调度:
- 从StepLR改为CosineAnnealingLR,这提供了更平滑的学习率衰减曲线。
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=20)
-
训练策略:
- 增加了训练的epoch数量从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 = model(inputs) batch_preds.append(torch.softmax(outputs, dim=1)[:, 1].cpu().numpy()) predictions = np.mean(batch_preds, axis=0)
-
内存优化:
- 通过调整批量大小、使用混合精度训练等方法来优化GPU内存使用,使得能够训练更大的模型。
scaler = GradScaler() with autocast(): outputs = model(inputs) loss = criterion(outputs, targets) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()
运行结果
感觉要训练很长时间,不知道明天能不能出来。