我是靠谱客的博主 漂亮小松鼠,最近开发中收集的这篇文章主要介绍深度之眼Pytorch打卡(十二):Pytorch数据预处理——选择与自定义transforms(通过向图片上添加椒盐噪声、高斯噪声增来强数据的数据增强方法),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言


  这篇笔记继续学习pytorch的数据预处理方式transforms,前三篇笔记学习了transforms的使用流程,和各种方法实现。这篇笔记包括两个要点,第一是在已经选好transform方法transform1,transform2,transform3...,并且都设置好参数数的前提下,如何在每次迭代的时候选择不同组的transform方法或者使用不同的调用顺序,第二是如何自定义transform方法 ,虽然pytorch提供了很多transform方法,但有时可能也需要自己定义。本笔记提供了在图片上添加椒盐和高斯噪声 的数据增强方法。本笔记的知识框架主要来源于深度之眼,并依此作了内容的丰富拓展,拓展内容主要源自对torch文档的翻译理解,所用数据来源于网络。

  数据预处理方法具体实现见:

  深度之眼Pytorch打卡(九):Pytorch数据预处理——预处理过程与数据标准化(transforms过程、Normalize原理、常用数据集均值标准差与数据集均值标准差计算)
  深度之眼Pytorch打卡(十):Pytorch数据预处理——数据统一与数据增强(上)
  深度之眼Pytorch打卡(十一):Pytorch数据预处理——数据增强(下)

  几篇数据增强笔记所涉代码及数据见:Poetair/Pytorch-Learning/transforms


transform选择


  • transforms.RandomChoice()
torchvision.transforms.RandomChoice(transforms)

  transforms是一个由若干预处理方法组成的列表transforms=[transform1,transform2,transform3,.....],该方法就是随机从该列表中随机取一个方法来执行。

    transforms.RandomChoice(
        [transforms.RandomGrayscale(1), transforms.ColorJitter(hue=0.5), transforms.RandomRotation(60, resample=2)]),
    transforms.ToTensor(),

在这里插入图片描述

图1.每次读入的图片都从灰度化、变色和旋转中随机选一种方法执行
  • transforms.RandomApply()
torchvision.transforms.RandomApply(transforms, p=0.5)

  依概率p执行transforms,并且执行时按照顺序执行其中每一个预处理方法。transforms是由若干预处理方法组成的list或者是tuple

    transforms.RandomApply([transforms.Pad(50, fill=(100, 130, 110)), transforms.RandomAffine(degrees=0, shear=40), transforms.RandomVerticalFlip(1)], 0.5),
    transforms.ToTensor(),

在这里插入图片描述

图2.每次读入的图片有0.5的概率按顺序执行拓展、仿射和翻转三个操作,有0.5的概率什么都不执行
  • transforms.RandomOrder()
torchvision.transforms.RandomOrder(transforms)

  按照随机的顺序执行transforms中每一个预处理方法,transforms是由若干预处理方法组成的list

    transforms.RandomOrder([transforms.Pad(100, fill=(100, 130, 110)), transforms.CenterCrop(200)]),
    transforms.ToTensor(),

在这里插入图片描述

图2.每次读入的图片执行拓展和裁剪的先后顺序随机,顺序不同结果不同

transform方法自定义


  观察Pytorch提供的transform方法,我们会发现,每一个transform方法都有一个默认输入和一个默认输出,输入往往是PIL Image,输出往往也是PIL Image,当然有特例,比如随机擦除(输入是TenSor),ToTensor(输出是归一化张量)和Normalize(输入是张量)等。

  以Resize为例,从以下源码中可以看出transform方法的基本代码结构。__init__ 中定义一些该类必要的其他参数,如概率p,标准差std,均值mean等。__call__() 中实现数据预处理方法,默认输入便是在这里使用的。大多数的transform方法的具体实现,都是直接调用的torchFunction里的函数,如这里的F.resize()。而在我们自定义预处理方法时,需要在这里自己写。

class Resize(object):

    def __init__(self, size, interpolation=Image.BILINEAR):
        assert isinstance(size, int) or (isinstance(size, Iterable) and len(size) == 2)
        self.size = size
        self.interpolation = interpolation

    def __call__(self, img):                # __call___,让类实例变成一个可以被调用的对象,像函数

        return F.resize(img, self.size, self.interpolation)
  • 添加椒盐噪声

  椒盐噪声是脉冲噪声的特例,指灰度值很低或者灰度值很高的随机点噪声,在图像上就表现为很暗的点(椒)和很亮的点(盐)随机分布。用添加过椒盐噪声的数据集训练出来的模型,对被椒盐噪声污染的测试图像应该会更鲁棒。椒盐噪声的添加,根据想要的噪声密度density,在图像内随机的像素位置,对像素点赋值为0或255,彩色图赋(255,255,255)或者(0,0,0)

  噪声添加的基本实现,额外参数只有density,其需要在__init__定义,而__call__中则添加,向图片中随机撒椒盐的程序。

  撒椒、盐的密度(等于椒、盐出现的概率值):d = density/2.0
  信号密度(等于原图像像素出现的概率值):d = 1-density

  有了各种信号出现的概率,现在就需要根据概率值,随机的在图像上去选择点。用Numpy中的random.choice()函数产生掩膜mask来实现。

  random.choice()

