Advertisement

Deep Learning for Computer Vision with PyTorch: Transfe

阅读量:

作者:禅与计算机程序设计艺术

1.简介

过去几年里

2.基本概念术语说明

2.1 图像分类

作为计算机视觉的核心任务之一,图像分类的目标是识别输入中的物体类别。面对这一挑战,在这一领域中通常会利用现有的预训练网络架构。可将这些预训练网络架构称为特征提取器(Feature Extractor)。借助于这些预训练网络架构对输入图像进行特征提取,并将得到的低维表征空间作为输入数据用于分类。

该种分类模型主要包含两种类型的特征提取方法:一种是基于深度学习的技术。其中一种类型是卷积神经网络(CNN),另一种是深度神经网络(DNN)。这些技术在处理复杂的图像数据时表现出色。传统的特征提取方法主要包括以下几种:首先是SIFT算法用于关键点匹配;其次是HOG直方图用于纹理描述;最后是Canny边缘检测技术。

2.2 迁移学习

迁移学习(Transfer Learning)属于深度学习的重要研究领域之一。其核心在于通过从源数据集(如ImageNet)中获得的经验直接应用于目标数据集(通常情况下,目标数据集可能基于较小规模的数据集,并具有更为丰富的样本分布特性)。具体而言,在这种框架下,我们主要通过预训练模型从源数据集中提取特征,并将这些特征作为基础信息来完成对目标数据集的分类任务。

迁移学习的主要特点有以下几个:

训练效能显著:基于有限的源数据集,在迁移学习技术的应用下,模型的训练时间得以缩减。

适应能力较强:基于目标数据集往往具有不同类别数量和数据规模的特点,在迁移学习中可以实现对不同数据集的推广,并使模型具备更强的通用性。

该模型设计较为简洁:主要基于已有知识库的迁移学习方法,并未引入额外复杂的组件。

迁移学习常用于以下场景:

对于小型图像分类任务:可以通过将源数据集(ImageNet)中的成熟模型应用于目标数据集(自己的数据),有效提高分类性能。

在不同领域中的图像分类任务中,在各个领域之间存在显著的差异;每个领域内的数据集通常具有其特有的特性;可以通过迁移学习方法进行分类。

非监督学习方法可应用于监督学习场景中,在无标注的数据集里,借助迁移学习策略实现模型训练。

2.3 卷积神经网络

卷积神经网络(Convolutional Neural Network, CNN)构成了一个复杂程度较高的神经网络架构,在图像识别领域具有广泛应用并被广泛采用。其工作流程由以下图形展示

基于CNN的方法通过叠加多个具有相同特征的卷积层与池化层来完成基于局部信息构建全局表示的任务。其中每一步骤中通过对局部区域进行提取并整合的操作,最终构建出完整的全局特征表示。每个卷积层通常包含多个过滤器(filter)组件,其中滤波器尺寸多设为3×3至7×7的范围,其作用类似于机器学习中的核函数特性。在图像像素数据与滤波器进行点乘运算后生成一批新的特征图数据,这些新生成的数据在空间维度上有所缩小变化。经过上述操作后得到的新特征图的空间维度有所缩小,随着网络层数逐渐增加,在经过多轮池化操作后,最终所得特征图的空间维度将缩减至1x1甚至消失的状态。为了进一步提高模型性能,我们可以将所有提取到的不同尺度下的不同方向上的信息以某种方式融合在一起形成统一维度的全局特征向量输入到全连接层进行分类处理

除了卷积层和池化层之外还有其他组件 包括激活函数(如ReLU) 归一化层(如Batch Normalization)以及全连接层等 激活函数的作用是调节神经元输出值的范围 这种操作有助于提升模型的非线性表达能力 归一化过程旨在防止过拟合 通过将输入数据标准化处理 可以使各特征在相同的输入条件下产生一致的输出 全连接结构则用于模型分类任务

2.4 自编码器

自编码器(AutoEncoder)是一种基于unsupervised learning设计的神经网络体系,在分析原始数据时能够揭示其内在特征。通常由一对互为镜像设计的编码器与解码器构成,在此过程中将输入信号经过压缩处理;其中 encoder负责将输入映射到低维表示空间;而 decoder则通过分析此低维表示逐步重构出原始输入内容

自编码器的核心概念是,在经过训练后使输入数据的内在结构和特征得以自动表达。这种机制不仅能够实现对原始数据的重建(即重构),而且还能有效推动无监督学习的目标。如上图所示。

自编码器的应用场景十分广泛,在图像处理方面有显著作用。首先,在图像去噪方面,自编码器能够有效提取复杂的图像特征如轮廓与边缘信息,并能有效去除噪声影响;其次,在降维方面,该技术可将高维度数据映射至低维空间中进行处理;第三,在多模态数据处理上具有优势,在不同光照条件、色彩变化以及噪声干扰下都能保持较好的去噪效果,并通过降维使得后续分析更加便捷;此外,在面对不同光照条件下的图像数据时也能有效提取关键特征并实现降噪效果

