使用 PyTorch 进行图像分类

发布日期:2026-07-09 05:38:02   来源 : 杭州电子商务研究院    浏览量 :21
杭州电子商务研究院 发布日期:2026-07-09 05:38:02  
21

介绍

PyTorch 彻底改变了解决计算机视觉或 NLP 问题的方法。它是一个动态深度学习框架,易于学习和使用。

在本指南中,我们将从头到尾构建一个图像分类模型,从探索性数据分析 (EDA) 开始,这将帮助您了解图像的形状和类别的分布。您将学习准备数据以获得最佳建模结果,然后构建一个卷积神经网络 (CNN),根据图像是否包含仙人掌对图像进行分类。

点击此处下载正在进行的 Kaggle 竞赛中的空中仙人掌数据集。此数据集包含 RGB 图像通道,而不是 MNIST 黑白图像。因此,它非常适合初学者用来探索和使用 CNN。这也是对猫和狗以外的其他事物进行分类的机会。

导入库和数据

首先,使用numpypandassklearn导入torchtorchvision框架及其库。以下代码中使用的库和函数包括:

  • 变换,用于基本图像变换
  • torch.nn. functional,包含有用的激活函数
  • DatasetDataloader,PyTorch 的数据加载实用程序
      import pandas as pd 
import matplotlib.pyplot as plt 
import torch
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms

from torch.utils.data import Dataset, DataLoader
from sklearn.model_selection import train_test_split

%matplotlib inline
    
      import os
