一、数据增强概述

二、数据增强方法:裁剪

三、数据增强方法:翻转和旋转

四、数据增强方法:变换

五、transforms方法的选择操作

一、数据增强概述

我们来看图片中的数据增强是怎么样的。

左边的图像可以增强得到右边的图片,供模型训练。模型见过更多更丰富的样本,从而提高模型的泛化能力。

下面开始学习具体的数据增强方法。

二、裁剪

1. transforms.CenterCrop()

功能是对图像进行中心裁剪。

看例子,左边是224*224的图片。进行一个196*196的CenterCrop,得到右边的图像。

例:还是人民币的例子。

# -*- coding: utf-8 -*-
"""
# @file name  : transforms_methods_1.py
# @author     : TingsongYu https://github.com/TingsongYu
# @date       : 2019-09-11 10:08:00
# @brief      : transforms方法(一)
"""
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))import numpy as np
import torch
import random
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
from PIL import Image
from matplotlib import pyplot as pltpath_lenet = os.path.abspath(os.path.join(BASE_DIR, "model", "lenet.py"))
path_tools = os.path.abspath(os.path.join(BASE_DIR, "tools", "common_tools.py"))
assert os.path.exists(path_lenet), "{}不存在,请将lenet.py文件放到 {}".format(path_lenet, os.path.dirname(path_lenet))
assert os.path.exists(path_tools), "{}不存在,请将common_tools.py文件放到 {}".format(path_tools, os.path.dirname(path_tools))import sys
'''
hello_pytorch_DIR = os.path.abspath(os.path.dirname(__file__)+os.path.sep+".."+os.path.sep+"..")
sys.path.append(hello_pytorch_DIR)
'''
from tools.my_dataset import RMBDataset
from tools.common_tools import set_seed, transform_invertset_seed(1)  # 设置随机种子# 参数设置
MAX_EPOCH = 10
BATCH_SIZE = 1
LR = 0.01
log_interval = 10
val_interval = 1
rmb_label = {"1": 0, "100": 1}# ============================ step 1/5 数据 ============================
split_dir = os.path.abspath(os.path.join(BASE_DIR, "data", "rmb_split"))
if not os.path.exists(split_dir):raise Exception(r"数据 {} 不存在, 回到lesson-06\1_split_dataset.py生成数据".format(split_dir))
train_dir = os.path.join(split_dir, "train")
valid_dir = os.path.join(split_dir, "valid")norm_mean = [0.485, 0.456, 0.406]
norm_std = [0.229, 0.224, 0.225]train_transform = transforms.Compose([transforms.Resize((224, 224)),# 1 CenterCroptransforms.CenterCrop(196),     # 196# 2 RandomCrop# transforms.RandomCrop(224, padding=16),# transforms.RandomCrop(224, padding=(16, 64)),# transforms.RandomCrop(224, padding=16, fill=(255, 0, 0)),# transforms.RandomCrop(512, pad_if_needed=True),   # pad_if_needed=True# transforms.RandomCrop(224, padding=64, padding_mode='edge'),# transforms.RandomCrop(224, padding=64, padding_mode='reflect'),# transforms.RandomCrop(1024, padding=1024, padding_mode='symmetric'),# 3 RandomResizedCrop# transforms.RandomResizedCrop(size=224, scale=(0.5, 0.5)),# 4 FiveCrop# transforms.FiveCrop(112),# transforms.Lambda(lambda crops: torch.stack([(transforms.ToTensor()(crop)) for crop in crops])),# 5 TenCrop# transforms.TenCrop(112, vertical_flip=False),# transforms.Lambda(lambda crops: torch.stack([(transforms.ToTensor()(crop)) for crop in crops])),# 1 Horizontal Flip# transforms.RandomHorizontalFlip(p=1),# 2 Vertical Flip# transforms.RandomVerticalFlip(p=0.5),# 3 RandomRotation# transforms.RandomRotation(90),# transforms.RandomRotation((90), expand=True),# transforms.RandomRotation(30, center=(0, 0)),# transforms.RandomRotation(30, center=(0, 0), expand=True),   # expand only for center rotationtransforms.ToTensor(),transforms.Normalize(norm_mean, norm_std),
])valid_transform = transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(norm_mean, norm_std)
])# 构建MyDataset实例
train_data = RMBDataset(data_dir=train_dir, transform=train_transform)
valid_data = RMBDataset(data_dir=valid_dir, transform=valid_transform)# 构建DataLoder
train_loader = DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
valid_loader = DataLoader(dataset=valid_data, batch_size=BATCH_SIZE)# ============================ step 5/5 训练 ============================
for epoch in range(MAX_EPOCH):for i, data in enumerate(train_loader):inputs, labels = data   # B C H Wimg_tensor = inputs[0, ...]     # C H Wimg = transform_invert(img_tensor, train_transform)    #这个函数用来对transform进行逆操作。使得可以观察到模型输入的数据长什么样。plt.imshow(img)plt.show()plt.pause(0.5)plt.close()# bs, ncrops, c, h, w = inputs.shape# for n in range(ncrops):#     img_tensor = inputs[0, n, ...]  # C H W#     img = transform_invert(img_tensor, train_transform)#     plt.imshow(img)#     plt.show()#     plt.pause(1)

