第二章 数据处理篇:transforms

news2025/2/9 7:53:48

教程参考:
https://pytorch.org/tutorials/
https://github.com/TingsongYu/PyTorch_Tutorial
https://github.com/yunjey/pytorch-tutorial
详细的transform的使用样例可以参考:ILLUSTRATION OF TRANSFORMS


文章目录

  • 为什么要使用transforms
  • transforms方法举例
    • ToTensor()
    • Normalize()
    • Geometry
      • transforms.Resize()
      • transforms.CenterCrop( size )
      • transforms.RandomCrop(size)
      • transforms.RandomResizedCrop()
      • transforms.FiveCrop(size)
      • transforms.TenCrop(size, vertical_flip = False)
      • RandomHorizontalFlip and RandomVerticalFlip
      • RandomRotation()
    • Color
      • ColorJitter()
      • RandomGrayscale(p = 0.1)
      • GaussianBlur(kernel_size, sigma=(0.1, 2.0))
      • RandomInvert(p=0.5)
    • Composition
      • Compose(transforms)
      • RandomApply(transforms, p)
      • RandomChoice(transforms,p)
      • RandomOrder(transforms)
    • Miscellaneous
      • RandomErasing()
      • Lambda(lambda)
    • Auto-Augmentation

为什么要使用transforms

你得到的原始数据,可能并不是你期望的用于模型训练的数据的形式,比如数据中图像的大小不同、数据的格式不对。这时就需要你对数据进行统一的处理,torchvision.transforms就提供了一些帮助我们进行数据处理的简易手段。

在pytorch官方教程最开始,给了这样一个示例。
示例中使用自带的datasets:FashionMNIST,为了便于训练,对于原始数据和label分别使用了transform的方法。
对于数据本身,使用的方法是 ToTensor(),
对于标签,使用的方法是one-hot。
在后面的部分我们会详细介绍一下不同的transform方法。

import torch
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda

ds = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
    target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
)

torchvision.transforms中提供了多个方法,并且这些那个发f可以使用Compose进行连接,并按顺序执行。其中的大部分transformations方法都可以接受PIL图像和tensor图像作为输入,当然也有一部分在输入上有限制。

transforms方法举例

我们使用opencv读入一张cifar10中的图片作为例子,并将其通道从BGR转为RGB通道。使用opencv读入的图片,为numpy.ndarray格式。下图是我们的例子,一个类别为airplane的图像。
在这里插入图片描述

ToTensor()

ToTensor()方法可以把一个PIL图像或者numpy.ndarray数据转成FloatTensor的形式,并且将图像规范化到0和1之间。
更细致地来说,它会把一共PIL图像,或者范围在[0,255]的大小为(HxWxC)的numpy.ndarray转成一个大小为(CxHxW)的范围在[0.0,1.0]的floattensor。ndarray数据的dtype必须是np.uint8。
在这里插入图片描述

使用ToTensor()方法对我们的img进行处理,可以看到它原本为uint8的ndarray,变成了float32的tensor,它的形状从(32, 32, 3)转为(3, 32, 32),并且它的像素值的大小从51 到 255被转变为0.2到1.0。

我们也可以将图像读取为PIL Image的形式,并使用同样的方法处理。得到的结果是完全相同的。
在这里插入图片描述

Normalize()

Normalize()方法可以把一个tensor数据进行归一化/标准化处理。在使用时,需要你提供数据的均值和方差,Normalize()会对输入数据的每一个通道进行归一化处理。使用的方法是:
o u t p u t [ c h a n n e l ] = i n p u t [ c h a n n e l ] − m e a n [ c h a n n e l ] s t d [ c h a n n e l ] output[channel] = \frac{input[channel] - mean[channel]}{std[channel]} output[channel]=std[channel]input[channel]mean[channel]
要注意它的输入是tensor格式,所以一般把它放到ToTensor()后面使用。
使用之后数据的大小类型都没有发生变化,但是值的范围发生了变化。
在这里插入图片描述

Geometry

主要对图像的大小形状等进行调整,没有改变图像的颜色信息。

transforms.Resize()

