PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

本文概述

  • 图像转换部分的更改
  • 实施, 培训和验证部分的更改
  • 测试部分的更改
  • 完整的代码
在上一个主题中, 我们发现带卷积神经网络的LeNet模型能够对MNIST数据集图像进行分类。 MNIST数据集包含作为灰度图像的图像数量, 但是在CHIFAR-10数据集中, 图像是彩色的并且具有不同的含义。因此, 我们最大的问题是我们的LeNet模型将对CIFAR-10数据集的图像进行分类。我们将复制上一个主题的代码, 即CNN的测试, 并对图像的图像转换, 实现, 训练, 验证和测试部分进行以下更改:
注意:如果你是这里的新手, 则必须有效地了解我们之前的主题, 才能有效地理解这一点。 图像转换部分的更改 在” 图像变换” 部分中, 我们将进行以下更改:
步骤1:
在这里, 我们正在使用CIFAR-10数据集, 因此第一步是加载CIFAR-10数据集而不是MNIST数据集。我们通过以下方式对训练数据集和验证数据集进行更改来加载CIFAR-10数据集:
training_dataset=datasets.CIFAR10(root='./data', train=True, download=True, transform=transform1)validation_dataset=datasets.CIFAR10(root='./data', train=False, download=True, transform=transform1)

第2步:
在下一步中, 我们将在transform语句中进行更改。我们知道MNIST图像的尺寸为28 x 28像素, 而CIFAR10图像的尺寸为32 x 32像素。因此, 我们将对transform.compose()方法的第一个参数进行如下更改:
transform1=transforms.Compose([transforms.Resize((32, 32)), transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5, ))])

现在, 如果我们绘制CIFAR-10图像, 它将提供以下输出:
PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

文章图片
第三步:
在CIFAR10图像中, 我们知道图像是在类别中分类的。为了更好地理解和可视化, 我们指定每个图像及其类。因此, 我们声明了一个类列表, 在其中, 我们在im_convert()方法之后按顺序指定了这些类:
classes={'plane', 'car', 'bird', 'cat', 'dear', 'dog'.'frog', 'horse', 'ship', 'truck'}

步骤4:
标签表示这些类的有序数字表示形式, 因此我们将使用每个标签来索引我们的类列表, 并且输出将是适当的类。我们将set_title()方法更改为:
ax.set_title(classes[labels[idx].item()])

它将给出以下输出:
PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

文章图片
实施, 培训和验证部分的更改 我们的Lenet模型是针对MNIST图像实现的。 MNIST图像是灰度图像, 但是我们必须为包含彩色图像的CIFAR-10数据集实现模型。因此, 我们必须在代码中进行以下更改:
步骤1:
以前, 我们使用一个通道的灰度图像, 现在使用传递到神经网络的三通道彩色图像。因此, 在第一卷积层中, 我们将3而不是1设置为:
self.conv1=nn.Conv2d(3, 20, 5, 1)

第2步:
现在, 我们必须训练大量参数。在5 x 5内核卷积之后, 图像变为28 x 28, 然后在下一个合并14 x 14时执行另一个具有相同大小内核的卷积。图像再次变小了4乘4减, 变成了10乘10。最后, 在另一个最大池化的情况下, 将被馈送到完全连接的网络中的矢量将是5乘5乘50。
因此, 我们必须将初始化程序中的第一个完全连接的层更改为:
self.fully1=nn.Linear(5*5*50, 500)

第三步:
现在, 我们还必须更改输出的形状。为此, 我们必须在forward函数中将view语句更改为:
x=x.view(-1, 5*5*50) #Reshaping the output into desired shape

现在, 我们找到总损失和验证损失以及准确性和验证准确性, 并将其绘制出来, 然后将为我们提供以下输出:
PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

文章图片
PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

文章图片
步骤4:
现在, 我们将使用它来预测来自网络的图像, 从而简单地获得模型准确性的视觉效果。我们将使用以下图像:https://3c1703fe8d.site.internapcdn.net/newman/gfx/news/hires/2018/2-dog.jpg
当我们绘制此图像时, 它将显示为:
PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

文章图片
步骤5:
在下一步中, 我们将删除反转和转换方法, 因为这一次我们的图像将被极大地转换为生物级格式, 并且我们的网络已经接受了彩色图像的培训。我们将变换图像并将其绘制为:
url='https://ichef.bbci.co.uk/news/912/cpsprodpb/160B4/production/_103229209_horsea.png'response=requests.get(url, stream=True)img=Image.open(response.raw)img=transform1(img) plt.imshow(im_convert(img))

PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

文章图片
转换后, 我们获得了图像的更抽象的表示。它减小为32 x 32的较小表示。
步骤6:
现在, 我们对该图像进行预测, 以便对图像进行压缩并使用以下类找到预测:
image1=img.to(device).unsqueeze(0) output=model(image1)_, pred=torch.max(output, 1)print(classes[pred.item()])

PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

