torchvision 是 torch 中计算机视觉库,提供了3种类型的接口,包括 datasets、transforms、model,其中 transforms 封装了各种图像数据增强的方法
裁剪
transforms.CenterCrop(size):从图像中心裁剪图片
- size:裁剪尺寸
transforms. RandomCrop:从图像中随机裁剪出指定尺寸的图片
- size:裁减尺寸
- padding:设置填充大小,默认为 None;可取整型和tuple,
// 当为整型 a 时,表示上下左右填充 a 个像素;
// 当为 (a,b) 时,代表上下填充 b,左右填充 a 个像素;
// 当为 (a,b,c,d) 时,代表 左上右下 填充 abcd 个像素 【顺时针】
- pad_if_need:若图像尺寸小于 裁剪 size,则需要填充,默认 False
- padding_mode:填充模式,共4种模式,默认取 constant
1. constant:像素值由 fill 参数指定
2. edge:像素值由图像边缘像素决定
3. reflect:镜像填充,最后一个像素不镜像,如 图像像素为 [1,2,3,4],则镜像填充为 [3,2,1,2,3,4,3,2], 边缘像素 1 4 不镜像
4. symmetric:镜像填充,最后一个像素也镜像,上例镜像填充为 [3,2,1,1,2,3,4,4,3,2]
- fill:填充值,当 padding_mode 为 constant 时有效,默认为 0
transforms.RandomSizeCrop:随机大小 长宽比 裁剪图片
- size:最后生成的图像尺寸
- scale:随机裁剪面积比例,默认 (0.08,1)
- ratio:随机长宽比,默认 (3/4,4/3)
- interpolation:插值方法,PIL.Image.NEAREST、PIL.Image.BILINEAR、PIL.Image.BICUBIC
transforms.FiveCrop:在图像的四角和中心裁剪出指定尺寸的 5 张图片
- size:裁剪尺寸
transforms.TenCrop:在 FiveCrop 的基础上,并对这 5 张图片进行水平或者垂直翻转,共10张
- size:裁剪尺寸
- vertical_flip:是否进行垂直翻转,若为 False,进行水平翻转
翻转 Flip 和 旋转 Rotation
transforms.RandomRotation:随机旋转图片
- degrees:旋转角度,当为 a 时,在 (-a,a) 之间选择旋转角度,当为 (a,b) 时,在 (a,b) 之间选择旋转角度
- resample:重采样方法,默认 False
- expand:是否扩大图片,默认 False;旋转后图片size不变时,部门图片会丢失,此时可选择 扩大图片,以包含丢失图片
- center:以该点为中心进行旋转
transforms.RandomRotation(30, center=(0, 0), expand=True)
图像变换
transforms.Pad:对图像边缘进行填充
- padding:设置填充大小
// 当为整型 a 时,表示上下左右填充 a 个像素;
// 当为 (a,b) 时,代表上下填充 b,左右填充 a 个像素;
// 当为 (a,b,c,d) 时,代表 左上右下 填充 abcd 个像素 【顺时针】
- padding_mode:填充模式,共4种模式,包括 constant、edge、reflect、symmetric,默认取 constant 【具体含义见上文-裁剪部分】
- fill:当 constant 时,设置填充像素值 (R,G,G) or (Gray)
transforms.ColorJitter:调整亮度、对比度、饱和度、色相
- brightness:亮度调整因子;当为 a 时,从 [max(0,1-a),1+a] 中随机选择,当为 (a,b) 时,从 [a,b] 中随机选择
- contrast:对比度参数,方法同 brightness
- saturation:饱和度参数,方法同 brightness
- hue:色相参数,色相取值 在 -0.5 到 0.5
// 当为 a 时,从 [-a,a] 中选择,注意 -0.5<a<0.5,当为 (a,b) 时,在[a,b] 中选择
transforms.Grayscale:转成灰度图
- num_output_channels:输出通道数,只能取 1 或者 3
transforms.RandomGrayscale:以一定概率转成灰度图
- num_output_channels:输出通道数,只能取 1 或者 3
- p:概率值,被灰度的概率,默认 0.1
transforms.RandomAffine:对图像进行仿射变换,仿射变换是二维的线性变换,由5种基本原子变换构成,包括旋转、平移、缩放、错切、翻转
- degrees:旋转角度,必选参数
- translate:平移,默认为 None
- scale:缩放,默认为 None
- shear:错切角度设置,有水平错切和垂直错切,默认为 None
// 若为 a,仅在 x 轴错切,错切角度在 (-a,a) 之间;
// 若为 (a,b),则 a 代表 x 轴错切角度,b代表 y 轴错切角度;
// 若为 (a,b,c,d),则 ab 设置 x 轴角度,cd 设置 y 轴角度;
- resample:重采样,有 nearest、bilinear、bicubic,默认 False
- fillcolor:填充像素,默认为 0
transforms.RandomErasing:对图像进行随机遮挡
- p:概率,执行遮挡操作的概率;
- scale:遮挡区域的面积;
- ratio:遮挡区域的长宽比;
- value:遮挡区域的像素值,(R,G,B) or (Gray)
- inplace:默认 False
transforms.RandomErasing(p=0.5, scale=(0.02, 0.33), ratio=(0.3, 3.3))
当 value 取字符串时,采用随机像素进行遮挡
匿名函数
transforms.Lambda:用户自定义图像处理的方法,如 CenterCrop
组合操作
transforms.RandomChoice:从多个 transforms 方法中随机选一个
transforms.RandomChoice([transforms1, transforms2, transform3])
transforms.RandomApply:依据概率执行一组 transforms 操作
transforms.RandomApply([transforms1, transforms2, transform3], p=0.5)
transforms.RandomOrder:对一组 transforms 操作进行乱序,乱序处理图片
transforms.RandomOrder([transforms1, transforms2, transform3])
transforms.Compose:顺序执行一系列 transforms 操作
transforms.Compose([transforms1, transforms2, transforms3])
自定义 transforms
transforms.Lambda 是自定义图像处理的方法,如 Resize;
自定义 transforms 是自定义 transforms 系列操作,如 RandomCompose;当然也可以是一个操作;
先看下 pytorch 的 Compose 方法的实现
class Compose(object): def __call__(self, img): for t in self.transforms: img = t(img) return img
类比实现自定义:处理椒盐噪声
椒盐噪声:又称脉冲噪声,是一种随机出现的白点或者黑点,白点称为盐噪声,黑点称为椒噪声
信噪比:Signal-Noise Rate,SNR,衡量噪声的比例,图像的信噪比是图像像素的占比
使用注意事项
1. 上述所有方法是一个类,参数都是初始化参数,然后都以对象的形式存在,使用时调用 __call__ 方法处理图片
2. 上述所有方法输入都是图像,输出也是图像
3. 输入网络前要转换成 Tensor
transforms.ToTensor():将 PIL Image 转换成 Tensor 对象,会自动将 [0, 255] 归一化到 [0, 1]
transforms.Normalize:标准化,注意 只有 Tensor 才能标准化,img 不可以,故 Normalize 之前一般都有 ToTensor
方法总览
常规套路
train_transforms = torchvision.transforms.Compose([ torchvision.transforms.Resize(size=448), # Let smaller edge match torchvision.transforms.RandomHorizontalFlip(), torchvision.transforms.RandomCrop(size=448), torchvision.transforms.ToTensor(), torchvision.transforms.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)) ]) test_transforms = torchvision.transforms.Compose([ torchvision.transforms.Resize(size=448), torchvision.transforms.CenterCrop(size=448), torchvision.transforms.ToTensor(), torchvision.transforms.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)) ])
图像增强的原则
使得训练集尽可能接近测试集
例如,我们要区分第四套人民币的 1 元 和 100 元,很容易得到准确率很高的网络;
那么该网络是否能识别第五套人民币的 100 元,测试结果是基本上都是别成了 1 元,因为颜色很像;
假如我们把训练数据进行灰度处理,去掉颜色的影响,重新训练的模型也能准确预测 第五套人民币的 100 元