torchvision.transforms.Resize(size, interpolation=InterpolationMode.BILINEAR, max_size=None, antialias='warn')

Resize()的输入可以是PIL图像也可以是tensor。给定一张图片,Resize()会对图像的长款进行缩放,把它变成我们期望的大小。

输入的size可以是一个整数也可以是一个序列[h,w],如果是单个整数的话,则被认为是期望的短边的大小,长边会按比例缩放。
输入的interpolation是一个插值方法。
输入max_size定义了一个目标图像的长边大小的上限,如果超过上限,则会重新resize。

transforms.CenterCrop( size )

CenterCrop()的输入可以是PIL图像也可以是Tensor。给定一张图片,CenterCrop()会从图中心开始对图像进行裁剪,只保留我们期望的大小。假如输入的图像大小比我们期望的size小,则会在图像周围进行补0操作。
下图的第一张图为32x32大小的原图,第二张图为10x10的crop结果,第三张图为40x40的crop结果。
在这里插入图片描述

transforms.RandomCrop(size)

torchvision.transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant')

RandomCrop()的输入可以是PIL图像也可以是Tensor。给定一张图像,RandomCrop()会在随机位置对图像进行裁剪

输入的size可以是一个整数也可以是一个序列[h,w],如果是单个整数的话,认为crop的图像的大小是[size,size]。
输入的padding可以是一个整数也可以是一个序列,如果是一个整数,会使用这个整数对所有的边进行padding。如果是一个长度为2的序列,则会分别用来扩充left/right和top/bottom。如果是一个长度为4的整数,则分别对应了每一个边。
输入的padding_mode有四个选项,分别是constant(常数填充), edge(边缘填充),reflect(镜像填充),symmetric (对称填充)。
镜像填充在填充时以边界为镜面形成镜像。对称填充则是使用对称值。具体来说,对[1,2]在左右进行一个像素大小的填充,使用镜像填充得到的结果为[2,1,2,1],使用对称填充得到的结果为[1,1,2,2]。
下图的第一张图为32x32大小的原图,第二张和第三张为10x10的crop结果,因为randomcrop,所以两个图的结果不一样。
在这里插入图片描述

transforms.RandomResizedCrop()

torchvision.transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=InterpolationMode.BILINEAR, antialias: Optional[Union[str, bool]] = 'warn')

RandomResizedCrop()的输入可以是PIL图像也可以是Tensor。给定一张图像,RandomResizedCrop()会在随机位置对图像进行随机大小的裁剪,并把它resize成期望的大小。

输入的size可以是一个整数也可以是一个序列[h,w],如果是单个整数的话,认为crop的图像的大小是[size,size]。
输入的scale要求是一个tuple,定义了crop的区域大小的下限和上限,它使用的是一个基于原图大小的比例值。
输入的ratio要求是一个tuple,定义了crop区域的长宽比的下限和上限。
scale和ratio的区别是,scale代表了取长宽的基准,ratio是在这个基准上参考的长宽比。
输入的interpolation要求是一个插值方法,在RandomResizedCrop()中没有padding,因为随即裁剪得到的图像会使用插值方法resize到期望的大小。
下图的第一张图为32x32大小的原图,第二张和第三张为40x40的crop结。
在这里插入图片描述

transforms.FiveCrop(size)

FiveCrop()的输入可以是PIL图像也可以是Tensor,给定一张图像,获得图像四个角和中心的crop结果。
要注意,FiveCrop()返回的结果是五张图,而不是一张图。
对于一个大小为(b, c, h, w)的tensor的输入,它返回的结果为(b, ncrop, c, size_h, size_w)。
在这里插入图片描述

transforms.TenCrop(size, vertical_flip = False)

TenCrop()和FiveCrop()类型,只不过在其基础上增加了翻转。默认是使用水平翻转,如果vertical_clip设为True,就会使用垂直翻转。
在这里插入图片描述

RandomHorizontalFlip and RandomVerticalFlip

torchvision.transforms.RandomHorizontalFlip(p=0.5)

torchvision.transforms.RandomVerticalFlip(p=0.5)

两个函数的输入可以是PIL图像也可以是tensor。
输入P代表反转图像的概率,默认为0.5,即有50%的概率该图像会被翻转。