后面的只要每次修改标红的地方就行了,就不全写了。

结果:

可以看到生成了196*196的图像。

如果要生成的图像大于224*224呢?比如参数改成256,我们看到程序不报错,而是能正确裁剪出256*256的图片。只不过对超出的部分会填充为0的像素。

2. transforms.RandomCrop()

随机裁剪出大小为size的图片。是随机位置的裁剪。

padding:当为一个数时,上下左右都填充a个像素。当时一个元组(a,b)时,左右填充a个像素,上下填充b个像素。当padding为(a,b,c,d)的元组时,对四边填充不同的值。

例1:对上下左右均进行16像素的padding。然后再在这个大的图片上进行224*224的随机选取。

结果:

对上下左右均进行16像素的padding。然后再在这个大的图片上进行224*224的随机选取。

例2:左右填充16,上下填充64。然后随机选取224*224。

结果:

左右填充16,上下填充64。然后随机选取224*224。

例3:不想填充黑色的时候,可以通过fill进行设置。颜色为RGB。

结果:

例4:当size大于图像尺寸的时候,一定要设pad_if_need为True,否则会报错。

结果报错:

把参数打开:

结果:

例5:由图片边缘的像素填充。

结果:

例6:镜像模式

结果:

例7:镜像

结果:

像不像印钞机!

3. RandomResizedCrop()

相比RandomCrop()多了一个Resized的操作。将给定图像随机裁剪为不同的大小和宽高比,然后缩放所裁剪得到的图像为指定的大小.(即先随机采集,然后对裁剪得到的图像缩放为同一大小)。

该操作的含义:即使只是该物体的一部分,我们也认为这是该类物体。比如 猫的图片别裁剪缩放后,仍然认为这是一个猫。

tatio:长宽比的区间是(3/4,4/3)。

插值方法:由于裁剪之后图片的尺寸可能会小于size,因此要对裁剪出来的图片进行插值,缩放到原始的图片

例1:

结果:

可以看到图片小了很多。

首先根据scale在0.08到1之间随机选取。然后根据长宽比ratio在(3/4,4/3)设定图形的长和宽。然后裁剪图片。裁剪完之后,resize到224*224。

例:将scale设为(0.5,0.5),这样每次都裁剪一半的图像。

结果:

这个图片保存了原有图片的50%的面积。

4. FiveCrop()

5. TenCrop()

FiveCrop()是在图像的左下角、左上角、右上角、右下角以及中心进行裁剪。裁剪出5张图片。【例2】

