使用Pytorch对FashionMNIST数据集进行分类的图像分类简介

0
14133
汉娜·摩根(Hannah Morgan)在Unsplash上​​拍摄的照片

In this 博客文章, we will discuss how to build a Convolution Neural Network that can classify Fashion MNIST data using Pytorch on 谷歌 Colaboratory (Free GPU). 的 way we do that is, first we will download the data using Pytorch DataLoader class and then we will use 乐网 -5 architecture to build our model. Finally, we will train our model on GPU and evaluate it on the test data.

注意 :

本教程假定读者具有卷积神经网络的基础知识,并且了解具有CUDA支持的Pytorch张量操作的基础知识。

影像分类

图像分类是从给定类别标签列表中为输入图像分配类别标签的任务。这里的想法是给您一个图像,该图像可能有几个类。图像分类中的任务是为给定图像预测单个类别标签。

广告Coursera Plus标语,包含约翰·霍普金斯大学,谷歌和密歇根大学的课程,突出显示数据科学职业发展的内容

时尚MNIST数据集

时尚mnist精灵
资源: 时尚男装

Fashion-MNIST is a dataset of 扎兰多‘的文章图片-由60,000个示例的训练集和10,000个示例的测试集组成。每个例子是28×28个灰度图像,与来自10个类别的标签关联。Fashion-MNIST 旨在直接 临时替换 for the original MNIST数据集 for benchmarking machine 学习 ing algorithms. It shares the same image size and structure of training and testing splits. According to the creators of Fashion-MNIST, 这里 are some good reasons to replace MNIST数据集:

  • MNIST太简单了。 卷积网络在MNIST上可以达到99.7%。
  • MNIST被过度使用。 In 2017年4月这个Twitter主题,Google Brain研究科学家和深度学习专家Ian Goodfellow呼吁人们远离MNIST。
  • MNIST无法代表现代CV任务,如中所述 2017年4月这个Twitter主题,深度学习专家/ Keras作者FrançoisChollet。

在Colab中运行此笔记本

本文讨论的所有代码都存在于 我的GitHub。您可以使用以下方式打开代码笔记本 any setup by directly opening 我在Cothub上的Jupyter笔记本和Colab 在Google的虚拟机上运行。请点击 这里 ,如果您只是想快速打开笔记本并按照本教程进行操作。要了解有关如何在Colab中执行Pytorch张量的更多信息,请阅读我的 博客文章.

本文其余部分的结构如下

  • Download dataset (Using Dataloader)
  • 可视化数据集
  • 乐网
  • 设置GPU设备
  • 培训和评估LeNet
  • 可视化损失图
  • 然后去哪儿?
  • 结论

导入库

在开始构建网络之前,首先需要导入所需的库。我们正在导入 numpy 因为我们需要将张量图像转换为numpy格式,以便我们可以使用matplotlib 可视化图像。输入 torch for all things related to Pytorch and torchvision to download the Fashion MNIST数据集.

import torchvision
import torchvision.transforms as transforms
import torch
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize = (3,3)) #define the image size

下载数据集

的  torchvision package consists of popular datasets, model architectures, and common image transformations for computer vision. All the images present in the FashionMNIST dataset are stored in PIL format. So we are using transform function to transform the input images to Pytorch tensors.

#transforming the PIL Image to tensors
trainset = torchvision.datasets.FashionMNIST(root = "./data", train = True, download = True, transform = transforms.ToTensor())
testset = torchvision.datasets.FashionMNIST(root = "./data", train = False, download = True, transform = transforms.ToTensor())

Once we download the training data, we will use torch.utils.data.DataLoader to load the dataset. DataLoader also gives us the ability to iterate over the dataset.

#loading the training data from trainset
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle = True)
#loading the test data from testset
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False)

可视化数据集

To visualize the dataset, we will implement a custom function imshow. In the FashionMNIST dataset, there are 10 classes, these will be represented as indices starting from 0 to 9.

classes = ('T-Shirt','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankle Boot')
 def imshow(img):
     npimg = img.numpy() #convert the tensor to numpy for displaying the image
     #for displaying the image, shape of the image should be height * width * channels 
     plt.imshow(np.transpose(npimg, (1, 2, 0))) 
     plt.show()

In this function first, we will convert the Pytorch tensor image to numpy image and then we transpose the image such that image size should be height, width, and channels. After that, we will use matplotlib to display the image.

来自训练数据集的图像

乐网 – 5

 乐网 -5纸质原始图像
乐网 -5体系结构 原始纸.

