- 数据增强
transforms
— 裁剪transforms
— 翻转和旋转
一、数据增强
数据增强又称为数据增广,数据扩增,它是对训练集进行变换,增加训练集的数量,使训练集更丰富,从而让模型更具泛化能力。
左边是一张原始图片,我们对这张图片进行一系列的操作变换,得到右边的这64张增强样本供模型去训练。模型可以监控更多更丰富的样本,从而来提高模型的泛化能力。下面我们开始学习具体的方法。
二、transforms
— 裁剪Crop
01. transforms.CenterCrop()
transforms.CenterCrop(size)
- 功能:从图像中心裁剪图片
- size:所需裁剪图片尺寸
02. transforms.RandomCrop()
transforms.RandomCrop(
size,
padding=None,
pad_if_needed=False,
fill=0,
padding_mode='constant')
- 功能:从图片中随机位置裁剪出尺寸为size的图片
size
:所需裁剪图片尺寸padding
:设置填充大小- 当为a时,上下左右均填充a个像素
- 当为(a, b)时,上下填充b个像素,左右填充a个像素
- 当为(a, b, c, d)时,左,上,右,下分别填充a, b, c, d
pad_if_need
:若图像小于设定size,则填充padding_mode
:填充模式,有4种模式constant
:像素值由fill
设定edge
:像素值由图像边缘像素决定reflect
:镜像填充,最后一个像素不镜像,eg:[1,2,3,4] → [3, 2 | 1 | 2,3 | 4 | 3,2]symmetric
:镜像填充,最后一个像素镜像,eg:[1,2,3,4] → [2, 1 | 1,2,3,4 | 4,3]
-
03.
transforms.RandomResizedCrop()
RandomResizedCrop(
size,
scale=(0.08, 1.0),
ratio=(3/4, 4/3),
interpolation)
功能:随机大小、长宽比裁剪图片
size
:所需裁剪图片尺寸scale
:随机裁剪面积比例,默认(0.08, 1)ratio
:随机长宽比,默认(3/4, 4/3)interpolation
:插值方法功能:在图像的上下左右以及中心裁剪出尺寸为size的5张图片,TenCrop对这5张图片进行水平或者垂直镜像获得10张图片
size
:所需裁剪图片尺寸-
三、
transforms
- 翻转、旋转Flip and Rotation01.
transforms.RandomHorizontalFlip()
、transforms.RandomVerticalFlip()
RandomHorizontalFlip(p=0.5)
RandomVerticalFlip(p=0.5)
功能:依概率水平(左右)或垂直(上下) 翻转图片
-
02.
transforms.RandomRotation()
RandomRotation(degrees,
resample=False,
expand=False,
center=None)
功能:随机旋转图片
degrees
:旋转角度- 当为a时,在之间选择旋转角度
- 当为时,在之间选择旋转角度
resample
:重采样方法expand
:是否扩大图片,以保持原图信息-
四、transforms - 图像变换
01.
transforms.Pad()
transforms.Pad(
padding,
fill=0,
padding_mode='constant')
功能:对图片边缘进行填充
padding
:设置填充大小- 当为 a 时,上下左右均填充a个像素
- 当为 (a, b) 时,上下填充b个像素,左右填充a个像素
- 当为 (a, b, c, d) 时,左,上,右,下分别填充a, b, c, d
padding_mode
:填充模式,有4种模式,constant
edge
reflect
symmetric
fill
:constant
时,设置填充的像素值,(R, G, B) or (Gray)02.
transforms.ColorJitter()
transforms.ColorJitter(
brightness=0,
contrast=0,
saturation=0,
hue=0)
功能:调整亮度、对比度、饱和度和色相
brightness
:亮度调整因子- 当为a时,从中随机选择
- 当为 (a, b) 时,从中随机选择
contrast
:对比度参数,同brightnesssaturation
:饱和度参数,同brightnesshue
:色相参数功能:依概率将图片转换为灰度图
num_ouput_channels
:输出通道数。 注意:只能设1
或3
-
04.
transforms.RandomAffine()
RandomAffine(
degrees,
translate=None,
scale=None,
shear=None,
resample=False,
fillcolor=0)
功能:对图像进行仿射变换,仿射变换是二维的线性变换,由五种基本原子变换构成,分别是旋转、平移、缩放、错切和翻转
degrees
:旋转角度设置translate
:平移区间设置,如(a, b), a设置宽(width),b设置高(height) 图像在宽维度平移的区间为scale
:缩放比例(以面积为单位)fill_color
:填充颜色设置shear
:错切角度设置,有水平错切和垂直错切- 若为 a,则仅在x轴错切,错切角度在(-a, a)之间
- 若为(a,b),则a设置x轴角度,b设置y的角度
- 若为(a, b, c, d),则a, b设置x轴角度,c, d设置y轴角度
resample
:重采样方式,有NEAREST 、BILIN05.
transforms.RandomErasing()
RandomErasing(
p=0.5,
scale=(0.02, 0.33),
ratio=(0.3, 3.3),
value=0,
inplace=False)
功能:对图像进行随机遮挡
p
:概率值,执行该操作的概率scale
:遮挡区域的面积ratio
:遮挡区域长宽比value
:设置遮挡区域的像素值,(R, G, B) or (Gray)参考文献:《Random Erasing Data Augmentation 》
06. transforms.Lambda()
transforms.Lambda(lambda)
- 功能:用户自定义lambda方法
lambda
:lambda匿名函数# 模板
lambda [arg1 [,arg2, … , argn]] : expression
# 例子
transforms.TenCrop(200, vertical_flip=True),
transforms.Lambda(lambda crops: torch.stack([transforms.Totensor()(crop) for crop in crops])),
五、Transforms Operation
01.
transforms.RandomChoice()
功能:从这一系列transforms方法中随机挑选一个进行图像变换transforms.RandomChoice([transforms1, transforms2, transforms3])
02.
transforms.RandomApply()
功能:执行该组transforms操作的概率为0.5transforms.RandomApply([transforms1, transforms2, transforms3], p=0.5)
03.
transforms.RandomOrder()
功能:对一组transforms操作打乱顺序transforms.RandomOrder([transforms1, transforms2, transforms3])
六、自定义transforms
我们想要自定义transforms
方法,首先要熟悉transforms
方法的运行机制。之前讲解的DataLoader
、DataSet
以及我们数据的读取机制的时候,就知道transforms
方法是在Compose
类中的__call__函数
被调用的。我们对一组transforms
方法进行for循环
,顺序执行transforms方法
。
在第四行,class Compose(object): def __call__(self, img): for t in self.transforms: img = t(img) return img
t
就是transforms方法
。对transforms方法
只输入一个参数,返回一个参数:也就是transforms方法
必须只能接受一个参数,返回一个参数,这是他的第一个限制。第二限制是我们看到他是一个for循环
,也就是我们当前transforms方法
的input
是上一个transforms方法
的output
,也就是我们要注意上下要输入输出的一个匹配关系。
所以总结下来,我们自定义transforms方法
有两个注意的地方:第
- 一个是自定义
transforms方法
只能接受一个参数,返回一个参数。 - 需要注意上下游的输入输出的一个对应关系。当前的
transforms方法
的输入是上一个transforms方法
的输出,以及当前的transforms方法
的输出是下一个transforms方法
的输入。所以我们这些输入输出之间的数据类型必须要匹配。
说道数据类型必须匹配,比如说我们都是PIL image的数据类型,或者是都是tensor数据类型,然后我们在设计transforms方法
时需要多个参数,比如说我们还要设置概率取值、信噪比。那这些参数该怎么实现?这时候就可以用到类方法:可以用到类来实现多参数传入。下面这个代码结构就是我们自定义transforms
方法的一个基本的一个结构。
class YourTransforms(object):
def __init__(self, ...):
...
def __call__(self, img):
...
return img
先是一个 __init__函数
,初始化函数可以传入我们想要的参数。比如说信噪比、概率值等等。然后我们在这一个类当中,还必须要有一个 __call__函数
,也就是这个类的实例可以被调用的。我们在这个__call__函数
当中,只能接受一个input,只有一个参数 img
,返回一个参数 img
。在__call__函数
中实现我们具体想要的功能。这就是一个基本的自定义transforms方法
的结构。
下面我们通过定义添加椒盐噪声的 transforms方法
来学习如何自定义transforms方法
。椒盐噪声又称为脉冲噪声,它是一种随机出现了黑点或者白点,我们白点成为盐噪声,黑色成为椒噪声。椒盐噪声当中的一个重要的参数叫做信噪比。信噪比是用来衡量噪声的比例:图像中图像像素占整张图像的一个比例。
来看一个例子。这是对小猫图像进行增加不同信噪比的一个效果图。
下面我们就通过自定义 transforms方法
对图像进行增加椒盐噪声
自定义椒盐噪声 transforms方法
的基本结构
class AddPepperNoise(object):
"""增加椒盐噪声
Args:
snr (float): Signal Noise Rate
p (float): 概率值,依概率执行该操作
"""
def __init__(self, snr=0.9, p):
assert isinstance(snr, float) or (isinstance(p, float))
self.snr = snr # 信噪比
self.p = p # 概率值:按照一定的概率值执行程序
def __call__(self, img):
"""
Args:
img (PIL Image): PIL Image
Returns:
PIL Image: PIL image.
"""
if random.uniform(0, 1) < self.p:
img_ = np.array(img).copy() # 将PIL图像转化为数组
h, w, c = img_.shape # 获取高、宽、channel
signal_pct = self.snr # 信号比例
noise_pct = (1 - self.snr) # 噪声比例
mask = np.random.choice((0, 1, 2), # 0原图1 盐噪声 2 椒噪声
size=(h, w, 1),
# 原图的比例 盐噪声的比例 椒噪声的比例
p=[signal_pct, noise_pct/2., noise_pct/2.])
mask = np.repeat(mask, c, axis=2)
img_[mask == 1] = 255 # 盐噪声
img_[mask == 2] = 0 # 椒噪声
return Image.fromarray(img_.astype('uint8')).convert('RGB') # 将数组转化为PIL形式
else:
return img
总结: transforms 方法
- 裁剪
- transforms.CenterCrop
- transforms.RandomCrop
- transforms.RandomResizedCrop
- transforms.FiveCrop
- transforms.TenCrop
- 二、翻转和旋转
- transforms.RandomHorizontalFlip
- transforms.RandomVerticalFlip
- transforms.RandomRotation
- 三、图像变换
- transforms.Pad
- transforms.ColorJitter
- transforms.Grayscale
- transforms.RandomGrayscale
- transforms.RandomAffine
- transforms.LinearTransformation
- transforms.RandomErasing
- transforms.Lambda
- transforms.Resize
- transforms.Totensor
- transforms.Normalize
- 四、transforms的操作
- transforms.RandomChoice
- transforms.RandomApply
- transforms.RandomOrder
数据增强原则:让训练集与测试集更接近