Press "Enter" to skip to content

使用PyTorch构建卷积神经网络

使用PyTorch构建卷积神经网络 四海 第1张

 

简介

 

卷积神经网络(CNN或ConvNet)是一种专门设计用于需要进行对象识别的任务的深度学习算法,如图像分类、检测和分割。CNN能够在复杂的视觉任务上实现最先进的准确性,驱动许多现实生活应用,如监控系统、仓库管理等。

作为人类,我们可以通过分析图案、形状和颜色来轻松识别图像中的对象。CNN也可以通过学习哪些模式对于区分是重要的来进行此识别。例如,在试图区分猫和狗的照片时,我们的大脑专注于独特的形状、纹理和面部特征。CNN学会了捕捉这些相同类型的区分特征。即使对于非常细粒度的分类任务,CNN也能够直接从像素中学习复杂的特征表示。

在本博客文章中,我们将学习关于卷积神经网络以及如何使用它们来构建一个基于PyTorch的图像分类器。

 

卷积神经网络的工作原理

 

卷积神经网络(CNN)常用于图像分类任务。从高层次上看,CNN包含三种主要类型的层:

  1. 卷积层。对输入应用卷积过滤器以提取特征。这些层中的神经元称为过滤器,并捕捉输入中的空间模式。
  2. 池化层。对来自卷积层的特征图进行下采样以合并信息。常用的策略有最大池化和平均池化。
  3. 全连接层。以卷积和池化层的高级特征作为分类的输入。可以堆叠多个全连接层。

卷积过滤器充当特征检测器,学会在看到特定类型的模式或形状时激活。当这些过滤器应用于图像时,它们产生突出显示特定特征存在的特征图。

例如,一个过滤器在看到垂直线时激活,产生一个显示图像中垂直线的特征图。多个过滤器应用于同一输入会产生一组特征图,捕捉图像的不同方面。

  使用PyTorch构建卷积神经网络 四海 第2张  

通过堆叠多个卷积层,CNN可以学习特征的层次结构-从简单的边缘和模式到更复杂的形状和对象。池化层有助于合并特征表示并提供平移不变性。

最后的全连接层将这些学到的特征表示用于分类。对于图像分类任务,输出层通常使用softmax激活函数产生类别的概率分布。

在PyTorch中,我们可以定义卷积、池化和全连接层来构建CNN架构。下面是一些示例代码:

# 卷积层 
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size)
self.conv2 = nn.Conv2d(in_channels, out_channels, kernel_size)

# 池化层
self.pool = nn.MaxPool2d(kernel_size)

# 全连接层 
self.fc1 = nn.Linear(in_features, out_features)
self.fc2 = nn.Linear(in_features, out_features)

 

然后,我们可以使用反向传播和优化算法在图像数据上训练CNN。卷积和池化层将自动学习有效的特征表示,使网络能够在视觉任务上取得强大的性能。

 

开始使用CNN

 

在本部分中,我们将加载CIFAR10数据集,并使用PyTorch构建和训练基于CNN的分类模型。CIFAR10数据集提供了32×32的RGB图像,涵盖了十个类别,非常适合测试图像分类模型。类别以0到9的整数标记。

注意:示例代码是从MachineLearningMastery.com博客修改而来。

首先,我们将使用torchvision下载和加载CIFAR10数据集。我们还将使用torchvision将测试和训练集都转换为张量。

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision

transform = torchvision.transforms.Compose(
    [torchvision.transforms.ToTensor()]
)

train = torchvision.datasets.CIFAR10(
    root="data", train=True, download=True, transform=transform
)

test = torchvision.datasets.CIFAR10(
    root="data", train=False, download=True, transform=transform
)

 

正在下载 https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 到 data/cifar-10-python.tar.gz

100%|██████████| 170498071/170498071 [00:10<00:00, 15853600.54it/s]

正在解压缩 data/cifar-10-python.tar.gz 至 data
文件已经下载并验证完毕

 

接下来,我们将使用数据加载器将图像分成批次。

batch_size = 32
trainloader = torch.utils.data.DataLoader(
    train, batch_size=batch_size, shuffle=True
)
testloader = torch.utils.data.DataLoader(
    test, batch_size=batch_size, shuffle=True
)

 

为了将批次中的图像可视化,我们将使用matplotlib和torchvision的实用函数。

from torchvision.utils import make_grid
import matplotlib.pyplot as plt

