深度学习图像分类:使用PyTorch构建图像分类器

在当今数字化的世界中,数据以各种形式大量存在,其中图像数据的增长尤为显著,这主要归功于社交媒体网站和应用。深度学习是专门处理图像数据的一个领域。在这篇文章中,将使用PyTorchAPI构建一个图像分类器。

图像分类器的应用无处不在,例如当打开Google Photos时,会发现一个名为“Things”的集合,其中包含“Sky”、“Hiking”、“Temples”、“Cars”等类别。Google的算法已经将照片分类到这些类别中。另一个主要应用领域是医疗保健。训练有素的模型可以将X射线/扫描分类为疾病阳性/阴性。

将从二分类开始,即将图像分类为两个类别,更像是YES/NO分类。之后,可以修改它并用于多分类。

数据是什么?有许多数据集如MNIST、CIFAR10可以进行分类。在这篇文章中,选择了一个Kaggle数据集:Hot Dog – Not a hotdog。可以在这里找到链接:https://www.kaggle.com/dansbecker/hot-dog-not-hot-dog。它基本上包含要么是热狗要么是非热狗的图像。

可以像这样从两个类别中可视化一些样本:

from PIL import Image Image.open("../input/seefood/train/hot_dog/1053879.jpg") Image.open("../input/seefood/train/not_hot_dog/102037.jpg")

它有两个目录:train和test。目标是构建一个模型,用训练数据训练它,并检查其在测试数据集上的准确性。将使用Pytorch框架。由于其构建和训练模型的简单API,它非常受欢迎。作为第一步,让导入所需的主要库和模块。

import pandas as pd import matplotlib.pyplot as plt import torch import torchvision import torch.nn as nn import torch.optim as optim import torch.nn.functional as F from torchvision import transforms, utils, datasets from torch.utils.data import Dataset, DataLoader from torchvision import datasets

处理数据集。可能经常需要在将图像数据传递给模型之前进行处理。例如,如果所有图像的大小都不同(这通常是大型数据集的情况),那么模型将抛出错误。因此,需要调整它们的大小,并且可以考虑重新缩放像素值。除此之外,可以执行多种转换以进行数据增强。

使用transform.compose()应用多个转换的优雅方式如下所示。

train_transform = transforms.Compose([ transforms.Resize(255), transforms.RandomResizedCrop(224), transforms.CenterCrop(224), transforms.RandomHorizontalFlip(), transforms.ColorJitter(), transforms.ToTensor() ]) test_transform = transforms.Compose([ transforms.Resize(255), transforms.CenterCrop(224), transforms.ToTensor() ])

Pytorch提供了内置的Dataset和DataLoader模块,将在这里使用它们。Dataset存储样本及其对应的标签。而DataLoader则围绕Dataset包装了一个可迭代对象,以便于访问样本。

train_data = datasets.ImageFolder("train_data_directory", transform=train_transform) test_data = datasets.ImageFolder("test_data_directory", transform=test_transform)

可以使用ImageFolder()函数传递包含样本的根目录和需要执行的转换。

train_loader = torch.utils.data.DataLoader(train_data, batch_size=16, shuffle=True) test_loader = torch.utils.data.DataLoader(test_data, batch_size=16)

DataLoader()输入Dataset以及批量大小。在上面的代码中,要求了16个样本的批量。可以使用shuffle参数以确保数据的顺序不影响结果。可以检查数据加载器的输入形状:(批量大小 X 通道数 X 高度 X 宽度)

构建模型:解密层。在这里,将编写即将使用的模型的架构。将定义一个从PyTorchnn.Module派生的类。在类内部,将定义想要的层。

class Binary_Classifier(nn.Module): def __init__(self): super(Binary_Classifier, self).__init__() self.conv1 = nn.Conv2d(in_channels=3, out_channels=10, kernel_size=3) self.conv2 = nn.Conv2d(10, 20, kernel_size=3) self.conv2_drop = nn.Dropout2d() self.fc1 = nn.Linear(720, 1024) self.fc2 = nn.Linear(1024, 2) def forward(self, x): x = F.relu(F.max_pool2d(self.conv1(x), 2)) x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) x = x.view(x.shape[0], -1) x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) x = self.fc2(x) return x

模型类定义应该始终有__init__()方法。在这里,将初始化块/层和其他参数。

谈到神经网络层,图像分类中有三种主要类型:卷积层、最大池化层和丢弃层。

卷积层。卷积层将从输入图像中提取特征并生成特征图/激活。可以使用filters参数决定想要多少激活。基本上,当对图像应用卷积时,核将覆盖整个图像的小部分,并给出一个激活。

池化层。当使用conv2d层时,会得到很多特征图,它们占用了很高的计算空间。为了减少所需的计算时间和空间,可以使用最大池化或平均池化。对于每个补丁/组的地图,只选择最大值以形成输出。下面的图像清楚地展示了工作。

丢弃层。可以从名字中猜出它的功能!它会丢弃大约10-20%的数据。

为什么要这样做?过拟合是在多次迭代/周期对同一数据进行训练时的常见问题。通过丢弃随机选择的10%的数据,模型将能够更好地泛化到新数据。

这总结了在代码中使用的层的简要描述。请注意,最后一层的输出为2,因为它是二分类。

因此,模型已经准备好了!

训练模型。最后是训练部分。在这里需要决定两个关键事项:损失函数和优化器。对于优化器,有多种选择,如SGD、Adam等。使用了交叉熵损失,这是分类问题中的流行选择。还需要设置一个学习率,它决定了模型的学习速度。

model = Binary_Classifier() criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) train_losses = [] for epoch in range(1, num_epochs=15): train_loss = 0.0 model.train() for data, target in train_loader: optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() train_loss += loss.item() * data.size(0)
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485