2.5 数据集

本文使用的图像数据集有三个:MNIST、FashionMNIST和CIFAR-10。MNIST是一个包含handwritten digits的图片数据集,总共包括6万张训练图片和1万张测试图片;每幅图片的尺寸为28x28像素。FashionMNIST是一个关于fashionable apparel的图片数据集,它包含了总共10个类别中的服饰样本;其中训练集共有6万张图片而测试集中有1万张图片;每幅图片均为28x28像素分辨率拍摄。CIFAR-10是一个广泛应用于计算机视觉研究的通用图像数据集;它涵盖了总共十个物体类别;该数据集总共包含了600万个训练样本以及100万个测试样本;每幅图片的标准尺寸为32x32像素。

3.核心算法原理和具体操作步骤以及数学公式讲解

3.1 MNIST

3.1.1 准备数据集

复制代码
    import torch
    from torchvision import datasets, transforms
    
    trainset = datasets.MNIST('dataset/', train=True, download=True, 
                          transform=transforms.Compose([
                              transforms.ToTensor(),
                              transforms.Normalize((0.1307,), (0.3081,))
                          ]))
    testset = datasets.MNIST('dataset/', train=False, download=True,
                         transform=transforms.Compose([
                             transforms.ToTensor(),
                             transforms.Normalize((0.1307,), (0.3081,))
                         ]))
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
    testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.1.2 创建模型

复制代码
    class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)
    
    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.pool(x)
        x = F.relu(self.conv2(x))
        x = self.pool(x)
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x
    
    net = Net()
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.1.3 训练模型

复制代码
    for epoch in range(2):  
      running_loss = 0.0
      for i, data in enumerate(trainloader, 0):
      inputs, labels = data
    
      optimizer.zero_grad()
    
      outputs = net(inputs)
      loss = criterion(outputs, labels)
      loss.backward()
      optimizer.step()
    
      running_loss += loss.item()
      if i % 100 == 99:    # print every 100 mini-batches
          print('[%d, %5d] loss: %.3f' %
                (epoch + 1, i + 1, running_loss / 100))
          running_loss = 0.0
    print('Finished Training')
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.1.4 测试模型

复制代码
    correct = 0
    total = 0
    with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
    print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))
    
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.2 FashionMNIST

3.2.1 准备数据集

复制代码
    import torch
    from torchvision import datasets, transforms
    
    trainset = datasets.FashionMNIST('dataset/', train=True, download=True,
                                 transform=transforms.Compose([
                                    transforms.ToTensor(),
                                    transforms.Normalize((0.1307,), (0.3081,))
                                ]))
    testset = datasets.FashionMNIST('dataset/', train=False, download=True,
                                transform=transforms.Compose([
                                    transforms.ToTensor(),
                                    transforms.Normalize((0.1307,), (0.3081,))
                                ]))
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
    testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.2.2 创建模型

复制代码
    class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)
    
    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.pool(x)
        x = F.relu(self.conv2(x))
        x = self.pool(x)
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x
    
    net = Net()
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.2.3 训练模型

复制代码
    for epoch in range(2):  
      running_loss = 0.0
      for i, data in enumerate(trainloader, 0):
      inputs, labels = data
    
      optimizer.zero_grad()
    
      outputs = net(inputs)
      loss = criterion(outputs, labels)
      loss.backward()
      optimizer.step()
    
      running_loss += loss.item()
      if i % 100 == 99:    # print every 100 mini-batches
          print('[%d, %5d] loss: %.3f' %
                (epoch + 1, i + 1, running_loss / 100))
          running_loss = 0.0
    print('Finished Training')
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.2.4 测试模型

复制代码
    correct = 0
    total = 0
    with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
    print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))
    
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.3 CIFAR-10

3.3.1 准备数据集

复制代码
    import torch
    import torchvision
    import torchvision.transforms as transforms
    
    transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
    
    trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                            shuffle=True, num_workers=2)
    
    testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
    testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                         shuffle=False, num_workers=2)
    classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse','ship', 'truck')
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.3.2 创建模型

复制代码
    import torch.nn as nn
    import torch.nn.functional as F
    
    
    class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)
    
    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
    
    net = Net()
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.3.3 训练模型

复制代码
    import torch.optim as optim
    
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
    
    for epoch in range(2):  # loop over the dataset multiple times
    
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data
    
        # zero the parameter gradients
        optimizer.zero_grad()
    
        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
    
        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0
    
    print('Finished Training')
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

3.3.4 测试模型

复制代码
    correct = 0
    total = 0
    with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
    
    print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))
    
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

全部评论 (0)

还没有任何评论哟~