文章图片
测试部分的更改 测试部分与之前相同。 CNN测试的过程将相同, 但在彩色图像中, 我们将使用类来预测每个验证图像, 如下所示:
dataiter=iter(validation_loader)images, labels=dataiter.next()images_=images.to(device)labels=labels.to(device)output=model(images_)_, preds=torch.max(output, 1)fig=plt.figure(figsize=(25, 4))for idx in np.arange(20):ax=fig.add_subplot(2, 10, idx+1, xticks=[], yticks=[])plt.imshow(im_convert(images[idx]))ax.set_title("{}({})".format(str(classes[preds[idx].item()]), str(classes[labels[idx].item())), color=("green" if preds[idx]==labels[idx] else "red"))plt.show()

PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试

文章图片
【PyTorch LeIF模型对CIFAR-10数据集的Pytorch测试】似乎可以准确预测大多数图像。总的来说, 我们的模型能够很好地将自己根据训练后的参数归纳为新数据。
完整的代码
import torchimport matplotlib.pyplot as pltimport numpy as npimport torch.nn.functional as funcimport PIL.ImageOpsfrom torch import nnfrom torchvision import datasets, transforms import requestsfrom PIL import Imagedevice=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")transform1=transforms.Compose([transforms.Resize((32, 32)), transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5, ))])training_dataset=datasets.CIFAR10(root='./data', train=True, download=True, transform=transform1)validation_dataset=datasets.CIFAR10(root='./data', train=False, download=True, transform=transform1)training_loader=torch.utils.data.DataLoader(dataset=training_dataset, batch_size=100, shuffle=True)validation_loader=torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=100, shuffle=False)def im_convert(tensor):image=tensor.cpu().clone().detach().numpy()image=image.transpose(1, 2, 0)print(image.shape)image=image*(np.array((0.5, 0.5, 0.5))+np.array((0.5, 0.5, 0.5)))image=image.clip(0, 1)return imageclasses=('plane', 'car', 'bird', 'cat', 'dear', 'dog', 'frog', 'horse', 'ship', 'truck')dataiter=iter(training_loader)images, labels=dataiter.next()fig=plt.figure(figsize=(25, 4))for idx in np.arange(20):ax=fig.add_subplot(2, 10, idx+1)plt.imshow(im_convert(images[idx]))ax.set_title(classes[labels[idx].item()])class LeNet(nn.Module):def __init__(self):super().__init__()self.conv1=nn.Conv2d(3, 20, 5, 1)self.conv2=nn.Conv2d(20, 50, 5, 1)self.fully1=nn.Linear(5*5*50, 500)self.dropout1=nn.Dropout(0.5) self.fully2=nn.Linear(500, 10)def forward(self, x):x=func.relu(self.conv1(x))x=func.max_pool2d(x, 2, 2)x=func.relu(self.conv2(x))x=func.max_pool2d(x, 2, 2)x=x.view(-1, 5*5*50) #Reshaping the output into desired shapex=func.relu(self.fully1(x)) #Applying relu activation function to our first fully connected layerx=self.dropout1(x)x=self.fully2(x) #We will not apply activation function here because we are dealing with multiclass datasetreturn xmodel=LeNet().to(device)criteron=nn.CrossEntropyLoss()optimizer=torch.optim.Adam(model.parameters(), lr=0.00001) epochs=12loss_history=[]correct_history=[]val_loss_history=[]val_correct_history=[]for e in range(epochs):loss=0.0correct=0.0val_loss=0.0val_correct=0.0for input, labels in training_loader:input=input.to(device)labels=labels.to(device)outputs=model(input)loss1=criteron(outputs, labels)optimizer.zero_grad()loss1.backward()optimizer.step()_, preds=torch.max(outputs, 1)loss+=loss1.item()correct+=torch.sum(preds==labels.data)else:with torch.no_grad():for val_input, val_labels in validation_loader:val_input=val_input.to(device)val_labels=val_labels.to(device)val_outputs=model(val_input)val_loss1=criteron(val_outputs, val_labels) _, val_preds=torch.max(val_outputs, 1)val_loss+=val_loss1.item()val_correct+=torch.sum(val_preds==val_labels.data)epoch_loss=loss/len(training_loader)epoch_acc=correct.float()/len(training_loader)loss_history.append(epoch_loss)correct_history.append(epoch_acc)val_epoch_loss=val_loss/len(validation_loader)val_epoch_acc=val_correct.float()/len(validation_loader)val_loss_history.append(val_epoch_loss)val_correct_history.append(val_epoch_acc)print('training_loss:{:.4f}, {:.4f}'.format(epoch_loss, epoch_acc.item()))print('validation_loss:{:.4f}, {:.4f}'.format(val_epoch_loss, val_epoch_acc.item()))plt.plot(loss_history, label='Training Loss')plt.plot(val_loss_history, label='Validation Loss')plt.legend()plt.show()plt.plot(correct_history, label='Training accuracy')plt.plot(val_correct_history, label='Validation accuracy')plt.legend()plt.show()url='https://3c1703fe8d.site.internapcdn.net/newman/gfx/news/hires/2018/2-dog.jpg'response=requests.get(url, stream=True)img=Image.open(response.raw)img=transform1(img)image1=img.to(device).unsqueeze(0)output=model(image1)_, pred=torch.max(output, 1)print(classes[pred.item()])dataiter=iter(validation_loader)images, labels=dataiter.next()images_=images.to(device)labels=labels.to(device)output=model(images_)_, preds=torch.max(output, 1)fig=plt.figure(figsize=(25, 4))for idx in np.arange(20):ax=fig.add_subplot(2, 10, idx+1, xticks=[], yticks=[])plt.imshow(im_convert(images[idx]))ax.set_title("{}({})".format(str(classes[preds[idx].item()]), str(classes[labels[idx].item()]), color=("green" if preds[idx]==labels[idx] else "red"))plt.show()

    推荐阅读