在本教程中,我们将使用LeNet-5(7层卷积网络)体系结构对Fashion Images进行分类。 Yann LeCun,Leon Bottou, Yosuha Bengio, and 帕特里克·哈夫纳(Patrick Haffner)提出了一个名为LeNet-5的卷积网络,以对美国银行支票上的手写数字进行自动分类。 乐网 -5体系结构非常简单。它是一个7层网络体系结构,不包括输入,包括两个交替的卷积和池化层,最后是三个完全连接的层。 乐网 -5使用平均池对功能进行下采样。此网络中使用了Tanh和Sigmoid激活。

To create 乐网 -5 architecture in Pytorch, we will use nn.Module class and nn.Sequential API to create a custom class called 乐网 .

class  乐网 (nn.Module):
     def init(self):
         super(LeNet, self).init()
         self.cnn_model = nn.Sequential(
             nn.Conv2d(3, 6, kernel_size = 5), (N, 1, 28, 28) -> (N, 6, 24, 24)
             nn.Tanh(),
             nn.AvgPool2d(2, stride = 2), #(N, 6, 24, 24) -> (N, 6, 12, 12)
             nn.Conv2d(6, 16, kernel_size = 5), #(N, 6, 12, 12) -> (N, 6, 8, 8)
             nn.Tanh(),
             nn.AvgPool2d(2, stride = 2)) #(N, 6, 8, 8) -> (N, 16, 4, 4)
          self.fc_model = nn.Sequential(
             nn.Linear(256, 120), # (N, 256) -> (N, 120)
             nn.Tanh(),
             nn.Linear(120, 84), # (N, 120) -> (N, 84)
             nn.Tanh(),
             nn.Linear(84, 10))  # (N, 84)  -> (N, 10)) #10 classes
      def forward(self, x):     
           x = self.cnn_model(x)     
           x = x.view(x.size(0), -1)     
           x = self.fc_model(x)     
           return x

nn.Sequential object executes the series of transformations contained within it, in a sequential manner. In our 乐网 class, we will implement two functions __init__ function (constructor function) and forward function. In _init_ function, we define convolution and downsampling operations inside self.cnn_model and the fully connected network is defined inside self.fc_model.

To define a convolution layer we are using nn.Conv2d() inside our custom class. nn.Conv2d() applies a 2D convolution over an input signal composed of several input planes. It takes a few input parameters such as:

  • in_channels ( 整型 )–输入图像中的通道数
  • out_channels ( 整型 )–卷积产生的通道数
  • kernel_size ( 整型  or  元组 )–卷积核的大小

In the forward function, we will pass the inputs through the convolution block and its output it is flattened or reshaped using view() to match the input dimensions required for the fully connected block of neural network.

设置GPU设备

要检查计算机上连接了多少个CUDA支持的GPU,您可以使用以下代码段。如果您在Colab中执行代码,则将得到1,这表示Colab虚拟机已连接到一个GPU。 torch.cuda 用于设置和运行CUDA操作。它跟踪当前选择的GPU。

>> print(torch.cuda.device_count())
1

需要注意的重要一点是,我们可以将此CUDA支持的GPU卡引用为变量,并将此变量用于任何Pytorch操作。您分配的所有CUDA张量都将在该设备上创建。

>> device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
>> print(device)
cuda: 0

培训和评估LeNet– 5

为了训练我们的卷积神经网络,我们需要定义损失函数和优化算法,即… a variant of gradient descent algorithm. In this case, we will use CrossEntropyLoss to calculate the loss of the network and make use of the Adam optimizer to find the global minima.

#create the model object and move it to GPU
net =  乐网 ().to(device)
loss_fn = nn.CrossEntropyLoss()
opt = optim.Adam(net.parameters())

在开始训练我们的网络之前,让’定义了一个自定义函数来计算我们网络的准确性。

# function to do evaluation (calculate the accuracy) in gpu
def evaluation(dataloader):
     total, correct = 0, 0
     #keeping the network in evaluation mode 
     net.eval()
     for data in dataloader:
         inputs, labels = data
         #moving the inputs and labels to gpu
         inputs, labels = inputs.to(device), labels.to(device)
         outputs = net(inputs)
         _, pred = torch.max(outputs.data, 1)
         total += labels.size(0)
         correct += (pred == labels).sum().item()
     return 100 * correct / total

evaluation function takes a data loader as an input parameter. In this function,

  • 我们正在将网络设置为评估模式。
  • 遍历数据加载器中存在的所有批次。
  • 在输入上调用我们的模型并获得输出。
  • 计算预测的类。
  • 计算正确预测的类的总数并返回最终百分比。

