在之前的文章中,我们主要使用了如MNIST和CIFAR-10等经过预处理的数据集,这些数据集的图像大小和形状都已标准化。然而,在实际应用中,我们通常会遇到不同大小和形状的图像。本文将通过对猫狗分类任务的数据集进行处理,学习如何处理不同大小和形状的图像,应用数据增强技术,并对图像进行归一化处理。
1. 数据集概览
我们首先使用Python的 os
模块收集图像文件名,并利用Pillow库的 Image
类打开图像文件,并提取图像的尺寸信息。通过这些信息,我们可以了解数据集中的图像大小分布,并决定模型输入所需的图像尺寸。
import os
from PIL import Image
import pandas as pd
# 获取数据集文件路径
path = '../data/cat_dog/'
img_names = []
for folder, subfolders, filenames in os.walk(path):
for img in filenames:
img_names.append(folder+'/'+img)
# 提取图像尺寸信息
img_sizes = []
rejected = []
for item in img_names:
try:
with Image.open(item) as img:
img_sizes.append(img.size)
except:
rejected.append(item)
# 将尺寸信息存储在DataFrame中
df = pd.DataFrame(img_sizes)
df[0].describe() # 宽度统计
df[1].describe() # 高度统计
我们发现,大多数图像的宽度和高度都超过了300像素,这为我们后续选择模型输入尺寸提供了依据。
2. 图像预处理
在神经网络中,输入图像的大小、通道数和像素值范围需要保持一致。我们使用PyTorch的 torchvision.transforms
模块进行数据预处理,包括图像尺寸调整、裁剪、翻转、旋转等操作。
import torchvision.transforms as transforms
# 定义图像预处理变换
train_transform = transforms.Compose([
transforms.RandomRotation(10), # 随机旋转10度
transforms.RandomHorizontalFlip(), # 水平翻转
transforms.Resize(224), # 调整大小为224x224
transforms.CenterCrop(224), # 居中裁剪
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406],
[0.229, 0.224, 0.225])
])
3. 数据增强与变换演示
我们可以通过数据增强技术,如旋转、翻转等,生成更多的训练数据。下方代码展示了如何对图像进行多种变换,并将其可视化。
import matplotlib.pyplot as plt
dog = Image.open('../data/cat_dog/train/dog/14.jpg')
display(dog) # 显示原始图像
# 变换并显示图像
transform = transforms.Compose([
transforms.RandomHorizontalFlip(p=1), # 水平翻转
transforms.RandomRotation(30), # 旋转30度
transforms.Resize(224),
transforms.CenterCrop(224),
transforms.ToTensor()
])
im = transform(dog)
plt.imshow(np.transpose(im.numpy(), (1, 2, 0)))
这些变换操作有助于提高模型的泛化能力,避免模型对特定角度或方向的图像过拟合。
4. 图像归一化
在神经网络训练过程中,归一化操作可以加快模型的收敛速度,并提高训练稳定性。我们使用了广泛应用的归一化参数:mean=[0.485, 0.456, 0.406]
和 std=[0.229, 0.224, 0.225]
,这些参数是基于ImageNet数据集统计得出的。
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406],
[0.229, 0.224, 0.225])
])
im = transform(dog)
plt.imshow(np.transpose(im.numpy(), (1, 2, 0)))
归一化后,图像的RGB值被映射到一个标准范围内,有助于神经网络更好地处理图像数据。
5. 反归一化
为了将归一化后的图像还原为原始状态,我们可以进行反归一化操作。这样我们可以在不影响模型训练的情况下,观察归一化后的图像内容。
inv_normalize = transforms.Normalize(
mean=[-0.485/0.229, -0.456/0.224, -0.406/0.225],
std=[1/0.229, 1/0.224, 1/0.225]
)
im_inv = inv_normalize(im)
plt.imshow(np.transpose(im_inv.numpy(), (1, 2, 0)))
结语
在这篇文章中,我们通过对图像处理的实际操作,展示了如何有效地预处理和转换图像数据。无论是图像的尺寸调整、旋转、翻转还是归一化操作,所有这些步骤都是构建强大和泛化能力强的图像分类模型的重要基础。通过归一化,我们能够确保图像的像素值符合模型的要求,从而提高模型的训练效率和准确性。而通过反归一化操作,我们能够轻松地将处理过的图像还原为可视化的原始状态,从而便于我们检查和理解图像的变化。掌握这些图像预处理技巧,是我们进入更加复杂的深度学习图像分类任务的关键一步。
如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!
欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。
谢谢大家的支持!