Coggle 30 Days of ML 打卡任务二:苹果病害数据加载与数据增强

news2024/11/20 1:33:41

Coggle 30 Days of ML 打卡任务二:苹果病害数据加载与数据增强

任务二:苹果病害数据加载与数据增强

  • 难度/分值:中/2

打卡内容:

  1. 参赛选手名称:AppleDoctor
  2. 完成日期:2023.6.9
  3. 任务完成情况
    • 使用的编程语言:Python,Pytorch
    • 实现的功能:
      • 使用OpenCV或者PIL加载数据集
      • 使用torchvision或者OpenCV实现图像分类任务的数据增强

背景介绍

本次打卡任务是 Coggle 30 Days of ML 中的第二项任务,要求完成苹果病害数据加载与数据增强。数据加载阶段,参赛选手需要编写代码来读取和处理提供的图像数据。数据增强阶段,选手可以使用各种图像处理技术和方法,如旋转、缩放、翻转、亮度调整等,来增强数据集的多样性和数量。

任务名称难度/分值
任务1:两个赛题数据可视化低/1
任务2:苹果病害数据加载与数据增强中/2
任务3:苹果病害模型训练与预测中/2
任务4:苹果病害模型优化与多折训练高/3
任务5:建筑物检测数据加载与数据增强高/2
任务6:建筑物检测模型训练与预测中/2
任务7:建筑物检测模型优化与多折训练高/3

数据集准备

首先报名并下载数据集,以下是实践比赛地址:

  • 赛题1:苹果病害图像识别
  • 赛题2:建筑物变化检测

自定义数据集

首先,使用PyTorch作为示例,需要自定义数据集。为此,我定义了一个名为AppleDataset的类。

# 定义Apple数据集的类
class AppleDataset(Dataset):
    def __init__(self, img_path, transform=None):
        """
        构造函数,初始化数据集的路径和数据增强操作
        Args:
            - img_path: list类型,存储数据集中图像的路径
            - transform: torchvision.transforms类型,数据增强操作
        """
        self.img_path = img_path
        self.transform = transform
            
    def __getitem__(self, index):
        """
        获取一个样本
        Args:
            - index: 数据集中的索引
        Returns:
            - img: Tensor类型,经过处理后的图像
            - label: Tensor类型,标签
        """
        img = Image.open(self.img_path[index])
        if self.transform is not None:
            img = self.transform(img)

        # 将类别名转换为数字标签
        class_name = self.img_path[index].split('/')[-2]
        if class_name in ['d1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9']:
            label = ['d1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9'].index(class_name)
        else:
            label = -1

        return img, torch.from_numpy(np.array(label))
    
    def __len__(self):
        """
        获取数据集的大小
        Returns:
            - size: int类型,数据集的大小
        """
        return len(self.img_path)

然后,我们可以使用这个自定义数据集类来加载数据。

np.random.shuffle(train_path)
train_data = AppleDataset(train_path,)
valid_data = AppleDataset(val_path,)

print("类别: {}".format(classes_name))
print("训练集: {}".format(len(train_data)))

可以看到,训练集大约有1万张图片,这个信息在第一次打卡中已经提到过。

类别: ['d1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9']
训练集: 10211

数据增强及可视化

接下来,让我们进行数据增强和可视化。

import matplotlib.pyplot as plt
import torchvision.transforms.functional as TF


# 定义一系列的图像增强操作
transformations = [
    transforms.Resize((224, 224)), # 将图像大小调整为224*224
    transforms.RandomHorizontalFlip(), # 以0.5的概率对图像进行水平翻转
    transforms.RandomVerticalFlip(), # 以0.5的概率对图像进行垂直翻转
    transforms.GaussianBlur(kernel_size=3), # 对图像进行高斯模糊,卷积核大小为3
    transforms.ColorJitter(brightness=0.9), # 调整图像的亮度,亮度因子的范围为[0.1, 1.9]
    transforms.ColorJitter(contrast=0.9), # 调整图像的对比度,对比度因子的范围为[0.1, 1.9]
    transforms.ColorJitter(saturation=0.9), # 调整图像的饱和度,饱和度因子的范围为[0.1, 1.9]
]

# 定义每个转换操作的标题
transformations_title = ['Resize', 
                         'RandomHorizontalFlip', 
                         'RandomVerticalFlip', 
                         'RandomGaussianBlur', 
                         'ColorJitter(brightness)', 
                         'ColorJitter(contrast)', 
                         'ColorJitter(saturation)',
                        ]

