【pytorch】图片增广

前言

在神经网络的训练过程中,往往需要大量的图片,大量的数据,否则可能会造成过拟合与欠拟合。然而并非都能找到合适的数据,因为标注标签的成本太高了,因此非常有必要利用好手上现有的数据。

图片增广

通俗的来说,就是通过已有标签的图片,生成新的图片。这个听起来有点不可思议,但是确实一个性质有效的方法。
考虑这样一张图片:
【pytorch】图片增广_第1张图片
它是一朵玫瑰,再看下面的图片:【pytorch】图片增广_第2张图片
【pytorch】图片增广_第3张图片
它依然是一朵玫瑰。
不难看出,通过调整亮度、对比度等,以及裁剪,就可以非常快速地生成一张有标签且与原来不同的照片。

torchvision

这是在计算机视觉上,非常好用的一个包,特别是torchvision.transforms几乎可以完成上面提到的操作。
来看一个例子:

class Flower_Dataset(Dataset):
    def __init__(self, path , is_train, augs):
        data_root = pathlib.Path(path)
        all_image_paths = list(data_root.glob('*/*'))
        self.all_image_paths = [str(path) for path in all_image_paths]
        label_names = sorted(item.name for item in data_root.glob('*/') if item.is_dir())
        label_to_index = dict((label, index) for index, label in enumerate(label_names))
        self.all_image = [cv.imread(path) for path in self.all_image_paths]
        self.all_image_labels = [label_to_index[path.parent.name] for path in all_image_paths]
        if is_train:  
            self.transformer = transforms.Compose([
                transforms.ToPILImage(),
                transforms.Resize((224,224)),
                augs,
                transforms.ToTensor(),
                transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
            ])
        else:
            self.transformer = transforms.Compose([
                transforms.ToPILImage(),
                transforms.Resize((224,224)),
                transforms.ToTensor(),
                transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
            ])
        
    def __getitem__(self, index):
        img = self.all_image[index]
        img = self.transformer(img)
        label = self.all_image_labels[index]
        label = torch.tensor(label)
        return img, label

    def __len__(self):
        return len(self.all_image_paths)

color_aug = torchvision.transforms.ColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.5)
augs = torchvision.transforms.Compose([torchvision.transforms.RandomHorizontalFlip(), color_aug])

这里就定义了一个带有图片增广的数据集,它可以将图片随机的水平反转,以及改变亮度。

  • 水平翻转和垂直反转需要慎用,因为某些东西反转之后就不是原来的东西了。比如在识别英文字母中,字母b反转后就成了p。这不仅仅不能给神经网络带来新的数据,反而还会误导神经网络。

作用与意义

图片增广在图像识别的作用是非常巨大的。

  1. 通过十分廉价的方式,仅仅需要多一点算力,就可以获得大量数据。一张图片通过随机裁剪,改变亮点等,理论上是可以得到无数张照片的。
  2. 避免了过拟合,通过各种变换,能使得神经网络看到更多的情况下的图片,提高泛化能力。

不足与需要注意的地方

虽然是图片增广有着不少的作用,但是它也有一些不足与需要注意的地方。

  1. 反转要慎重,这一点在上面也有提过。
  2. 可能造成欠拟合,这种情况往往是图片增广与实际情况不同导致的。比如一台自动贩卖机,它需要识别顾客从贩卖机中拿走的物品。在正常情况下,贩卖机中都是有灯光照射,物体明亮。而如果在图片增广中产生了大量昏暗的图片(训练集与测试集的分布不同),就会让神经网络学会如何识别昏暗的物体,而不是识别明亮的物体。
  3. 可能误导神经网络,比如在裁剪图片时,将一只猫裁剪的只剩下一条尾巴,这显然会误导神经网络在识别棍子等柱状物体。也就是说经过图片增广后可能会改变图片的标签。

你可能感兴趣的:(笔记,#,神经网络,Python,pytorch,深度学习,python,计算机视觉)