RandomRotation()

torchvision.transforms.RandomRotation(degrees, interpolation=InterpolationMode.NEAREST, expand=False, center=None, fill=0)

RandomRotation()的输入可以是PIL图像也可以是tensor。

输入degrees可以是一个整数或者一个序列。如果是整数则代表旋转的范围是 - degrees,+ degrees,如果是一组数则分别代表了最小值和最大值。
输入interpolation是一个插值方法。
输入expand代表是否要对图片进行扩展,经过旋转后图片的形状发生变化,如果expand = False,则会默认保持输出和输入图像大小一致。
输入center代表旋转中心,默认是图片中心。
输入fill代表填充图片边界外 区域所用的数值,默认是0。

第一行的是expand = False时随机旋转的结果,输出图像和输入图像保持一样的大小。第二行是expand = True时的结果,输出图像的大小发生了变化。
在这里插入图片描述

Color

主要对图像的颜色信息进行调整,没有改变图像的形状大小。

ColorJitter()

torchvision.transforms.ColorJitter(brightness: Union[float, Tuple[float, float]] = 0, contrast: Union[float, Tuple[float, float]] = 0, saturation: Union[float, Tuple[float, float]] = 0, hue: Union[float, Tuple[float, float]] = 0)

ColorJitter()的输入可以是PIL图像也可以是tensor。假如输入的是tensor,期望tensor的数据格式为[…, 1 or 3, H, W]。ColorJitter()可以随即调整图像的亮度,对比度,饱和度,色调等。
可以看到使用ColorJitter()后只有图像的颜色发生了变化,几何信息没有受到影响。
在这里插入图片描述

RandomGrayscale(p = 0.1)

RandomGrayscale()的输入可以是PIL图像是也可以是tensor,但是要求tensor的通道数是3。RandomGrayscale()有p的概率将一个图像转换为灰度图。

GaussianBlur(kernel_size, sigma=(0.1, 2.0))

GaussianBlur()的输入可以是PIL图像也可以是tensor。给定一张图像,它可以随机使用高斯模糊来把图像变得模糊。

输入kernel_size是一个整数或者序列,表示高斯核的大小。
输入sigma是代表标准差的上下界。

下图为kernel_size = 5时的结果。
在这里插入图片描述

RandomInvert(p=0.5)

RandomInvert()的输入可以是PIL图像也可以是tensor。给定一张图像,RandomInvert()有p的概率翻转图像的颜色。
在这里插入图片描述

Composition

主要是不同的transforms的组合方式。

Compose(transforms)

Compose()将多个transforms方法组合在一起,在使用时会按顺序进行。
如以下例子,首先将图片进行CenterCrop,然后转变为tensor格式,最后又将图像的dtype变为float。

>>> transforms.Compose([
>>>     transforms.CenterCrop(10),
>>>     transforms.PILToTensor(),
>>>     transforms.ConvertImageDtype(torch.float),
>>> ])

Compose()方法可以用torch.nn.Sequential()替代。

RandomApply(transforms, p)

RandomApply()将多个transforms方法组合在一起,在使用时按照概率p决定是否执行,要么全都执行,全么全都不执行。

RandomChoice(transforms,p)

RandomChoice() 参考random.choices方法,从多个transforms方法中选择一个使用。

RandomOrder(transforms)

RandomOrder()将多个transforms方法而在一起,在使用时会按随机顺序进行。

Miscellaneous

RandomErasing()

torchvision.transforms.RandomErasing(p=0.5, scale=(0.02, 0.33), ratio=(0.3, 3.3), value=0, inplace=False)

RandomErasing()方法的输入必须是tensor,这个函数不支持PIL图像。给定一个图像,RandomErasing()方法会随机选择图像中的一块并擦除他的元素值。

输入p代表执行擦除操作的概率。
输入scale代表擦除区域占输入图像的范围。
输入ratio代表擦除区域的长宽比。
输入value代表擦除后用来替换的值。
输入inplace代表是否在原图像上进行操作。

因为输入必须是tensor,所以只能放在ToTensor()后面使用。

