Datawhale AI夏令营CV方向代码讲解之数据预处理

数据预处理

当我们将所有有效数据导入后,至少需要确保:

  1. 全部样本的尺寸是一致的(同时,全部样本的通道数是一致的)
  2. 图像最终以Tensor形式被输入卷积网络
  3. 图像被恰当地归一化

其中,前两项是为了卷积神经网络能够顺利地运行起来,第三项是为了让训练过程变得更加流畅快速。在PyTorch中,所有的数据预处理都可以在导入数据的时候,通过transform参数来完成,我们通常在transform参数中填写torchvision.transforms这个模块下的类。在预处理时,我们需要使用的常规类如下所示:

  1. Compose: transforms专用的,类似于nn.Sequential的打包功能,可以将数个transforms下的类打包,形成类似于管道的结构来统一执行。
  2. CenterCrop: 中心裁剪。需要输入最终希望得到的图像尺寸。
  3. Resize: 尺寸调整。需要输入最终希望得到的图像尺寸。注意区别于使用裁剪缩小尺寸或使用填充放大尺寸。
  4. Normalize: 归一化(Tensor Only)。对每张图像的每个通道进行归一化,每个通道上的每个像素会减去该通道像素值的均值,并除以该通道像素值的方差。
  5. ToTensor: (PIL Only)将任意图像转变为Tensor

1 调整尺寸

无论使用怎样的卷积网络,我们都倾向于将图像调整到接近28x28或224x224的尺寸。

1.1 剪裁 Crop

当原图尺寸与目 标尺寸较为接近时,我们可以使用**裁剪**功能。裁剪是会按照我们输入的目标尺寸,将大于目标尺寸的 像素点丢弃的功能,因此使用裁剪必然会导致信息损失,过多的信息损失会导致卷积网络的结果变差。 当需要检测或识别的对象位于图像的中心时,可以使用中心裁剪。**中心裁剪**会以图像中心点为参照,按照输入的尺寸从外向内进行裁剪,被裁剪掉的像素会被直接丢弃。如果输入的尺寸大于原始图像尺寸, 则在原始图像外侧填充0,再进行中心裁剪。

1.2 Resize

当图像的尺寸与目标尺寸相差较大,我们不能接受如此多的信息被丢弃的时候,就需要使用尺寸调整的类Resize。**Resize**是使用像素聚类、像素插补等一定程度上对信息进行提取或选择、并按要求的尺寸重排像素点的功能。一般来说,Resize过后的图片会呈现出与原图较为相似的信息,但图片尺寸会得到缩放。

如果原始图像尺寸很大,目标尺寸很小,我们一般会优先使用Resize将图像尺寸缩小到接近目标尺寸的程度,再用裁剪让图片尺寸完全等于目标尺寸。例如,对于600*800的图像,先Resize将尺寸降到 256x256,再裁剪至224x224。

from torch import nn
import torchvision.transforms as transforms
transform = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224)])

#等价于
transform = nn.Sequential(transforms.Resize(256),transforms.CenterCrop(224))

2 归一化/标准化 Normalize()

调整完尺寸之后,我们需要对数据进行归一化,在这里使用的类是 transforms.Normalize() 。从理论上来说,图像数据的归一化不是必须的,但历史的经验告诉我们,**归一化能够非常有效地改善整体训练过程速度,并对最终模型的结果造成巨大的影响**,因此各大经典架构的论文和PyTorch官方都强烈建议进行归一化。这里的归一化与BN等训练过程中存在的归一化有较大的区别,这里的归一化主要是**让像素值减去一个数(默认为均值)、再除以另一个数(默认是标准差)**,以实现对像素值大小的改变, 让模型在一个较高的起点上训练,但并不能像BN一样改变数据的分布。

对表格数据而言,归一化是以特征为单位进行的,每个特征会单独减去自己这个特征的均值,再除以这个特征的标准差。对任意图像而言,**归一化都是以通道为单位进行的**,每个通道上的全部样本的全部像素点会减去通道像素的均值,再除以通道像素的标准差。为了能够对通道上的全部像素进行计算,**图像在被归一化前必须被转化为Tensor**。因此在实际中,我们常常将 transforms.Normalize() 常常和 transforms.ToTensor() 连用。

transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(0.5,0.5)])

注:类transforms.ToTensor()已经带有归一化的功能:这个类会**按照最大值255,最小值0对图片数据进行归一化,将所有图像的像素值压缩到[0,1]之间**。因此类transforms.Normalize()往往是在[0,1]区间执行。因此类 transforms.Normalize() 往往是在[0,1]区间上执行。唯一的例外可能是表格数据,如果输入transforms.ToTensor() 的数据原本是二维表,那其最大值可能会远远超出255,那经过归一化后数字范围也不会在[0,1]之间。为了避免这种情况的出现,我们可以提前将二维表的数据压缩到[0,255]之间。

在类 transforms.Normalize() 中有两个参数,一个是mean,另一个是std,分别代表需要减去的值和需要除以的值。

对图像而言,必须完成的预处理就只用尺寸调整和归一化而已。接下来会有一些操作比如数据增强等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值