由于返回的是5张或者10张图片,返回的是一个元组。如果直接使用会报错。【例1】

因此,直接使用是不行的,需要对tuple进行操作。把它变成张量的形式或者PIL image的形式。【例2】

而TenCrop()是在这5张图片的基础上进行镜像得到。代码与FiveCrop()一样。

vertical_flip: True是垂直翻转;False是水平翻转。

例1:

结果:

例2:

lambda是一个匿名函数。冒号之前的是函数的输入,即“crops”。冒号之后的语句就是函数的返回值。

由于上面进行了ToTenser(),下面就不要进行ToTensor()和Normalize()

由于得到的张量不再是一个4维的张量(batchsize, channel, h, w),而是一个5维的张量(batchsize, ncrops, channel, h, w)。所以,不能用上面的代码进行可视化,而是使用下面的循环对5张图片进行可视化。

结果:

左上角:

右上角:

左下角:

右下角:

中间:

三、翻转、旋转

1. RandomHorizontalFlip()

2. RandomVerticalFlip()

只有一个参数p。每次根据一定的概率执行Flip()操作。

什么是水平翻转:

什么是垂直翻转:

例1:水平翻转

结果:

例2:垂直翻转

结果:

有的垂直翻转, 有的没有翻转。

3. RandomRotation()

degrees:旋转角度。【例1】

expand:图片旋转之后,它的四个角有可能超出原始图片的矩形框。超出的部分信息会丢失。如果想保持图片完整。就要吧expand设置为true。【例2】

比如:

左边是旋转了之后不扩大图片。右边是旋转了之后扩大图片。

使用expand的时候,每次图片大小是不一样的。如果batchsize不是1的话,会报错。因为把数据整理成一个batchdata的时候,因为图片的尺寸不一致。

center:旋转点。默认是中心旋转。也可以设置,比如下面第二张是中心旋转,第三张是以左上角旋转。【例3】

不是中心旋转,是不能通过expand=True找回丢失的信息的。【例4】

例1:旋转-90~90度。

例2:旋转-90~90度,中心扩展

结果:

使用expand的时候,每次图片大小是不一样的。

例3:以左上角为中心点,旋转30度。

结果:

例4:

结果:

发现图片还是会丢失,这是因为expand机制是针对centerRotation这个模式计算需要扩大的长度的。而以左上角为中心,扩大的计算方法不一样。所以会出问题。

四、图像变换

1. Pad()

在学习RandomCrop()的时候,就是首先对图片进行填充,然后随机裁剪。

例1:上下左右填充32个像素,填红色。

例2:左右填充8像素,上下64像素。颜色红色。

结果:

例3:四周填充不同的像素值。

结果:

例4:对称填充

2. ColorJitter()

这个方法经常用到,尤其是自然图像。由于自然图像在采集过程中,由于光线或者环境不同,色彩通常会有一些偏差。所以要对其进行调整,以弥补这些偏差带来的扰动。

brightness:亮度。如果brights<1,会变暗;如果>1,会更亮一些。【例1】

contrast:对比度。当对比度降低,会发灰。如果对比度升高,白色的地方会更白,灰色的地方会更灰。【例2】

saturation:饱和度。饱和度降低,图像更暗淡。饱和度升高,图像更鲜艳。【例3】

例1:

首先去掉注释,查看原始图片:

然后放开注释,执行,看效果:

发现变暗了。

例2:对比度

结果:

原图为:

例3:饱和度

结果:

原图:

饱和度降低,图像更暗淡。

例4:色相

结果:

原图:

3. Grayscale()

4. RandomGrayscale()

transforms中提供了两个将彩色图像转换成灰度图像的方法。

RandomGrayscale是依据一定的概率将图片转换成灰度图。Grayscale是RandomGrayscale的一个特例,也就是概率等于1的RandomGrayscale。

我的实验结果是RandomGrayscale()没有num_output_channels这个参数,只有p这个参数。【例2】

