数据增强(Data Augmentation)


前言

最近写论文需要插入很多图片,为了蒙混过关,找了很多很多数据增强的手段,增强论文的丰富性,大家不要学我哈,反正我把技巧放这儿了!!!哈哈哈哈哈哈哈哈哈
在这里插入图片描述

1. Data Augmentation

1.1 数据增强的作用

大家都知道在深度学习网络训练中,模型的样本越充足训练出来的网络模型泛化性越强,鲁棒性越高。最好的例子就是SSD对大目标效果很好,对小目标效果很差,但当使用数据增强后,涨分立马上去了,原因就在于数据增强crop,可以让小目标变成大目标。

  1. 增加训练的数据量,提高模型的泛化能力
  2. 增加噪声数据,提升模型的鲁棒性
  3. 一定程度上能解决过拟合问题,样本过少容易出现过拟合
  4. 解决样本不平衡问题,例如某个类别过少,数据增强可以增强这个类别的数量。

1.2 图像增强小工具

我写了一款图像增强的小工具,大家可以查看连接下载使用
在这里插入图片描述

2. 数据增强的手段

数据增强的手段太多了,我就不一一解释了,直接总结吧

  1. 几何变换:反转/平移/旋转/缩放/裁剪
  2. 颜色变换:加噪声/亮度/饱和度/颜色反转/直方图均衡/色彩平衡/
  3. 基于GAN网络数据增强:用生成模型,生成不同风格的图像
  4. 高级增强:Cutout/Mixup/One-hot/Cutmix/AutoAugment/Sample pairing/FMix
  5. 网络中增强:RandAugment/Refinement/Mosaic/DropOut/DropOut/DropBlock

下面简单是介绍一些大家可能不太熟悉的概念:
Cutout:图像中挖掉一个矩形快补0
Mixup:image——两张图片线性叠加,label——one-hot形式进行相同的线性叠加
Cutmix:Cutout + Mixup,image——在图片中挖出来的矩形用另外一张图片填充,label——做同样的叠加
Sample pairing:image——两张图片直接做平均,label——选取其中一张
FMix:采用Fourier变换选取挖掉和补充的区域
推荐一下网站:
https://segmentfault.com/a/1190000022784467
https://jishuin.proginn.com/p/763bfbd29660
https://www.pythonf.cn/read/169722

3. 数据增强的代码

3.1 代码

如果大家想深入了解,建议大家跑跑代码

import os
import cv2
import numpy as np

class Resize(object):
    """
    调整大小
    """

    def __init__(self, output_size):
        self.output_size = output_size

    def __call__(self, X, Y):
        _X = cv2.resize(X, self.output_size, interpolation=cv2.INTER_NEAREST)
        w, h = self.output_size
        c = Y.shape[-1]
        # _Y = cv2.resize(Y, self.output_size)
        _Y = np.zeros((h, w, c))
        for i in range(Y.shape[-1]):
            _Y[..., i] = cv2.resize(Y[..., i], self.output_size, interpolation=cv2.INTER_NEAREST)
        return _X, _Y[...,0]

class Clip(object):
    """
    彩色截断
    """
    def __init__(self, mini, maxi=None):
        if maxi is None:
            self.mini, self.maxi = 0, mini
        else:
            self.mini, self.maxi = mini, maxi

    def __call__(self, X, Y):
        mini_mask = np.where(X < self.mini)
        maxi_mask = np.where(X > self.maxi)
        X[mini_mask] = self.mini
        X[maxi_mask] = self.maxi
        return X, Y

class Normalize(object):
    """
   最大最小值归一化
    """
    def __init__(self, axis=None):
        self.axis = axis

    def __call__(self, X, Y):
        mini = np.min(X, self.axis)
        maxi = np.max(X, self.axis)
        X = (X - mini) / (maxi - mini)
        X = 255 * X
        return X, Y

class Standardize(object):
    """
    标准归一化
    """

    def __init__(self, axis=None):
        self.axis = axis

    def __call__(self, X, Y):
        mean =  np.mean(X, self.axis)
        std = np.std(X, self.axis)
        X = (X - mean) / std
        X = 255 * X
        return X, Y

class Flip(object):
    """
    反转
    """
    def __call__(self, X, Y):
        for axis in [0, 1]:
            if np.random.rand(1) < 0.5:
                X = np.flip(X, axis)
                Y = np.flip(Y, axis)
        return X, Y

class Crop(object):
    def __init__(self, min_size_ratio, max_size_ratio=(1, 1)):
        self.min_size_ratio = np.array(list(min_size_ratio))
        self.max_size_ratio = np.array(list(max_size_ratio))

    def __call__(self, X, Y):
        size = np.array(X.shape[:2])
        mini = self.min_size_ratio * size
        maxi = self.max_size_ratio * size
        # random size
        h = np.random.randint(mini[0], maxi[0])
        w = np.random.randint(mini[1], maxi[1])
        # random place
        shift_h = np.random.randint(0, size[0] - h)
        shift_w = np.random.randint(0, size[1] - w)
        X = X[shift_h:shift_h+h, shift_w:shift_w+w]
        Y = Y[shift_h:shift_h+h, shift_w:shift_w+w]

        return X, Y

class CustomFilter(object):
    def __init__(self, kernel):
        self.kernel = kernel

    def __call__(self, X, Y):
        X = cv2.filter2D(X, -1, self.kernel)
        return X, Y

class Sharpen(object):
    """
    锐化
    """
    def __init__(self, max_center=4):
        self.max_center = max_center
        self.identity = np.array([[0, 0, 0],
                                  [0, 1, 0],
                                  [0, 0, 0]])
        self.sharpen = np.array([[ 0, -1,  0],
                                [-1,  4, -1],
                                [ 0, -1,  0]]) / 4

    def __call__(self, X, Y):

        sharp = self.sharpen * np.random.random() * self.max_center
        kernel = self.identity + sharp

        X = cv2.filter2D(X, -1<
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值