>>> transform = transforms.Compose([
>>>   transforms.RandomHorizontalFlip(),
>>>   transforms.PILToTensor(),
>>>   transforms.ConvertImageDtype(torch.float),
>>>   transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
>>>   transforms.RandomErasing(),
>>> ])

Lambda(lambda)

Lambda()就是在最开始的例子中,target_transform使用的方法。

该例子定义了一个one-hot编码的函数,对于输入的整数类型的图像类别,可以将其转为特殊的one-hot编码格式

target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))

Auto-Augmentation

pytorch 提供了一些policy供使用者选择,比如 IMAGENET, CIFAR10 and SVHN. 依靠这些policy,使用者可以直接套用前人的augmentation方法,而不需要自己编写代码。

  • AutoAugment(policy) 使用你给定的policy执行augmentation方法。
  • RandAugment() https://arxiv.org/abs/1909.13719
  • TrivialAugmentWide() https://arxiv.org/abs/2103.10158
  • AugMix() https://arxiv.org/abs/1912.02781

之后有时间的话再介绍一下别的augmentation常用的包。

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

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

相关文章

RK3588平台开发系列讲解(以太网篇)PHY驱动

文章目录 一、PHY驱动初始化二、PHY 配置初始化三、PHY 的扫描四、PHY 的STATUS状态读取五、PHY的RESET 复位六、PHY 的注册phy_device_register七、PHY 的状态变化沉淀、分享、成长,让自己和他人都能有所收获!😄 一、PHY驱动初始化 完成了mdio总线的注册,以及对不一样厂家…

chatgpt赋能python:Python怎么截图

Python怎么截图 介绍 在日常的工作和学习中,截图是一项非常常见的操作。随着Python在各个领域的不断普及和应用,使用Python进行截图也成为了一个热门话题。Python作为一种高级编程语言,具备丰富的第三方库和模块,可以实现复杂的…

chatgpt赋能python:Python的GUI界面开发

Python的GUI界面开发 Python是目前非常流行的编程语言之一,其优雅的语法和强大的库使其在各个领域得到广泛应用。在GUI界面开发方面,Python也表现出了巨大的潜力。本文将介绍Python的GUI开发框架以及相关的工具和技术。 介绍 Python有多个GUI框架可供…

chatgpt赋能python:Python快速打括号小技巧

Python快速打括号小技巧 作为Python程序员,打括号无法避免。但是有没有快速打括号的方法呢?本文将分享一些小技巧,让你在编码中更加高效。 常规打括号 首先,我们来看看常规的打括号方法。在Python中,我们需要用括号…

Nacos架构与原理 - 健康检查机制

文章目录 注册中心的健康检查机制Nacos 健康检查机制临时实例健康检查机制永久实例健康检查机制集群模式下的健康检查机制 注册中心的健康检查机制 想象发生地质灾害,被掩埋在废墟下,搜救队需定位才能施救。两种方法: 大喊求救,告知位置与健康状况,让搜救队知晓搜救队使用专业…

机器学习之线性回归模型

1 线性回归模型介绍 线性回归模型是机器学习中非常基础且经典的模型,是利用线性拟合的方式探寻数据背后的规律,特征变量的个数可将线性回归模型分为一元线性回归和多元线性回归。 (1)一元线性回归 线性模型的原型为一元一次方程&…

多线程/WinAPI线程退出方式比较分析

文章目录 概述ExitThreadTerminateThread进程退出逼迫线程退出?线程入口函数返回验证无法执行C对象析构不同方案的比较参考或关联 概述 关于如何终止 Windows 线程,在 MSDN Terminating a Thread 一文中列举的很详细: A thread executes until one of …

python数据赋值后,修改新数据,原数据如何保证不被修改?

目录 1.deepcopy 2.实战演练 3.python中的变量实质 好文推荐:传送锚点 1.deepcopy python中对象,赋值后是同一地址,如果是可变对象,对其中一个修改会影响到另一个,如果要生成完全新的对象,应使用&#…

使用Gogs搭建自己的github服务器