例1:

结果:

例2:

结果:

5. RandomAffine()

RandomAffine()方法必须要设置degrees参数。如果不想旋转,就可以把它设置为0.

什么是错切,我们举一个例子:

中间图是进行X轴的错切,可以看到x轴还是平行的;右图是在Y轴进行错切,可以看到y轴还是平行的。

例1:旋转degrees

结果:

可以看到每张图片都是在(-30,30)之间旋转。

例2:平移

结果:

很像RandomCrop()

例3:缩放

结果:

图像还是224*224的,不过进行了缩小。

例4:错切

设置y轴上的错切。

例5:x轴错切

结果:

6. RandomErasing()

往往搜集图片的时候,我们的目标会被遮挡住一部分,但是人类的具有联想的功能,即使我们的物体被遮挡一部分,我们根据联想仍然能够识别出图片中的物体。然而我们的模型就没有这么智能了,他没有联想的功能,所以我们需要对训练集进行人为的遮挡,让我们的模型去见过这些被遮挡的图片。

下面举个例子:

对图片进行了随机大小、随机像素值、随机长宽比的遮挡。

scale:要遮挡多大的面积。

ratio:遮挡的长宽比。

value: 遮挡区间的像素值。

p:依据某一概率确定是否遮挡。

inplace:是否执行原位操作。

需要注意的是,随机遮挡接受的是Tensor,它是在一个张量上进行操作。所以在之前要执行一个ToTensor()。后面的ToTensor()和Normalize可以不要。

例1:

scale=(0.02, 0.33) ration=(0.3, 3.3)是论文推荐的值。因为是Tensor,所以像素值不再是0-255,而是0-1。

例2:如果设置为一个字符串,就会进行随机填充。字符串是个任意的。

结果:

7. transforms.Lambda()

匿名函数。通常用于几个简单的操作的实现。

冒号前面是输入,冒号后面是表达式。

我们上节课的例子:

参数是crops。

首先从crops中拿出crop。然后把crop转换为Tensor。

拼成一个列表。然后把列表拼接成一个向量。返回。

五、transforms方法的选择操作

transforms对图像的具体操作学习完了。现在学习方法的选择操作。通过选择操作方法,可以使得数据增强方法更加灵活、丰富、多样。

1. transforms.RandomChoice()

在一系列方法中随机挑选一个。【例1】

2. transforms.RandomApply()

每次依概率执行还是不执行,执行就执行一组。【例2】

3. transforms.RandomOrder()

打乱顺序再执行。【例3】

例1:图像要么水平翻转要么垂直翻转。

结果:

例2:

结果:

在x轴错切,并变成灰度图。

例3:

结果:

旋转、填充、仿射变换,随机打乱顺序执行。

