记第一次使用baseline#AI夏令营 #Datawhale

156 阅读4分钟

Deepfake是什么?

Deepfake是一种使用人工智能技术生成的伪造媒体,特别是视频和音频,它们看起来或听起来非常真实,但实际上是由计算机生成的。这种技术通常涉及到深度学习算法,特别是生成对抗网络(GANs),它们能够学习真实数据的特征,并生成新的、逼真的数据。

Deepfake技术虽然在多个领域展现出其创新潜力,但其滥用也带来了一系列严重的危害。在政治领域,Deepfake可能被用来制造假新闻或操纵舆论,影响选举结果和政治稳定。经济上,它可能破坏企业形象,引发市场恐慌,甚至操纵股市。法律体系也面临挑战,因为伪造的证据可能误导司法判断。此外,深度伪造技术还可能加剧身份盗窃的风险,成为恐怖分子的新工具,煽动暴力和社会动荡,威胁国家安全。

深度伪造技术通常可以分为四个主流研究方向:

  • 面部交换专注于在两个人的图像之间执行身份交换;
  • 面部重演强调转移源运动和姿态;
  • 说话面部生成专注于在角色生成中实现口型与文本内容的自然匹配;
  • 面部属性编辑旨在修改目标图像的特定面部属性;

baseline中的语言:

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) + ']'

理解

AverageMeter 类

这个类用于计算并存储一个变量的平均值和当前值。它包含以下方法和属性: init(self, name, fmt=':f'): 构造函数接受一个名字(name)和一个格式化字符串(fmt),默认格式为浮点数。 reset(self): 重置所有内部状态,包括当前值(val)、平均值(avg)、总和(sum)和计数(count)。 update(self, val, n=1): 更新内部状态。val 是要更新的值,n 是更新的次数(默认为1)。这个方法会更新当前值、总和和计数,并重新计算平均值。 str(self): 返回对象的字符串表示,格式为“名字 当前值(平均值)”。

ProgressMeter 类

这个类用于显示训练进度,包括当前批次和一系列AverageMeter对象的值。它包含以下方法和属性: init(self, num_batches, *meters): 构造函数接受总批次数(num_batches)和一个或多个AverageMeter对象作为参数。 pr2int(self, batch): 显示当前批次的进度和所有AverageMeter对象的值。batch是当前批次的索引。 _get_batch_fmtstr(self, num_batches): 一个私有方法,用于生成显示批次的格式化字符串。它根据总批次数来确定批次索引的宽度。

    FFDIDataset(train_label['path'].head(1000), train_label['target'].head(1000), 
            transforms.Compose([
                        transforms.Resize((256, 256)),
                        transforms.RandomHorizontalFlip(),
                        transforms.RandomVerticalFlip(),
                        transforms.ToTensor(),
                        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ])
    ), batch_size=40, shuffle=True, num_workers=4, pin_memory=True
)

val_loader = torch.utils.data.DataLoader(
    FFDIDataset(val_label['path'].head(1000), val_label['target'].head(1000), 
            transforms.Compose([
                        transforms.Resize((256, 256)),
                        transforms.ToTensor(),
                        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ])
    ), batch_size=40, shuffle=False, num_workers=4, pin_memory=True
)

criterion = nn.CrossEntropyLoss().cuda()
optimizer = torch.optim.Adam(model.parameters(), 0.005)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=4, gamma=0.85)
best_acc = 0.0
for epoch in range(2):
    scheduler.step()
    print('Epoch: ', epoch)

    train(train_loader, model, criterion, optimizer, epoch)
    val_acc = validate(val_loader, model, criterion)
    
    if val_acc.avg.item() > best_acc:
        best_acc = round(val_acc.avg.item(), 2)
        torch.save(model.state_dict(), f'./model_{best_acc}.pt')

数据加载:

train_loader 和 val_loader 分别用于加载训练和验证数据。 FFDIDataset 是一个自定义的数据集类,它接受图像路径、标签和一系列转换(transforms)作为输入。 对于训练数据,应用了随机水平翻转和随机垂直翻转来增强数据。 对于训练和验证数据,都应用了大小调整(Resize)、转换为张量(ToTensor)和标准化(Normalize)操作。 模型、损失函数和优化器:model 是要训练的模型,尽管代码中没有给出模型的定义。 criterion 是损失函数,这里使用的是交叉熵损失(CrossEntropyLoss),适用于多分类问题。 optimizer 是优化器,这里使用的是Adam优化器,学习率设置为0.005。 scheduler 是学习率调度器,用于在训练过程中调整学习率,这里使用的是步长调度器(StepLR),每4个epoch学习率乘以0.85。

训练和验证:

代码通过两个循环进行训练和验证。 在每个epoch开始时,首先调用scheduler.step()更新学习率。 train 函数用于训练模型,它接受训练数据加载器、模型、损失函数、优化器和当前epoch作为输入。 validate 函数用于验证模型,它接受验证数据加载器、模型和损失函数作为输入,并返回验证准确率。

模型保存:

如果当前验证准确率高于之前的最佳准确率,则更新最佳准确率,并保存当前模型的参数。 模型参数保存为.pt文件,文件名包含当前的最佳准确率。