def show_batch(dl):
    for images, labels in dl:
        fig, ax = plt.subplots(figsize=(12, 12))
        ax.set_xticks([]); ax.set_yticks([])
        ax.imshow(make_grid(images[:64], nrow=8).permute(1, 2, 0))
        break
show_batch(trainloader)

 

如我们所见,我们有汽车、动物、飞机和船只的图像。

  使用PyTorch构建卷积神经网络 四海 第3张  

接下来,我们将构建我们的CNN模型。为此,我们必须创建一个Python类并初始化卷积、最大池化和全连接层。我们的架构有2个具有池化和线性层的卷积层。

初始化后,我们将在前向函数中按顺序连接所有层。如果您对PyTorch不熟悉,您应该阅读《使用PyTorch进行可解释的神经网络》以了解每个组件的详细信息。

class CNNModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=(3,3), stride=1, padding=1)
        self.act1 = nn.ReLU()
        self.drop1 = nn.Dropout(0.3)
 
        self.conv2 = nn.Conv2d(32, 32, kernel_size=(3,3), stride=1, padding=1)
        self.act2 = nn.ReLU()
        self.pool2 = nn.MaxPool2d(kernel_size=(2, 2))
 
        self.flat = nn.Flatten()
 
        self.fc3 = nn.Linear(8192, 512)
        self.act3 = nn.ReLU()
        self.drop3 = nn.Dropout(0.5)
 
        self.fc4 = nn.Linear(512, 10)
 
    def forward(self, x):
        # 输入 3x32x32, 输出 32x32x32
        x = self.act1(self.conv1(x))
        x = self.drop1(x)
        # 输入 32x32x32, 输出 32x32x32
        x = self.act2(self.conv2(x))
        # 输入 32x32x32, 输出 32x16x16
        x = self.pool2(x)
        # 输入 32x16x16, 输出 8192
        x = self.flat(x)
        # 输入 8192, 输出 512
        x = self.act3(self.fc3(x))
        x = self.drop3(x)
        # 输入 512, 输出 10
        x = self.fc4(x)
        return x

 

我们现在将初始化我们的模型,设置损失函数和优化器。

model = CNNModel()
loss_fn = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

 

在训练阶段,我们将对模型进行10个周期的训练。

  1. 我们使用模型的前向函数进行前向传递,然后使用损失函数进行反向传递,最后更新权重。这一步在所有类型的神经网络模型中几乎是相似的。
  2. 之后,我们使用一个测试数据加载器在每个周期结束时评估模型性能。
  3. 计算模型的准确率并打印结果。
n_epochs = 10
for epoch in range(n_epochs):
    for i, (images, labels) in enumerate(trainloader):
        # 前向传递 
        outputs = model(images)
        loss = loss_fn(outputs, labels)

        # 反向传递和优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in testloader:
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()

    print('第 %d 个周期:准确率:%d %%' % (epoch,(100 * correct / total)))

 

我们的简单模型达到了57%的准确率,这很差。但是,您可以通过添加更多层、运行更多周期和进行超参数优化来提高模型性能。

第 0 个周期:准确率:41 %
第 1 个周期:准确率:46 %
第 2 个周期:准确率:48 %
第 3 个周期:准确率:50 %
第 4 个周期:准确率:52 %
第 5 个周期:准确率:53 %
第 6 个周期:准确率:53 %
第 7 个周期:准确率:56 %
第 8 个周期:准确率:56 %
第 9 个周期:准确率:57 %

 

使用PyTorch,您不必从头开始创建卷积神经网络的所有组件,因为它们已经可用。如果使用`torch.nn.Sequential`,甚至更简单。PyTorch被设计成模块化的,并在构建、训练和评估神经网络方面提供了更大的灵活性。

 

结论

 

在本文中,我们探讨了如何使用PyTorch构建和训练卷积神经网络进行图像分类。我们介绍了卷积层用于特征提取、池化层用于降采样以及全连接层用于预测的CNN架构的核心组件。

我希望本文提供了有关使用PyTorch实现卷积神经网络的概述。CNN是计算机视觉中深度学习的基本架构,而PyTorch使我们能够快速构建、训练和评估这些模型。

    Abid Ali Awan(@1abidaliawan)是一位获得认证的数据科学家,热衷于构建机器学习模型。目前,他专注于内容创作,并在机器学习和数据科学技术方面撰写技术博客。Abid拥有技术管理硕士学位和电信工程学士学位。他的愿景是利用图神经网络为患有心理疾病的学生构建一个AI产品。

Leave a Reply

Your email address will not be published. Required fields are marked *