我们将编写一个简单的for循环,以训练网络

%%time
 loss_arr = []
 loss_epoch_arr = []
 max_epochs = 10
 for epoch in range(max_epochs):
     #iterate through all the batches in each epoch
     for i, data in enumerate(trainloader, 0):
     #keeping the network in training mode     
     net.train()     
     inputs, labels = data     
     #moving the input and labels to gpu     
     inputs, labels = inputs.to(device), labels.to(device)     
     #clear the gradients     
     opt.zero_grad()     
     #forward pass     
     outputs = net(inputs)      
     loss = loss_fn(outputs, labels)     
     #backward pass     
     loss.backward()     
     opt.step()     
     loss_arr.append(loss.item()) 
  loss_epoch_arr.append(loss.item()) 

在我们的训练循环中

  • 对于每个时期,我们遍历数据加载器。
  • 获取输入数据和标签,将它们移至GPU(如果有)。
  • 在计算下一批的梯度之前,请重置优化器中存在的任何以前的梯度。
  • 执行前向传递并获得输出。
  • 根据预测输出和实际输出计算损失。
  • 反向传播渐变。
  • 在每个时期结束时,我们都会记录损失值,以绘制和打印进度消息。

网络中使用的超参数如下:

  • 学习率:0.001
  • 损失函数:CrossEntropyLoss
  • 优化器:自适应矩估计(亚当)
  • 纪元= 10

一旦开始训练我们的模型,您应该会看到进度消息:

Epoch: 0/10, Test acc: 79.09, Train acc: 80.22
Epoch: 1/10, Test acc: 82.65, Train acc: 83.46
Epoch: 2/10, Test acc: 84.83, Train acc: 85.87
Epoch: 3/10, Test acc: 85.75, Train acc: 87.00
Epoch: 4/10, Test acc: 85.93, Train acc: 87.48
Epoch: 5/10, Test acc: 86.57, Train acc: 88.28
Epoch: 6/10, Test acc: 87.10, Train acc: 88.87
Epoch: 7/10, Test acc: 87.35, Train acc: 89.31
Epoch: 8/10, Test acc: 87.75, Train acc: 89.61
Epoch: 9/10, Test acc: 88.05, Train acc: 90.23

To evaluate the model on the test dataset, just call our evaluation function and pass the test data loader.

#test on testing data
>> print('Test acc: %0.2f, Train acc: %0.2f' % (evaluation(testloader), evaluation(trainloader)))
Test acc: 88.96, Train acc: 92.15 

仅通过运行网络10个时间段,我就可以达到88.96%的测试数据。

可视化损失图

我们可以针对每个时期绘制网络损耗图,以检查模型性能。

#plotting the loss chart 
plt.plot(loss_epoch_arr)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.show()
损失图

有了您,我们已经成功使用Pytorch成功建立了第一个用于多类别分类的图像分类模型。本文讨论的整个代码都存在于此 GitHub存储库。随意分叉或下载它。

然后去哪儿?

对于我们必须要做的事情  学习  在我们做这些之前,我们 通过实践学习 他们。

亚里士多德 尼科马汉伦理

在本文中,我们讨论了使用Pytorch进行图像分类的基础。如果您想提高网络性能,可以尝试:

  • 修改LeNet以使用ReLU而不是Tanh:比较培训时间和最终网络损失。
  • 使用L2正则化:为了避免过度拟合,可以在torch.optim中使用weight_decay添加L2正则化。
  • 不同的优化器:可以使用带或不带动量的SGD来代替Adam优化器。

使用此框架,您可以为不同的流行数据集(例如CIFAR10或MNIST)建立分类器,需要注意的重要一点是CIFAR10图像具有3个通道(RGB图像),而不是MNIST和FashionMNIST的1个通道。

推荐读物

结论

In this post, we discussed the FashionMNIST dataset and the need to replace MNIST数据集. 的 n we have seen how to download and visualize the FashionMNIST dataset. After that, we have discussed the architecture of 乐网 -5 and trained the 乐网 -5 on GPU using Pytorch nn.Module. If you any issues or doubts while implementing the above code, feel free to ask them in the comment section below or send me a message in 领英 citing this 文章.


注意:  这是一个来宾帖子,本文中的观点属于来宾作者。如果您对发布的任何文章有任何疑问 请访问www.marktechpost.com,网址为: [电子邮件 protected]

广告

发表评论

请输入您的评论!
请在这里输入您的名字

该网站使用Akismet减少垃圾邮件。 了解如何处理您的评论数据.