os.getcwd()
# place the files in your IDE working dicrectory .
labels = pd.read_csv(r'/aerialcactus/train.csv')
submission = pd.read_csv(r'/aerialcactus/sample_submission.csv)

train_path = r'/aerialcactus/train/train/'
test_path = r'/aerialcactus/test/test/'
    
      labels.head()
    
      labels.tail()
    
      labels['has_cactus'].value_counts()
    
      label = 'Has Cactus', 'Hasn\'t Cactus'
plt.figure(figsize = (8,8))
plt.pie(labels.groupby('has_cactus').size(), labels = label, autopct='%1.1f%%', shadow=True, startangle=90)
plt.show()
    

根据饼图,数据偏向于一个类别。不平衡的数据会影响最终结果。我们已经有足够的数据让 CNN 产生结果,因此不需要任何数据采样或增强。

图像预处理

 数据集中的图像通常不具有相同的像素强度和尺寸。在本节中,您将通过标准化像素值来预处理数据集。下一个必需的过程是将原始图像转换为张量,以便算法可以处理它们。

      import matplotlib.image as img
fig,ax = plt.subplots(1,5,figsize = (15,3))

for i,idx in enumerate(labels[labels['has_cactus'] == 1]['id'][-5:]):
    path = os.path.join(train_path,idx)
    ax[i].imshow(img.imread(path))
    
      fig,ax = plt.subplots(1,5,figsize = (15,3))
for i,idx in enumerate(labels[labels['has_cactus'] == 0]['id'][:5]):
    path = os.path.join(train_path,idx)
    ax[i].imshow(img.imread(path))
    

使用以下代码通过定义的平均值和标准差来标准化图像,因为使用原始图像数据不会产生所需的结果。

      import numpy as np
import matplotlib.pyplot as plt

def imshow(image, ax=None, title=None, normalize=True):
    if ax is None:
        fig, ax = plt.subplots()
    image = image.numpy().transpose((1, 2, 0))

    if normalize:
        mean = np.array([0.485, 0.456, 0.406])
        std = np.array([0.229, 0.224, 0.225])
        image = std * image + mean
        image = np.clip(image, 0, 1)

    ax.imshow(image)
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['left'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.tick_params(axis='both', length=0)
    ax.set_xticklabels('')
    ax.set_yticklabels('')

    return ax
    
      class CactiDataset(Dataset):
    def __init__(self, data, path , transform = None):
        super().__init__()
        self.data = data.values
        self.path = path
        self.transform = transform
        
    def __len__(self):
        return len(self.data)
    
    def __getitem__(self,index):
        img_name,label = self.data[index]
        img_path = os.path.join(self.path, img_name)
        image = img.imread(img_path)
        if self.transform is not None:
            image = self.transform(image)
        return image, label
    

正常化

      train_transform = transforms.Compose([transforms.ToPILImage(),
                                      transforms.ToTensor(),
                                      transforms.Normalize(means,std)])

test_transform = transforms.Compose([transforms.ToPILImage(),
                                     transforms.ToTensor(),
                                     transforms.Normalize(means,std)])

valid_transform = transforms.Compose([transforms.ToPILImage(),
                                     transforms.ToTensor(),
                                     transforms.Normalize(means,std)])
    

分割数据集

模型的学习效果取决于数据的种类和数量。我们需要使用train_test_split将数据分为训练集和验证集。

训练数据集:模型从该数据集的示例中进行学习。它将参数拟合到分类器中。

验证数据集:验证数据集中的示例用于调整超参数,例如学习率和时期数。创建验证集的目的是避免模型过度拟合。它是一个检查点,用于了解模型是否与训练数据集很好地契合。

测试数据集:此数据集测试模型的最终演变,衡量模型的学习效果和对所需输出的预测。它包含未见过的真实数据。

      train, valid_data = train_test_split(labels, stratify=labels.has_cactus, test_size=0.2)
    
      train_data = CactiDataset(train, train_path, train_transform )
valid_data = CactiDataset(valid_data, train_path, valid_transform )
test_data = CactiDataset(submission, test_path, test_transform )
    

定义超参数的值。

      # Hyper parameters

num_epochs = 35
num_classes = 2
batch_size = 25
learning_rate = 0.001
    

每当您初始化一批图像时,默认情况下它都会在 CPU 上进行计算。函数torch.cuda.is_available()将检查是否存在 GPU。如果存在 CUDA,.device("cuda")会将张量路由到 GPU 进行计算。

      # CPU or GPU

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
device
    

该设备将使用带有单个 GPU 处理器的 CUDA。这将使我们的计算速度更快。如果您的系统中有 CPU,那就没问题。您可以使用 Google Colab,它提供免费的GPU

在下面的代码中,dataloader结合了数据集和采样器,并提供了给定数据集的可迭代对象。da ​​taset()指示从可用数据中加载哪个数据集。有关详细信息,请阅读此文档

      train_loader = DataLoader(dataset = train_data, batch_size = batch_size, shuffle=True, num_workers=0)
valid_loader = DataLoader(dataset = valid_data, batch_size = batch_size, shuffle=False, num_workers=0)
test_loader = DataLoader(dataset = test_data, batch_size = batch_size, shuffle=False, num_workers=0)
    
      import numpy as np
import matplotlib.pyplot as plt

def imshow(image, ax=None, title=None, normalize=True):
    if ax is None:
        fig, ax = plt.subplots()
    image = image.numpy().transpose((1, 2, 0))

    if normalize:
        mean = np.array([0.485, 0.456, 0.406])
        std = np.array([0.229, 0.224, 0.225])
        image = std * image + mean
        image = np.clip(image, 0, 1)

    ax.imshow(image)
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['left'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.tick_params(axis='both', length=0)
    ax.set_xticklabels('')
    ax.set_yticklabels('')

    return ax
    
      trainimages, trainlabels = next(iter(train_loader))

fig, axes = plt.subplots(figsize=(12, 12), ncols=5)
print('training images')
for i in range(5):
    axe1 = axes[i] 
    imshow(trainimages[i], ax=axe1, normalize=False)

print(trainimages[0].size())
    

下一步是制作一个从操纵的训练数据集中学习的 CNN 模型。

设计卷积神经网络 (CNN)

如果您尝试识别给定图像中的物体,您会注意到颜色、形状和大小等特征,这些特征可帮助您识别图像中的物体。CNN 使用相同的技术。CNN 中的两个主要层是卷积层和池化层,模型在其中记录图像中的特征,以及全连接 (FC) 层,进行分类。

图片来源:https://commons.wikimedia.org/wiki/File:Typical_cnn.png

卷积层

从数学上讲,卷积是对两个函数执行的操作,以产生第三个函数。卷积在语音处理(1 维)、图像处理(2 维)和视频处理(3 维)中运行。卷积层在图像上形成一个厚过滤器。

卷积层的输出形状受内核大小、输入维度、填充和步幅(窗口移动的像素数)的选择的影响。

在这个模型中,使用了 3x3 大小的内核。它将有 27 个权重和 1 个偏差。

这就是CNN背后发生的事情。

<div class
以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据