4.3 pytorch数据预处理:transforms图像增强方法相关推荐

  1. (第一篇)pytorch数据预处理三剑客之——Dataset,DataLoader,Transform

    前言:在深度学习中,数据的预处理是第一步,pytorch提供了非常规范的处理接口,本文将针对处理过程中的一些问题来进行说明,本文所针对的主要数据是图像数据集. 本文的案例来源于车道线语义分割,采用的数 ...

  2. 数据预处理的常见方法

    数据预处理 定义内涵 用户从多种渠道收集的数据可能包含噪音,或是存在不一致.不完整等问题,无法直接 进行训练.为了提高数据的质量,在将数据交给模型训练之前,需要对数据预处理.数据预 处理是指在数据分析 ...

  3. 深度之眼Pytorch打卡(九):Pytorch数据预处理——预处理过程与数据标准化(transforms过程、Normalize原理、常用数据集均值标准差与数据集均值标准差计算)

    前言   前段时间因为一些事情没有时间或者心情学习,现在两个多月过去了,事情结束了,心态也调整好了,所以又来接着学习Pytorch.这篇笔记主要是关于数据预处理过程.数据集标准化与数据集均值标准差计算 ...

  4. NLP数据预处理的一般方法

    文章目录 一.前言 二.实现方法 一.前言 数据预处理一般包括如下几个步骤 读取数据[txt.csv] 拆分输入.输出数据 缺失数据处理[删除.插值] 字符串类型的数据处理[稀疏矩阵.embeddin ...

  5. 机器学习中数据预处理——标准化/归一化方法(scaler)

    由于工作问题比较忙,有两周没有总结一下工作学习中遇到的问题. 这篇主要是关于机器学习中的数据预处理的scaler变化. 工作中遇到的问题是:流量预测问题,拿到的数据差距非常大,凌晨的通话流量很少几乎为 ...

  6. 机器学习过程中的数据预处理和特征选择方法

    1.数据清洗 数据清洗(data cleaning)是在机器学习过程中一个不可缺少的环节,其数据的清洗结果直接关系到模型效果以及最终的结论.在实际的工作中,数据清洗通常占开发过程的50%-80%左右的 ...

  7. 关于文本数据预处理的一些方法

    最近在进行一个关于深度学习的文本情感分类的项目,从数据获取到清洗,以及文本标注这些都在准备.文本预处理是NLP中十分关键的一个流程,正所谓数据是否优质决定着神经网络的训练效果,以及后续对神经网络的调参 ...

  8. 数据预处理之标准化方法

    评价是现代社会各领域的一项经常性的工作,是科学做出管理决策的重要依据.随着人们研究领域的不断扩大,所面临的评价对象日趋复杂,如果仅依据单一指标对事物进行评价往往不尽合理,必须全面地从整体的角度考虑问题 ...

  9. Pytorch 数据预处理

    数据预处理 0. 环境介绍 环境使用 Kaggle 里免费建立的 Notebook 教程使用李沐老师的 动手学深度学习 网站和 视频讲解 小技巧:当遇到函数看不懂的时候可以按 Shift+Tab 查看 ...

最新文章

  1. 我为NET狂官方面试题
  2. 江苏“超牛”女博导:16岁考入北大,跨专业读博,成为全球第4个获此奖项的学者!...
  3. Oracle计划新的移动OpenJDK项目
  4. httpClient多线程问题
  5. gcc 提供的原子操作
  6. SpringMVC中@ResponseBody和@RequestBody的使用
  7. 如何去掉ECShop 2.7.2中的Powered by ECShop字符
  8. python-标识符与变量-标识符的命名规范
  9. C语言异常处理机制——为您的C程序添加异常处理
  10. overfitting怎么解决?
  11. 关于在Ubuntu中更新pip时遇到的问题及解决方法
  12. 矩阵按层级内容排序——Power BI
  13. 读书笔记之《阿里传:这是阿里巴巴的世界》
  14. linux cp命令改名字,Linux cp命令复制文件
  15. html中放大镜案列,HTML放大镜的一种实现及原理讲解(js)
  16. python中append函数的用法
  17. 逆水寒2021最新服务器,逆水寒公布2021部分更新计划,写满了离经叛道
  18. openwt dns 解析部分域名出错问题。
  19. 人类高质量文章:阿里大佬的回顾
  20. 【MATLAB】函数定义与反函数

热门文章

  1. 计算机网络体系结构-外部路由
  2. oracle rpad mysql_Oracle Lpad()函数和Rpad()函数的用法
  3. 职中计算机应用高考项目,新邵职业中专计算机应用专业对口高考习题
  4. conda env虚拟环境
  5. 基于51单片机光照强度检测系统
  6. 王力宏妻子提前诞下一女
  7. TOJ 3287 Sudoku dfs
  8. 导入项目出现a cycle was detected in the build path of project问题解决
  9. 配准中雅可比行列式(Jacobian determinant)的原理、意义、代码实现以及可视化(5.14更新)
  10. 水平拉滑轮组计算机械效率的题,滑轮组机械效率计算题