numpy.random.choice(a, size=None, replace=True, p=None)

  a: 整型数值或者一维数组。为数字时,表示生成的mask中的值,是从np.arange(a)中根据概率p随机采样得到的。为一数组时,则表示生成的mask中的值,是随机选择数组中a中的一个值,选择概率由p中对应位置的概率值决定。
  size: 生成mask的大小或输出数组大小,为整型(一维)或者元组(多维)。
  replace:True时,输出数组中的元素可以重复,反之不可重复。
  p: a中对应元素的概率,若没有给出,默认它们等概率

import numpy as np
mask = np.random.choice(99, 100, replace=False)
print(mask)

  ValueError: Cannot take a larger sample than population when 'replace=False'replace=False时,a取值范围应该比size大。

  在添加椒盐噪声的应用中,共有三类点,只需要在mask中用三个值便可以区分,三个值的概率分别就是椒、盐和原像素出现的概率。类似如下代码:

mask = np.random.choice((0, 1, 2), size=(224, 224, 1), p=[0.1, 0.1, 0.8])

  my_transforms.py

import numpy as np
from PIL import Image


class AddSaltPepperNoise(object):

    def __init__(self, density=0):
        self.density = density

    def __call__(self, img):

        img = np.array(img)                                                             # 图片转numpy
        h, w, c = img.shape
        Nd = self.density
        Sd = 1 - Nd
        mask = np.random.choice((0, 1, 2), size=(h, w, 1), p=[Nd/2.0, Nd/2.0, Sd])      # 生成一个通道的mask
        mask = np.repeat(mask, c, axis=2)                                               # 在通道的维度复制,生成彩色的mask
        img[mask == 0] = 0                                                              # 椒
        img[mask == 1] = 255                                                            # 盐
        img= Image.fromarray(img.astype('uint8')).convert('RGB')                        # numpy转图片
        return img

  调用:

    my_transforms.AddSaltPepperNoise(0.2),
    transforms.ToTensor(),

  结果:
椒盐噪声

图3.添加密度为0.2的椒盐噪声

  

  • 添加高斯噪声

  高斯噪声,即分布服从正态分布的噪声,是一种非常常见的噪声,其叠加在图像的每一个点上。主要参数有方差、均值和幅值。用numpy.random.normal函数来产生服从高斯分布的噪声。

在这里插入图片描述

  random.normal()

numpy.random.normal(loc=0.0, scale=1.0, size=None)  

  loc: 均值。浮点值或者数组
  scale:标准差。浮点值或者数组。
  size: 输出尺寸。整型值或者元组。

N = amplitude*numpy.random.normal(loc=mean, scale=variance, size=(224, 224, 1))  

在这里插入图片描述

图3.高斯噪声

  my_transforms.py

class AddGaussianNoise(object):

    def __init__(self, mean=0.0, variance=1.0, amplitude=1.0):

        self.mean = mean
        self.variance = variance
        self.amplitude = amplitude

    def __call__(self, img):
        img = np.array(img)
        h, w, c = img.shape
        N = self.amplitude * np.random.normal(loc=self.mean, scale=self.variance, size=(h, w, 1))
        N = np.repeat(N, c, axis=2)
        img = N + img
        img[img > 255] = 255                       # 避免有值超过255而反转
        img = Image.fromarray(img.astype('uint8')).convert('RGB')
        return img

  主函数使用:

    my_transforms.AddGaussianNoise(mean=0, variance=1, amplitude=20),
    transforms.ToTensor(),

  结果:
高斯噪声

图3.添加幅值为20的标准高斯噪声

参考


  https://pytorch.org/docs/stable/torchvision/transforms.html#torchvision-transforms
  https://blog.csdn.net/u012936765/article/details/53200918
  https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.random.normal.html
  https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.random.choice.html#numpy.random.choice

最后

以上就是漂亮小松鼠为你收集整理的深度之眼Pytorch打卡(十二):Pytorch数据预处理——选择与自定义transforms(通过向图片上添加椒盐噪声、高斯噪声增来强数据的数据增强方法)的全部内容,希望文章能够帮你解决深度之眼Pytorch打卡(十二):Pytorch数据预处理——选择与自定义transforms(通过向图片上添加椒盐噪声、高斯噪声增来强数据的数据增强方法)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部