num_images = 5

# 可视化训练集的图像转换结果
fig, axes = plt.subplots(nrows=1, ncols=num_images, figsize=(12, 2))

# 显示原始图像
for i in range(num_images):
    img, label = train_data[i]
    ax = axes[i]
    ax.imshow(img)
    ax.set_title(f"Original d{label+1}")
    ax.axis('off')
plt.show()


# 显示每个转换操作的结果
for i, transform in enumerate(transformations):
    # 可视化训练集的图像转换结果
    fig, axes = plt.subplots(nrows=1, ncols=num_images, figsize=(12, 2))
    for j in range(num_images):
        img, label = train_data[j]
        ax = axes[j]
        transformed_img = transform(img)
        ax.imshow(transformed_img)
        ax.set_title(f"{transformations_title[i]}")
        ax.axis('off')

    plt.tight_layout()
    plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过上述代码,我们定义了一系列的数据增强操作,并进行了可视化。可以看到,在不同的数据增强操作下,图像发生了变化。

在代码中,我们使用了以下数据增强操作:

  1. 调整图像大小:使用 transforms.Resize((224, 224)) 将图像大小调整为 224x224 像素。
  2. 随机水平翻转:使用 transforms.RandomHorizontalFlip() 以 0.5 的概率对图像进行水平翻转。
  3. 随机垂直翻转:使用 transforms.RandomVerticalFlip() 以 0.5 的概率对图像进行垂直翻转。
  4. 高斯模糊:使用 transforms.GaussianBlur(kernel_size=3) 对图像进行高斯模糊,卷积核大小为 3。
  5. 调整亮度:使用 transforms.ColorJitter(brightness=0.9) 调整图像的亮度,亮度因子的范围为 [0.1, 1.9]。
  6. 调整对比度:使用 transforms.ColorJitter(contrast=0.9) 调整图像的对比度,对比度因子的范围为 [0.1, 1.9]。
  7. 调整饱和度:使用 transforms.ColorJitter(saturation=0.9) 调整图像的饱和度,饱和度因子的范围为 [0.1, 1.9]。

以上操作使得图像在进行数据增强时产生了多样的变化效果。

数据加载+数据增强

下面是将数据增强操作应用于数据集的代码:

# 定义图像预处理的参数
image_mean = [0.4940, 0.4187, 0.3855]
image_std = [0.2048, 0.1941, 0.1932]

# 定义训练集的数据增强操作
transform_train = transforms.Compose([
    transforms.Resize((224,224)), # 将图像大小调整为224*224
    transforms.RandomHorizontalFlip(), # 以0.5的概率对图像进行水平翻转
    transforms.RandomVerticalFlip(), # 以0.5的概率对图像进行垂直翻转
    transforms.RandomApply([transforms.GaussianBlur(kernel_size=3)], p=0.1), # 以0.1的概率对图像进行高斯模糊,卷积核大小为3
    transforms.RandomApply([transforms.ColorJitter(brightness=0.9)],p=0.5), # 以0.5的概率调整图像的亮度,亮度因子的范围为[0.1, 1.9]
    transforms.RandomApply([transforms.ColorJitter(contrast=0.9)],p=0.5), # 以0.5的概率调整图像的对比度,对比度因子的范围为[0.1, 1.9]
    transforms.RandomApply([transforms.ColorJitter(saturation=0.9),],p=0.5), # 以0.5的概率调整图像的饱和度,饱和度因子的范围为[0.1, 1.9]
    transforms.ToTensor(), # 将图像转换成张量
    transforms.Normalize(image_mean, image_std), # 对图像进行标准化处理
])

# 定义验证集的数据预处理操作
transform_valid = transforms.Compose([
    transforms.Resize((224,224)), # 将图像大小调整为224*224
    transforms.ToTensor(), # 将图像转换成张量
    transforms.Normalize(image_mean, image_std), # 对图像进行标准化处理
])

在上述代码中,我们定义了训练集和验证集的数据增强操作。transform_train 是训练集的数据增强操作,其中包括图像大小调整、水平翻转、垂直翻转、高斯模糊、亮度调整、对比度调整和饱和度调整等操作。transform_valid 是验证集的数据预处理操作,其中包括图像大小调整。

接下来,我们可以可视化经过数据增强操作后的图像。

