“在任何一种数据丰富的环境中都很容易找到模式。关键在于确定模式是代表噪声还是信号。”―奈特·西尔弗
本文将介绍将图像处理作为机器学习工作流程的一部分时要遵循的一些最佳实践。
库
import random
from PIL import Image
import cv2
import numpy as np
from matplotlib import pyplot as plt
import json
import albumentations as A
import torch
import torchvision.models as models
import torchvision.transforms as transforms
import torch.nn as nn
from tqdm import tqdm_notebook
from torch.utils.data import DataLoader
from torchvision.datasets import CIFAR10
调整图像大小/缩放图像
调整大小是该领域深度学习实践者所做的最基本的改变。这样做的主要原因是确保我们的深度学习系统收到的输入是一致的。
调整大小的另一个原因是减少模型中的参数数量。更小的维数意味着更小的神经网络,从而节省了我们训练模型所需的时间和计算能力。
信息丢失怎么办?
从较大的图像向下调整大小时,确实会丢失一些信息。但是,根据你的任务,你可以选择愿意为训练时间和计算资源牺牲多少信息。
例如,对象检测任务将要求你保持图像的纵横比,因为目标是检测对象的准确位置。
相反,图像分类任务可能需要将所有图像的大小调整为指定的大小(224x224是一个很好的经验法则)。
img = Image.open("goldendoodle-1234760_960_720.jpeg")
img_resized = Image.Image.resize(img, size=(224, 224))
调整图像大小后,图像如下所示:
为什么要执行图像缩放?
与表格数据类似,用于分类任务的缩放图像可以帮助我们的深度学习模型的学习率更好地收敛到最小值。
缩放可确保特定维度不会主导其他维度。在StackExchange上找到了一个非常好的答案:https://stats.stackexchange.com/questions/185853/why-do-we-need-to-normalize-the-images-before-we-put-them-into-cnn
一种特征缩放是标准化像素值的过程。我们通过从每个通道的像素值中减去每个通道的平均值,然后除以标准差。
在为分类任务训练模型时,这是一种常用的特征工程选择。
mean = np.mean(img_resized, axis=(1,2), keepdims=True)
std = np.std(img_resized, axis=(1,2), keepdims=True)
img_std = (img_resized - mean) / std
注意:与调整大小一样,在执行对象检测和图像生成任务时,可能不希望进行图像缩放。
上面的示例代码演示了通过标准化缩放图像的过程。还有其他形式的缩放,例如居中和标准化。
扩充(分类)
增强图像背后的主要动机是由于计算机视觉任务的可观数据需求。通常,由于多种原因,获取足够的图像进行训练是一项挑战。
图像增强使我们能够通过稍微修改原始样本来创建新的训练样本。
在本例中,我们将研究如何将普通的增强应用于分类任务。我们可以使用Albumentations库来实现这一点:
img_cropped = Image.fromarray(A.RandomCrop(width=225, height=225)(image=np.array(img))['image'])
img_gau_blur = Image.fromarray(A.GaussianBlur(p=0.8)(image=np.array(img_resized))['image'])
img_flip = Image.fromarray(A.Flip(0.8)(image=np.array(img_resized))['image'])