成绩打卡
1. BaseLine相关
1.1 Deepfake是什么?
Deepfake是一种使用人工智能技术生成的伪造媒体,特别是视频和音频,它们看起来或听起来非常真实,但实际上是由计算机生成的。这种技术通常涉及到深度学习算法,特别是生成对抗网络(GANs),它们能够学习真实数据的特征,并生成新的、逼真的数据。
Deepfake技术虽然在多个领域展现出其创新潜力,但其滥用也带来了一系列严重的危害。在政治领域,Deepfake可能被用来制造假新闻或操纵舆论,影响选举结果和政治稳定。经济上,它可能破坏企业形象,引发市场恐慌,甚至操纵股市。法律体系也面临挑战,因为伪造的证据可能误导司法判断。此外,深度伪造技术还可能加剧身份盗窃的风险,成为恐怖分子的新工具,煽动暴力和社会动荡,威胁国家安全。
深度伪造技术通常可以分为四个主流研究方向:
- 面部交换专注于在两个人的图像之间执行身份交换;
- 面部重演强调转移源运动和姿态;
- 说话面部生成专注于在角色生成中实现口型与文本内容的自然匹配;
- 面部属性编辑旨在修改目标图像的特定面部属性;
1. 2 BaseLine代码解析
1.2.1 工具类
class AverageMeter(object):
"""Computes and stores the average and current value"""
def __init__(self, name, fmt=':f'):
self.name = name
self.fmt = fmt
self.reset()
def reset(self):
self.val = 0
self.avg = 0
self.sum = 0
self.count = 0
def update(self, val, n=1):
self.val = val
self.sum += val * n
self.count += n
self.avg = self.sum / self.count
def __str__(self):
fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'
return fmtstr.format(**self.__dict__)
class ProgressMeter(object):
def __init__(self, num_batches, *meters):
self.batch_fmtstr = self._get_batch_fmtstr(num_batches)
self.meters = meters
self.prefix = ""
def pr2int(self, batch):
entries = [self.prefix + self.batch_fmtstr.format(batch)]
entries += [str(meter) for meter in self.meters]
print('\t'.join(entries))
def _get_batch_fmtstr(self, num_batches):
num_digits = len(str(num_batches // 1))
fmt = '{:' + str(num_digits) + 'd}'
return '[' + fmt + '/' + fmt.format(num_batches) + ']'
假设在训练一个深度学习模型时,我们想要记录损失值和准确率,并在每个批次结束后打印这些统计数据,可以使用这两个类:
loss_meter = AverageMeter('Loss')
acc_meter = AverageMeter('Accuracy')
progress = ProgressMeter(total_batches, loss_meter, acc_meter)
for batch in range(total_batches):
# 假设 val_loss 和 val_accuracy 是当前批次的损失值和准确率
loss_meter.update(val_loss)
acc_meter.update(val_accuracy)
# 打印当前批次的进度和统计数据
progress.pr2int(batch)
# 这样,每个批次结束后,会打印当前批次号及其对应的损失值和准确率,包括当前值和平均值。
1.2.2 模型过程函数
- 训练
- 初始化记录时间、损失和准确率的
AverageMeter
实例。 - 切换模型到训练模式
model.train()
。 - 迭代训练数据集。
- 对每个批次:- 将输入和目标移到 GPU 上。- 计算模型输出和损失。- 计算并记录准确率和损失。- 计算梯度并执行优化步骤(SGD)。- 更新批处理时间。
- 每 100 个批次打印一次进度和统计数据。
def train(train_loader, model, criterion, optimizer, epoch):batch_time = AverageMeter('Time', ':6.3f')losses = AverageMeter('Loss', ':.4e')top1 = AverageMeter('Acc@1', ':6.2f')progress = ProgressMeter(len(train_loader), batch_time, losses, top1)# switch to train modemodel.train()end = time.time()for i, (input, target) in enumerate(train_loader): input = input.cuda(non_blocking=True) target = target.cuda(non_blocking=True) # compute output output = model(input) loss = criterion(output, target) # measure accuracy and record loss losses.update(loss.item(), input.size(0)) acc = (output.argmax(1).view(-1) == target.float().view(-1)).float().mean() * 100 top1.update(acc, input.size(0)) # compute gradient and do SGD step optimizer.zero_grad() loss.backward() optimizer.step() # measure elapsed time batch_time.update(time.time() - end) end = time.time() if i % 100 == 0: progress.pr2int(i)
- 切换模型到评估模式
model.eval()
。
- 验证: 1. 初始化记录时间、损失和准确率的
AverageMeter
实例。2. 切换模型到评估模式model.eval()
。3. 在不计算梯度的上下文中,迭代验证数据集。4. 对每个批次: - 将输入和目标移到 GPU 上。- 计算模型输出和损失。- 计算并记录准确率和损失。- 更新批处理时间。5. 打印最终的平均准确率。 - 评估:
- 初始化
test_pred_tta
用于存储 TTA 结果。 - 进行多次(
tta
次)预测,每次预测: - 在不计算梯度的上下文中,迭代测试数据集。- 对每个批次: - 将输入和目标移到 GPU 上。- 计算模型输出并应用 softmax。- 将输出移到 CPU 并存储在列表中。- 将预测结果堆叠成一个数组,并累加到test_pred_tta
中。 - 返回累加后的 TTA 结果。
1.2.3 类加载函数
FFDIDataset
类是一个自定义的数据集类,用于加载图像及其对应的标签,并提供可选的图像预处理功能,以便与 PyTorch 的
DataLoader
结合使用,实现批量数据的高效加载和处理。
class FFDIDataset(Dataset):
def __init__(self, img_path, img_label, transform=None):
self.img_path = img_path
self.img_label = img_label
if transform is not None:
self.transform = transform
else:
self.transform = None
def __getitem__(self, index):
img = Image.open(self.img_path[index]).convert('RGB')
if self.transform is not None:
img = self.transform(img)
return img, torch.from_numpy(np.array(self.img_label[index]))
def __len__(self):
return len(self.img_path)
1.2.4 过程函数
以下代码主要实现了训练和验证流程,其中包括数据加载、模型定义、训练。
首先,代码定义了用于训练和验证的数据加载器 (
train_loader
和
val_loader
)。
- 使用
FFDIDataset
类加载训练数据。 - 数据经过一系列变换:调整大小、随机水平和垂直翻转、转换为张量以及归一化。
batch_size
设置为 40,数据会被打乱 (shuffle=True
),并使用 12 个工作进程 (num_workers=12
) 加载数据,同时启用内存锁页功能 (pin_memory=True
) 以加速数据传输到 GPU。
model = timm.create_model('resnet50', pretrained=True, num_classes=2) model = model.cuda()
- 使用
timm
库创建一个预训练的ResNet-50
模型,并将其分类输出层设置为 2 个类别。 - 将模型移动到 GPU 上。
1.2.5 损失函数和优化器
criterion = nn.CrossEntropyLoss().cuda() optimizer = torch.optim.Adam(model.parameters(), 0.003) scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=4, gamma=0.85)
- 定义交叉熵损失函数并移动到 GPU。
- 使用 Adam 优化器,学习率为 0.003。
- 学习率调度器每 4 个周期降低一次学习率,衰减系数为 0.85。
1.2.6 保存结果
这段代码的主要功能是生成验证数据集的预测结果,并将这些预测结果与提交文件进行合并,最后保存为新的提交文件。下面是对每个部分的详细分析:
生成验证集预测
val_pred = predict(val_loader, model,1)[:,1]
val_label["y_pred"]= val_pred
- 调用
predict
函数对验证集数据进行预测,predict
函数的tta
参数设为 1,表示只进行一次预测。 - 预测结果
val_pred
是一个二维数组,取第二列的值(假设这是模型输出的某个类别的概率)。 - 将预测结果添加到
val_label
数据框中,创建新列y_pred
。
合并预测结果与提交文件
submit = pd.read_csv("/kaggle/input/multi-ffdv/prediction.txt.csv")
merged_df = submit.merge(val_label[['video_name','y_pred']], on='video_name', suffixes=('','_df2'), how='left',)
- 读取提交文件
prediction.txt.csv
,存储在submit
数据框中。 - 将
submit
数据框与val_label
数据框的video_name
列进行合并,合并方式为左连接 (how='left'
),这样可以确保所有submit
中的video_name
都保留。 - 合并后,如果
video_name
存在于val_label
中,则会包含y_pred
列的值,并在结果数据框中命名为y_pred_df2
。
填充缺失的预测值
merged_df['y_pred']= merged_df['y_pred_df2'].combine_first(merged_df['y_pred'])
- 使用
combine_first
方法,将y_pred_df2
列中的非缺失值填充到y_pred
列中。这样,如果y_pred_df2
中有值,则使用该值;否则保留原始的y_pred
列中的值。
保存结果
merged_df[['video_name','y_pred']].to_csv('submit.csv', index=None)
- 选择
merged_df
数据框中的video_name
和y_pred
列,保存为新的 CSV 文件submit.csv
,不包含索引。 - 通过
predict
函数生成验证集的预测结果,并添加到val_label
数据框中。 - 将这些预测结果与提交文件合并,确保所有视频名称都包含在结果中。
- 填充缺失的预测值,并将最终结果保存为新的提交文件
submit.csv
。
版权归原作者 琦奇说 所有, 如有侵权,请联系我们删除。