数据增强方法--Cutout实现及结果分析

问题背景

近年来,深度学习在计算机视觉领域取得了相当大的进展,并且在许多具有挑战性的任务中取得了最新的性能,如对象识别、语义分割、图像字幕等等。这些改进在很大程度上可以归因于卷积神经网络的使用,它能够学习图像的复杂层次特征表示。但是随着要解决的任务的复杂性的增加,模型的资源利用率也在增加:内存占用、参数数量、推理时间和功耗。现代网络通常包含数千万到数亿个的学习参数,这些参数为此类任务提供了必要的表达能力,但是随着表达能力的增加,过拟合的可能性也在增加,这导致了模型的较差的泛化能力。
最常见的挑战是缺乏高质量的数据或数据集中的类别不平衡。如今,最有效的dnn非常复杂,因此需要大量的数据,而这在很多情况下可能很难提供。例如,非常流行的CNN架构VGG16由16层神经元组成,包含1.38亿个参数。此外,新架构的性能通常在ImageNet上进行测试,该数据集包含来自1000个非重叠类别的100多万张图像。
由于数据增强的易于实现和有效性,因此数据增强几乎无处不在。同时也产生了许多数据增强的方法。
常用数据增强方法

Cutout简介

Cutout是一种卷积神经网络的正则化技术,它包括去除输入图像的连续部分,有效地用现有样本的部分遮挡版本来增强数据集。这种技术可以解释为输入空间中dropout的扩展。
Cutout示例
Cutout的主要灵感来自于在许多计算机视觉任务中都很常见的物体遮挡的问题,如物体识别、跟踪等。通过生成模拟遮挡实例的新图像,不仅能更好地为现实世界中遇到遮挡做准备,而且在决策时还要考虑更多的图像上下文。

实现细节

在训练阶段在输入图片的随机位置使用一个固定大小的矩形区域,使用0进行填充。然后对数据集进行归一化。注意区域大小参数的设置,论文指出这在很大程度上会影响性能。值得注意的是,进行Cutout的区域可以不在图像中,这也是Cutout能取得较好效果的重要的地方。同时论文指出Cutout的操作可以在CPU上执行,从而可以与在GPU上的训练任务并行执行,并不会增加运行时间。

实验设置

  • 数据集:Tiny-imagenet-200.Tiny
    Imagenet是斯坦福大学提供的图像分类数据集,其中包含200个类别,每个类别包含500张训练图像,50张验证图像及50张测试图像
  • 模型:Resnet-18,Resnet-50
  • 实验设计:先实现Cutout方法,然后仿照论文中的实验采用对比的形式,构建网络模型,比较采用与不采用Cutout的分类结果,评价指标使用准确率,通过分类结果分析Cutout的效果。
  • 实验对比方法:做了4个实验,分别是不使用Cutout,使用Cutout,使用随机旋转+水平翻转,使用Cutout+随机旋转+水平翻转,比较4个实验的表现情况。
  • 参数设置:随机旋转20度,水平翻转概率为0.5,Cutout大小为16*16的矩形区域。训练15个epoch,学习率初始为0.01,在5,10,14个epoch缩小5倍。

代码实现

import torch
import numpy as np

## 实现了圆形与矩形的遮挡区域
class Cutout(object):
    """Randomly mask out one or more patches from an image.

    Args:
        n_holes (int): Number of patches to cut out of each image.
        length (int): The length (in pixels) of each square patch.
        radius (int): The radius (in pixels) of each square patch
        option(str): The type of hole
    """
    def __init__(self, n_holes = 1, length = 0, radius = 0, option = 'rectangle'):
        
        self.n_holes = n_holes
        self.length = length
        self.radius = radius
        self.option = option
        
    def __call__(self, img):
        """
        Args:
            img (Tensor): Tensor image of size (C, H, W).
        Returns:
            Tensor: Image with n_holes of dimension length x length cut out of it.
        """
        
        h = img.size(1)         
        w = img.size(2)

        mask = np.ones((h, w), np.float32)
        if self.option == 'rectangle':
            for n in range(self.n_holes):
                y = np.random.randint(h)         # Random location
                x = np.random.randint(w)

                y1 = np.clip(y - self.length // 2, 0, h)  #The clipping area can be out of the picture
                y2 = np.clip(y + self.length // 2, 0, h)
                x1 = np.clip(x - self.length // 2, 0, w)
                x2 = np.clip(x + self.length // 2, 0, w)

                mask[y1: y2, x1: x2] = 0.

            mask = torch.from_numpy(mask)
            mask = mask.expand_as(img)
            img = img * mask
        if self.option == 'circle':
            for n in range(self.n_holes):
                y1 = np.random.randint(h)
                x1 = np.random.randint(w)            
                # Find all the pixels
                circle = [(x1-x,x2-y) for x in range(-self.radius,self.radius+1) for y in range(-self.radius,self.radius+1)  if x**2 + y**2 <= self.radius**2 ]
            for i in range(len(circle)): 
                mask[circle[i][0]][circle[i][1]] = 0.
            mask = torch.from_numpy(mask)
            mask = mask.expand_as(img)
            img = img * mask
        return img

结果展示

train_acc
val_acc

参考文献

Improved Regularization of Convolutional Neural Networks with Cutout.Terrance DeVries1and Graham W. Taylor1,21University of Guelph2 Canadian Institute for Advanced Research and Vector Institute

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cutout数据增强是一种常用的数据增强方法,可以增加模型的泛化能力,从而提高模型的性能。其主要思想是在输入的图像中随机挖去一块矩形区域,使得模型在学习时对缺失的信息进行补充,从而增加模型的鲁棒性。 以下是Python实现Cutout数据增强的示例代码: ```python import numpy as np import cv2 def cutout(img, size=16): h, w, c = img.shape mask = np.ones((h, w, c), np.float32) y = np.random.randint(h) x = np.random.randint(w) y1 = np.clip(y - size // 2, 0, h) y2 = np.clip(y + size // 2, 0, h) x1 = np.clip(x - size // 2, 0, w) x2 = np.clip(x + size // 2, 0, w) mask[y1:y2, x1:x2, :] = 0 img = img * mask return img ``` 其中,函数cutout接受一个图像和一个整数参数size,表示挖去矩形区域的大小。在函数内部,首先获取输入图像的高度、宽度和通道数,然后随机生成挖去矩形区域的位置。根据矩形区域的位置和大小,生成一个遮罩矩阵,将矩形区域内的像素值设置为0。最后将原始图像与遮罩矩阵相乘,即可得到增强后的图像。 使用cutout数据增强可以通过以下方式实现: ```python img = cv2.imread('image.jpg') # 显示原始图像 cv2.imshow('Original Image', img) # 进行cutout数据增强 img = cutout(img) # 显示增强后的图像 cv2.imshow('Augmented Image', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 其中,cv2.imread()函数用于读取图像,cv2.imshow()函数用于显示图像,cv2.waitKey()函数用于等待用户按下按键,cv2.destroyAllWindows()函数用于关闭窗口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值