文章目录 下载Gogs配置和启动让gogs保持运行 使用参考资料 Gogs官方网址:https://gogs.io/ 下载Gogs 在官网首页可以找到二进制运行,点击进去 让咱们去 github 咱们就去 github 看看好了。https://github.com/gogs/gogs/releases 找到自己需要的版本。 …

【OpenMMLab AI实战营第二期】语义分割与MMSegmentation

MMSegmentation 开源代码仓:https://github.com/open-mmlab/mmsegmentation 算法丰富:600预训练模型、40篇算法复现 模块化设计:配置简便、容易拓展 统一超参:大量消融实验、支持公平对比 使用方便:训练工具、调试…

Python处理办公自动化的10大场景

在编程世界里,Python已经是名副其实的网红了。Python最大优势在于容易学,门槛比Java、C低非常多,给非程序员群体提供了用代码干活的可能性。当然Python能成为大众编程工具,不紧是因为易学,还因为Python有成千上万的工具…

2. CompletableFuture

2.1 Future接口理论知识复习 Future接口(FutureTask实现类)定义了操作异步任务执行一些方法,如获取异步任务的执行结果、取消异步任务的执行、判断任务是否被取消、判断任务执行是否完毕等。 举例:比如主线程让一个子线程去执行任…

python中的map函数

1. map()函数的简介以及语法: 1.1 map是python内置函数,会根据提供的函数对指定的序列做映射。 1.2 map()函数的格式是: map(function,iterable,...) 第一个参数接受一个函数名,后面的参数接受一个或多个可迭代的序列 1.3 map的返…

linux基本功之高效学习Linux命令行工具的技巧:Pandoc实战

前言 大家好,又见面了,我是沐风晓月,本文是专栏【linux基本功-基础命令实战】的第65篇文章。 专栏地址:[linux基本功-基础命令专栏] , 此专栏是沐风晓月对Linux常用命令的汇总,希望能够加深自己的印象&am…

F407之位带操作

位带操作的应用场景,通常在于对IO口进行输入输出读取和控制。 这就和51单片机中直接的端口赋值是一样的。 比如 P0.0 0; P0.0 1; 直接就是对端口P0.0输出0和1。 如何实现呢? 什么是位带操作 位带操作简单的说,就是把每个比特膨胀为一个32位…

全面了解AES加密:入门指南

文章目录 I. 介绍A. 什么是加密B. 为什么要加密1. 保护数据的机密性2. 防止数据被篡改3. 防止数据被窃取4. 保护数据的可信度 C. AES加密的概述 II. 对称加密与非对称加密A. 对称加密的定义和特点1. 简单快速2. 安全性较低3. 适合大量数据加密4. 密钥管理困难5. 用途广泛 B. 非…

黑马版Redis基础篇

一、 初识redis 1.1 认识 NoSQL 关系型数据库: 1.2 认识Redis 二、Redis 常见命令 2.1 Redis 数据结构介绍 2.2 Redis 通用命令 2.3 String 类型 2.3.1 Key的层级格式 2.4 Hash 类型 2.5 List 类型 2.6 Set 类型 2.7 SortedSet 类型 三、Redis 的 Java 客户端 1.…

DelayQueue的核心属性和写入、读取流程分析

DelayQueue的核心属性 DelayQueue的写入流程分析 add方法也是包装使用offer方法。Delay是无解的,数组又可以动态扩容,不需要关注生产者的阻塞问题 offer方法分析 DelayQueue读取流程 消费者消费元素存在两种阻塞的情况: 1.消费者得到栈顶的…

华为OD机试真题 JavaScript 实现【预定酒店】【2022Q4 100分】

一、题目描述 放暑假了,小明决定到某旅游景点游玩,他在网上搜索到了各种价位的酒店(长度为n的 数组A),他的心理价位是x元,请帮他筛选出k个最接近x元的酒店 (n>k>0) ,并由低到高打印酒店的价格。 二、输入描述 第一行: n,…

chatgpt赋能python:Python怎么开三次方?

Python怎么开三次方? Python是一门常用的高级编程语言,被广泛用于数据分析、人工智能、Web开发等领域。在Python中,我们可以使用几种方法轻松地计算三次方根,例如使用sqrt函数、cbrt函数和简单的数学表达式。本文将介绍三种方法&…