首页 > 其他分享 >Datawhale AI 夏令营——CV图像竞赛(Deepfake攻防)——Task3学习笔记

Datawhale AI 夏令营——CV图像竞赛(Deepfake攻防)——Task3学习笔记

时间:2024-07-20 19:56:36浏览次数:15  
标签:__ img AI self Datawhale transforms mixed alpha CV

        这一篇是在 数据增强 的方向上发力,尝试提升模型的表现。

        数据增强的目的是通过人工方式增加训练数据的多样性,从而提高模型的泛化能力,使其能够在未见过的数据上表现得更好。对于图像而言,数据增强包括例如视角、光照、遮挡等情况,使得模型能够学习到更加鲁棒的特征表示。

        效果如下:

        数据增强的方式有很多:颜色变换、噪声、翻转、仿射变换、自动增强、图片混合 Mixup、图片裁剪 Cutmix 等。

        实际上,这些方法并不一定能有效提升训练效果,很有可能产生负面影响;同时,参数的值也需要不断调整。

        标记一下,初始代码的分数为 0.53,接下来进行各种尝试。

(1)随机旋转+随机裁剪+颜色抖动

# 定义增强变换
data_transforms = transforms.Compose([
    transforms.Resize((256, 256)),
    transforms.RandomHorizontalFlip(),
    transforms.RandomVerticalFlip(),
    # 增加的部分
    transforms.RandomRotation(30),  # 随机旋转角度
    transforms.RandomResizedCrop(256, scale=(0.8, 1.0)),  # 随机裁剪
    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),  # 颜色抖动
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

        可以看到,分数小有提升。

(2)调整参数

# 定义增强变换
data_transforms = transforms.Compose([
    transforms.Resize((256, 256)),
    transforms.RandomHorizontalFlip(),
    transforms.RandomVerticalFlip(),
    transforms.RandomRotation(15),      # 随机旋转 ±15 度
    transforms.RandomResizedCrop(256, scale=(0.8, 1.0)),  # 随机裁剪,裁剪比例 80% 到 100%
    transforms.ColorJitter(brightness=0.1, contrast=0.1, saturation=0.1, hue=0.05),  # 颜色抖动,变化幅度 10% 到 20%
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

        可以看到,效果反而下降,说明参数修改的不好。

(3)颜色变换

import torch
from torchvision import transforms
from PIL import ImageFilter

# 自定义模糊变换
class RandomBlur(object):
    def __init__(self, radius=1):
        self.radius = radius

    def __call__(self, img):
        return img.filter(ImageFilter.GaussianBlur(self.radius))

# 定义颜色变化增强变换
data_transforms = transforms.Compose([
    transforms.Resize((256, 256)),
    transforms.Grayscale(num_output_channels=3),  # 转换为灰度图像,并扩展到 3 通道
    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),  # 颜色抖动
    RandomBlur(radius=2),  # 应用随机模糊
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

        分数比原始还低,说明这种方案效果不好,或者参数选取不对。

(4)调整参数

data_transforms = transforms.Compose([
    transforms.Resize((256, 256)),
    transforms.Grayscale(num_output_channels=3),  # 转换为灰度图像,并扩展到 3 通道
    transforms.ColorJitter(
        brightness=0.1,  # 亮度变化范围 10%
        contrast=0.1,    # 对比度变化范围 10%
        saturation=0.1,  # 饱和度变化范围 10%
        hue=0.05         # 色调变化范围 5%
    ),
    RandomBlur(radius=1),  # 应用模糊,半径为 1
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

        分数又有所回升,说明这种方案还是有效的,只不过参数需要调整得当。 

(5)自动增强

from torchvision import transforms

# 定义自动增强变换
data_transforms = transforms.Compose([
    transforms.Resize((256, 256)),
    transforms.RandomHorizontalFlip(),
    transforms.RandomVerticalFlip(),
    transforms.AutoAugment(transforms.AutoAugmentPolicy.CIFAR10),  # 使用 CIFAR10 的自动增强策略
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

        使用的是 CIFAR10 的自动增强,确实有提升,但是效果真的一般,不如增强变换。

今日达到上限,明天再提交吧。

(6)混合增强,也就是将前面的增强都用上

from torchvision import transforms

# 自定义模糊变换
class RandomBlur(object):
    def __init__(self, radius=1):
        self.radius = radius

    def __call__(self, img):
        return img.filter(ImageFilter.GaussianBlur(self.radius))

# AugMix 数据增强
class AugMix(object):
    def __init__(self, alpha=1.0, num_ops=3):
        self.alpha = alpha
        self.num_ops = num_ops
        self.operations = [
            transforms.ColorJitter(brightness=0.1, contrast=0.1, saturation=0.1, hue=0.05),
            transforms.RandomRotation(degrees=30),
            transforms.RandomHorizontalFlip(),
            transforms.RandomVerticalFlip(),
            transforms.RandomAffine(degrees=0, translate=(0.1, 0.1)),
            transforms.RandomResizedCrop(size=256, scale=(0.8, 1.0)),
            RandomBlur(radius=1)
        ]

    def __call__(self, img):
        img = Image.fromarray(np.array(img))
        mixed_img = img.copy()
        
        for _ in range(self.num_ops):
            op = np.random.choice(self.operations)
            augmented_img = op(img)
            if np.random.rand() < 0.5:
                mixed_img = Image.blend(mixed_img, augmented_img, alpha=self.alpha)
            else:
                mixed_img = Image.blend(mixed_img, augmented_img, alpha=1 - self.alpha)
                
        return mixed_img

# 定义变换和 AugMix 增强
data_transforms = transforms.Compose([
    transforms.Resize((256, 256)),
    AugMix(alpha=0.5, num_ops=3),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

(7)使用 Mixup,就是将两个不同的图像及其标签按照一定的比例混合,从而创建一个新的训练样本

from torchvision import transforms

# 定义 MixUp 数据增强
class MixUp(object):
    def __init__(self, alpha=0.4):
        self.alpha = alpha

    def __call__(self, img1, img2, label1, label2):
        # 混合比例
        lambda_ = np.random.beta(self.alpha, self.alpha)
        # 图像混合
        mixed_img = lambda_ * img1 + (1 - lambda_) * img2
        # 标签混合
        mixed_label = lambda_ * label1 + (1 - lambda_) * label2
        
        return mixed_img, mixed_label


# 自定义数据加载器,应用 MixUp
class MixUpDataLoader(DataLoader):
    def __init__(self, dataset, batch_size=32, shuffle=True, num_workers=4, pin_memory=True, alpha=0.4):
        super().__init__(dataset, batch_size=batch_size, shuffle=shuffle, num_workers=num_workers, pin_memory=pin_memory)
        self.mixup = MixUp(alpha=alpha)
    
    def __iter__(self):
        for batch in super().__iter__():
            images, targets = batch
            
            # 如果batch中的图像数量大于1
            if len(images) > 1:
                batch_size = len(images)
                mixed_images = torch.zeros_like(images)
                mixed_targets = torch.zeros_like(targets)

                for i in range(batch_size):
                    img1, label1 = images[i], targets[i]
                    img2, label2 = images[(i + 1) % batch_size], targets[(i + 1) % batch_size]
                    mixed_img, mixed_label = self.mixup(img1, img2, label1, label2)
                    mixed_images[i] = mixed_img
                    mixed_targets[i] = mixed_label

                yield mixed_images, mixed_targets
            else:
                yield images, targets

# 定义变换
data_transforms = 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])
])

(8)使用 Cutmix,就是将一个图像的一部分剪切并粘贴到另一个图像上来创建新的训练样本

import torch
import numpy as np
from torchvision import transforms

# 定义 CutMix 数据增强
class CutMix(object):
    def __init__(self, alpha=1.0):
        self.alpha = alpha

    def __call__(self, img1, img2, label1, label2):
        # 混合比例
        lambda_ = np.random.beta(self.alpha, self.alpha)
        
        # 图像大小
        w, h = img1.size
        
        # 随机选择裁剪区域的大小和位置
        cutout_width = int(w * np.sqrt(1 - lambda_))
        cutout_height = int(h * np.sqrt(1 - lambda_))
        x = np.random.randint(0, w - cutout_width)
        y = np.random.randint(0, h - cutout_height)
        
        # 创建裁剪区域
        cutout = img2.crop((x, y, x + cutout_width, y + cutout_height))
        
        # 将裁剪区域应用到 img1
        mixed_img = img1.copy()
        mixed_img.paste(cutout, (x, y))
        
        # 标签混合
        mixed_label = lambda_ * label1 + (1 - lambda_) * label2
        
        return mixed_img, mixed_label


# 自定义数据加载器,应用 CutMix
class CutMixDataLoader(DataLoader):
    def __init__(self, dataset, batch_size=32, shuffle=True, num_workers=4, pin_memory=True, alpha=1.0):
        super().__init__(dataset, batch_size=batch_size, shuffle=shuffle, num_workers=num_workers, pin_memory=pin_memory)
        self.cutmix = CutMix(alpha=alpha)
    
    def __iter__(self):
        for batch in super().__iter__():
            images, targets = batch
            
            # 如果batch中的图像数量大于1
            if len(images) > 1:
                batch_size = len(images)
                mixed_images = torch.zeros_like(images)
                mixed_targets = torch.zeros_like(targets)

                for i in range(batch_size):
                    img1, label1 = images[i], targets[i]
                    img2, label2 = images[(i + 1) % batch_size], targets[(i + 1) % batch_size]
                    mixed_img, mixed_label = self.cutmix(img1, img2, label1, label2)
                    mixed_images[i] = transforms.ToTensor()(mixed_img)
                    mixed_targets[i] = mixed_label

                yield mixed_images, mixed_targets
            else:
                yield images, targets

# 定义变换
data_transforms = 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])
])

        代码中已附加注释,不再赘述。

        很容易发现,这种增强带来的不一定是正向收益,而且也不是混合得越多越好,这需要我们不断地去尝试,去试错。这篇文章就没有介绍不同的数据增强代表的含义,是因为确实简单,看看开头的那张图就能很容易理解。

        其他优化方案比如改进模型,调整训练轮数等等都在上一篇文章中,本篇就是介绍实践过程与结果。

感谢九月大佬的直播讲解,以及源码展示:https://www.kaggle.com/code/chg0901/deepfake-ffdi-ch3-modified-by-hong

上一篇链接:Datawhale AI 夏令营——CV图像竞赛(Deepfake攻防)——Task2学习笔记-CSDN博客

标签:__,img,AI,self,Datawhale,transforms,mixed,alpha,CV
From: https://blog.csdn.net/m0_63566347/article/details/140574840

相关文章

  • Datawhale Al夏令营——Transformer架构
    Transformer:这个模型架构就是摒弃了所有的循环结构,完全依赖于注意力机制对源语言序列和目标语言序列全局依赖的建模对于循环神经网络来说,上下文的语义依赖是通过维护循环单元中的隐状态实现的。在编码过程中,每一个时间步的输入建模都涉及到对隐藏状态的修改。随着序列长度的增加,......
  • Windows下使用QT+OpenCV完成人脸检测(获取摄像头数据进行检测)
    鱼弦:公众号【红尘灯塔】,CSDN博客专家、内容合伙人、新星导师、全栈领域优质创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)Windows下使用QT+OpenCV完成人脸检测(获取摄像头数据进行检测)1.简介本文......
  • DatawhaleAI夏令营 机器学习方向 学习笔记
    电力需求预测挑战赛理解赛题【训练时序预测模型助力电力需求预测赛题任务给定多个房屋对应电力消耗历史N天的相关序列数据等信息,预测房屋对应电力的消耗。赛题数据赛题数据由训练集和测试集组成,为了保证比赛的公平性,将每日日期进行脱敏,用1-N进行标识。即1为数据集最近一天,......
  • TASK 3 Datawhale AI 夏令营
    \(transformer\)解决任务1.特点摒弃了循环结构,通过自注意力机制衡量上下文单词的重要程度说人话就是联系前后单词对于该单词的影响来完成本单词的翻译2.运行逻辑在运行前,由于摒弃了循环结构,我们需要在词语中嵌入位置编码来构建单词的向量表示,模型利用每个词语的位置与维度构......
  • Society-Links-Taiwan朋友们的链接列表
    王彦仁https://wangyenjen.github.io/部落格,簡報名稱網址經歷侯欣緯競程筆記部落格2022國手賴昭勳slides入營考比賽策略2022國手吳柏燁部落格CSESsolution20222!李政遠部落格wikiNHDK講師UMDCS李旺陽slides20152!王淇部落格202......
  • 【HZHY-AI300G智能盒试用连载体验】安装Neuron工业协议网关软件
    目录下载和安装软件运行本文首发于:【HZHY-AI300G智能盒试用连载体验】+智能工业互联网网关-北京合众恒跃科技有限公司-电子技术论坛-广受欢迎的专业电子论坛!为了能够将RS485等接口设备转换为MQTT设备,我使用了Neuron工业协议网关软件。Neuron是EMQ(杭州映云科技有......
  • OpenAI突发新模型GPT-4o mini,GPT-3.5退役!
    OpenAI突发新模型,全面取代老去的GPT-3.5——GPT-4omini!免费用户已可使用GPT-4omini模型。GPT-4omini,能力接近原版GPT-4,价格却要便宜一个数量级:GPT-4omini:每百万输入tokens,15美分(约1.09元人民币)GPT3.5:每百万输出tokens,60美分(约4.36元人民币)对应的API也已经开......
  • 吴恩达新书《How to build a career in AI》书摘
    Threekeystepsofcareergrowtharelearningfoundationalskills,workingonprojectsandfindingajob.Asyougothrougheachstep,youshouldalsobuildasupportivecommunity.Havingfriendsandallieswhocanhelpyou-andwhoyoustrivetohelp-......
  • 联通为工业及制造业提供AI与信息技术结合的一站式通信解决方案
    联通智慧智能制造解决方案:引领工业革命新篇章在第四次工业革命的浪潮中,人工智能(AI)、物联网(IoT)和大数据等前沿技术正以前所未有的速度改变着制造业的面貌。中国联通,作为国内领先的综合信息服务提供商,深刻理解这一行业变革的核心需求,精心打造了联通智慧智能制造解决方案,旨在通过AI......
  • 用AirScript脚本给女/男朋友发送每日早安邮件(极简版本)
     先看效果 工具金山文档/WPS提供了每日定时的AirScript脚本服务,非常方便~ 话不多说,我们以金山文档为例,只有简单的五个步骤,非常容易~教程开始步骤1我们打开金山文档新建一个智能表格步骤2按下图填写,注意是ABC这三列是否开启邮箱地址是否发送提醒是你的目的邮箱......