# 可视化训练集
fig, axes = plt.subplots(nrows=2, ncols=5, figsize=(10, 4))
for i in range(10):
    img, label = train_data[i]
    ax = axes[i // 5, i % 5]
    ax.imshow(img.permute(1, 2, 0))
    ax.set_title(classes_name[label.item()])
    ax.axis('off')
plt.tight_layout()
plt.show()

以上代码会显示经过数据增强后的训练集图像,但是我进行标准化,所以会看的非常奇怪

在这里插入图片描述

为了查看进行了哪些操作,我们可以进行反标准化操作:

def denormalize(img, mean, std):
    mean = torch.tensor(mean).reshape(3, 1, 1)
    std = torch.tensor(std).reshape(3, 1, 1)
    return img * std + mean

# 可视化训练集
fig, axes = plt.subplots(nrows=2, ncols=5, figsize=(10, 4))
for i in range(10):
    img, label = train_data[i]
    ax = axes[i // 5, i % 5]
    ax.imshow( denormalize(img, image_mean, image_std).permute(1, 2, 0))
    ax.set_title(classes_name[label.item()])
    ax.axis('off')
plt.tight_layout()
plt.show()

以上代码会显示经过反标准化操作后的训练集图像,以查看进行了哪些数据增强操作。

在这里插入图片描述

Mixup数据增强

接下来我们实现了Mixup数据增强方法。

首先,我们定义了一个Mixup类,它接受alphabeta作为参数,这些参数用于定义Beta分布。Mixup类有一个__call__方法,用于执行Mixup操作。给定图像数据x和标签y,该方法将返回混合后的图像mixed_image、两个标签y1y2以及混合系数lambd

# 定义Mixup类
class Mixup:
    def __init__(self, alpha=1.5, beta=1.5):
        """
        构造函数,初始化Mixup的参数
        Args:
        - alpha: float类型,beta分布的参数alpha
        - beta: float类型,beta分布的参数beta
        Returns:
        - None
        """
        self.alpha = alpha
        self.beta = beta

    def __call__(self, x, y):
        """
        实现Mixup的操作
        Args:
        - x: Tensor类型,图像数据
        - y: Tensor类型,标签
        Returns:
        - mixed_image: Tensor类型,混合后的图像数据
        - y1: Tensor类型,标签1
        - y2: Tensor类型,标签2
        - lambd: Tensor类型,混合系数
        """
        image, label = x, y
        batch_size = image.size(0)
        
        # 生成混合系数
        lambd = torch.Tensor([random.betavariate(self.alpha, self.beta)]).to(image.device)

        # 生成随机索引
        index = torch.randperm(batch_size).to(image.device)

        # 进行Mixup操作
        mixed_image = lambd * image + (1 - lambd) * image[index, :]

        # 生成对应的标签
        y1, y2 = label, label[index]
        return mixed_image, y1, y2, lambd

# 初始化Mixup的参数
mixup = Mixup(alpha=1.5, beta=1.5)

接下来,我们从训练集中获取一个batch的数据,并应用Mixup数据增强。

# 使用PyTorch的DataLoader加载训练集数据
train_loader = torch.utils.data.DataLoader(
        train_data, batch_size=8, shuffle=True, num_workers=0, pin_memory = True)

# 获取一个batch的数据
images, labels = next(iter(train_loader))

# 进行数据混合
mixed_image, y1, y2, lambd = mixup(images,labels)

然后,我们对混合后的图像进行反标准化,并可视化结果。你可以观察到图像实际上是两张图像的混合。

# 反标准化混合图像
denorm_mixed_images = denormalize(mixed_image, image_mean, image_std)

# 创建图像网格
num_images = len(denorm_mixed_images)
fig, axes = plt.subplots(nrows=2, ncols=num_images//2, figsize=(12, 6))

# 显示混合图像
for i, ax in enumerate(axes.flatten()):
    mixed_img = TF.to_pil_image(denorm_mixed_images[i])
    ax.imshow(mixed_img)
    ax.set_title(f"Mixed Image {i+1}")
    ax.axis('off')

plt.tight_layout()
plt.show()

在这里插入图片描述

最后,需要注意的是,经过Mixup数据增强后,损失函数也需要进行相应的调整。以下是一个模板示例,展示了如何在训练批次中应用Mixup。

# 在每个训练批次中应用Mixup
inputs, labels = data  # 获取训练数据及其标签
inputs, labels_a, labels_b, lam = mixup(inputs, labels)

# 将数据和标签输入模型进行训练
outputs = model(inputs)
loss = lam * criterion(outputs, labels_a) + (1 - lam) * criterion(outputs, labels_b)
optimizer.zero_grad()
loss.backward()
optimizer.step()

在上述代码中,inputs 是训练数据,labels 是对应的标签。通过调用 mixup 函数,我们将输入数据进行Mixup操作,生成混合的输入数据 mixed_inputs,同时生成对应的标签 labels_alabels_b。在训练过程中,我们使用混合数据 mixed_inputs 和相应的标签进行模型训练,并计算损失函数。注意,损失函数使用了Mixup系数 lam 进行加权计算。通过这种方式,你可以在训练过程中应用Mixup数据增强,并调整损失函数以适应混合图像的训练。

Mixup数据增强的核心思想是将两个样本按照一定的比例进行线性插值,生成一个新的样本,并将对应的标签也按照相同的比例进行插值。这种数据增强方法可以提升模型的鲁棒性和泛化能力,并且有助于防止过拟合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/641103.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第四章 完型填空

第四章 完型填空 第一节 真题 2020-完型填空- Section I Use of English Directions: Read the following text. Choose the best word (s) for each numbered blank and mark A, B, C or D on the ANSWER SHEET. (10 points) Being a good parent is, of cour…

Vue中使用editor.md(1):简单使用

0. 背景 在Vue项目中添加一个markdown编辑器,选择使用editor.md,记录在Vue项目中的简单使用。 1. 环境配置 1.1 下载editor.md 官网地址:http://pandao.github.io/editor.md/ 项目文件解压后放入:public/static/内 1.2 下…

【Linux】进程间的通信之共享内存

进程间的通信之共享内存 一、system V 内存共享原理二、共享内存的使用1、ftok函数2、shmget函数3、shmat函数4、shmdt函数5、shmctl函数6、代码使用 三、一些细节的补充 一、system V 内存共享原理 利用内存共享进行进程间的通信的原理其实分为以下几个步骤: 在物…

chatgpt赋能python:Python如何将英文转化为中文的最佳方法

Python如何将英文转化为中文的最佳方法 介绍 在现代全球化社会中,国与国之间的交流越来越频繁,相应的语言翻译工具的需求也愈发迫切。Python是一种易于学习、快速上手的编程语言,适合初学者和经验丰富的程序员使用,在语言翻译方…

技术很牛逼,不会讲PPT,可惜了!

怎样才能做好一场技术分享呢?结合我的经历,做了一些总结。 2015年,我出版《技术管理之巅》以后,先后收到QCon、CSDN、IT168等业界知名技术大会的邀请担任分享嘉宾,几年下来发表了近百场技术及管理相关话题的分享&#…

工业4G路由器 小体积4G LTE通信模块转有线转WiFi充电桩视频安防监控物联网路由器上网CPE

4G LTE代表第四代长期演进,这是一种用于通过蜂窝网络提供高速数据传输的无线通信技术。它是移动网络技术的最新标准,提供比其前身3G更快的数据传输速度。它广泛用于移动设备、物联网设备和机器对机器通信。 近年来,随着物联网技术的快速发展…

探索现代软件架构:揭秘单体、SOA和微服务的进化的之路

1、单体服务、SOA、微服务区别 单体服务 是指一个应用程序中所有的功能都集成在一个单一的代码库中。这种设计模式简单易用,开发人员可以快速地开发和维护应用程序,但是也存在一些问题。例如,当应用程序需要添加新功能时,需要对整…

OpenCV项目开发实战--对图像种的对象进行无缝克隆-附Python、C++的代码实现

文末附基于Python和C++两种方式实现的测试代码下载链接 图 1:无缝克隆示例:一架飞机被克隆到傍晚天空的图片中。 OpenCV 3 中引入的令人兴奋的新功能之一称为无缝克隆。有了这个新功能,您可以从一个图像中复制一个对象,然后将其粘贴到另一个图像中,从而使构图看起来无缝…

FineBI6.0安装部署(最新版)

文章目录 FineBI简介安装步骤场景复现 FineBI简介 FineBI是一款大数据分析的BI工具,同时也是纯B/S架构的商业智能分析服务平台,将其部署到服务器上,就可以通过浏览器进行服务平台的访问和使用。用户在FineBI里面可以进行轻量的数据模型构建&…

Python--常量和变量

Python--常量和变量 <font colorblue>引例<font colorblue>一、常量<font colorblue>二、变量<font colorblue>1.定义<font colorblue>2.变量的赋值<font colorblue>3.变量和变量值的关系<font colorblue>4.标识符、变量名、关键字 …

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

欢迎关注「全栈工程师修炼指南」公众号 点击 &#x1f447; 下方卡片 即可关注我哟! 设为「星标⭐」每天带你 基础入门 到 进阶实践 再到 放弃学习&#xff01; 专注 企业运维实践、网络安全、系统运维、应用开发、物联网实战、全栈文章 等知识分享 “ 花开堪折直须折&#xf…

大数据基础环境与常用软件搭建

大数据基础环境的搭建需要以下步骤&#xff1a; 安装操作系统&#xff1a;大数据环境通常使用Linux操作系统&#xff0c;推荐使用CentOS或Ubuntu。 安装Java环境&#xff1a;大数据软件通常需要Java环境支持&#xff0c;可以安装OpenJDK或Oracle JDK。 安装Hadoop&#xff1a…

【Android开发基础】多线程-Handle消息机制

文章目录 一、引言二、认识1、为什么要用Handle2、原理图3、关键对象&#xff08;1&#xff09;Message&#xff08;消息类&#xff09;&#xff08;2&#xff09;Handler&#xff08;消息机制&#xff09;&#xff08;3&#xff09;MessageQueue&#xff08;消息处理类&#x…

轻量级报表解决方案Telerik Reporting,轻松完成嵌入式报表交互!

开发者可以通过多种方式与集成在应用程序中的Telerik报表进行交互&#xff0c;从“只是阅读它”到更改报表中包含的数据。 但是要注意&#xff1a;开发者所能做的一些事情将取决于报表是如何创建的&#xff0c;以及它是如何嵌入到应用程序UI中的。因此(和任何应用程序一样)&am…

关于数据库SQL优化

简介 在项目上线初期&#xff0c;业务数据量相对较少&#xff0c;SQL的执行效率对程序运行效率的影响可能不太明显&#xff0c;因此开发和运维人员可能无法判断SQL对程序的运行效率有多大。但随着时间的积累&#xff0c;业务数据量的增多&#xff0c;SQL的执行效率对程序的运行…

假如不干技术,多年学的知识会不会白费?

【1】 有位匿名朋友&#xff0c;在星球中提问&#xff1a; 沈老师&#xff0c;作为一个开发&#xff0c;如果离开了公司&#xff0c;不再做技术&#xff0c;感觉这么多年学的知识都白费了&#xff0c;什么都用不上了&#xff0c;你怎么看&#xff1f; 我的一些思考&#xff0c;…

智能驾考远程监控方案4G工业路由器物联网应用

随着全民经济增长生活水平提高&#xff0c;汽车保有量也随之增长&#xff0c;需要驾驶机动车前提是需要经过标准的驾考培训获得机动车驾驶证后&#xff0c;才能够驾车上路。参加过驾考的朋友们都知道&#xff0c;科目一与科目四都是上机考试&#xff0c;而科目二和科目三则是在…

C#实战:Dapper操作PostgreSQL笔记

目录 一、PostgreSQL简介 二、PostgreSQL组成 三、PostgreSQL的主要优点 四、PostgreSQL的使用场景 五、示例 1、安装dapper&#xff0c;目前本案例安装的版本是1.50.2 2、安装PostgreSQL驱动 3、数据库链接示例 4、通过SQL查询数据列表写法 5、插入示例写法 一、PostgreSQL简介…

Triton教程 -- 快速开始

Triton教程 – 快速开始 文章目录 Triton教程 -- 快速开始创建模型存储库启动 Triton在带 GPU 的系统上运行在纯 CPU 系统上运行验证 Triton 是否正常运行发送推理请求 Triton 推理服务器的新手&#xff0c;想快速部署您的模型吗&#xff1f; 利用这些教程开始您的 Triton 之旅…

FasterTransformer 004 open_attention.h forward

initialize forward() https://github1s.com/NVIDIA/FasterTransformer/blob/v1.0/fastertransformer/cuda/open_attention.h#L149-L217 使用cuBLAS库执行矩阵乘法运算&#xff0c;并对cublasGemmEx&#xff08;&#xff09;进行三个单独的调用。这些操作包括将属性核与输入张…