PyTorch 教程-在PyTorch中实现卷积神经网络

我们使用了一个深度神经网络对无尽的数据集进行分类,发现它并不能最好地分类我们的数据。当我们使用深度神经网络时,模型的准确性不足,并且模型有待改进。卷积神经网络将帮助实现这一改进。让我们开始实现我们的卷积神经网络用于图像识别。
实现图像识别的CNN的步骤如下:
步骤1:
在第一步中,我们将定义一个类,该类将用于创建我们的神经模型实例。CNN模型包括LeNet模型,AlexNet模型,ZFNet模型和GoogleNet模型。这些模型的复杂性和性能逐渐增加,我们将使用LeNet模型。该模型简单、有效,应足以对无尽的数据集进行准确分类。
LeNet模型如下:
该类将继承自nn模块,因此我们首先要导入nn包。
from torch import nn
class LeNet (nn.Module):
我们的类将跟随一个init()方法。在init()方法中,第一个参数将始终为self。
def __init__(self):
步骤2:
在第二步中,我们调用init()方法以提供各种方法和属性。我们将使用四个输入参数初始化卷积层,即输入通道数(这是一个输入层,所以我们将使用1个输入通道),输出通道数(我们将使用20个输出通道进行有效的特征提取),卷积核大小(我们将使用5作为卷积核大小)和步幅长度(因为我们选择了更大的步幅长度,将导致提取效果较差)。我们将将整个命令解开为一个变量,并将其附加到我们类内的self对象。
同样,我们将定义我们的下一个卷积层,并根据需要调整其参数。
super().__init__()
self.conv1=nn.Con2d(1, 20, 5, 1)
self.conv2=nn.Con2d(20, 50, 5, 1)
步骤3:
在接下来的步骤中,我们将使用nn.Linear()定义两个全连接层,并提供适当的参数。
第一个卷积层将减小输入图像的尺寸,从28乘28减小到24乘24。然后,数据将通过一个2乘2的池化层,该层将切割图像的大小并将其转换为12乘12。下一个卷积层将图像的尺寸从12乘12减小到8乘8。另一个5乘5的池化层将图像的大小从8乘8减小到4乘4。因此,传递到第一个全连接层的输入通道将是4×4×50,第二个参数为500个输出通道。
同样,我们将根据需要定义第二个全连接层的参数。
self.fully1=nn.Linear(4*4*50,500)
self.fully2=nn.Linear(500,10)
步骤4:
现在,我们将在forward函数中定义池化层和每个层的激活函数,但在此之前,我们将导入torch.nn.functional包,然后我们将使用forward()函数,并将self作为第一个参数,x作为我们尝试进行预测的任何输入。
import torch.nn.functional as func
def forward(self,x):
现在,我们将定义我们的relu函数并将其连接到我们的第一个卷积层,然后我们将使用max_pool2d()和适当的参数定义池化层。
第一个参数将是前馈的x值,接下来两个参数将定义最大池化核的大小,并将解开为x变量。
同样,我们将为我们的第二个卷积和池化层执行此过程。
x=func.relu(self.conv1(x))
x=func.max_pool2d(x, 2,2)
x=func.relu(self.conv1(x))
x=func.max_pool2d(x, 2,2)
x=x.view(-1, 4*4*50) #Reshaping the output into desired shape
x=func.relu(self.fully1(x)) #Applying relu activation function to our first fully connected layer
x=self.fully2(x) #We will not apply activation function here because we are dealing with multiclass dataset
return x
步骤5:
在下一步中,我们将设置我们的模型构造函数。在初始化器中不需要传递任何内容。
model=LeNet()
我们的CNN模型已经实现,现在,我们将讨论其在CNN实现中的应用。
完整代码:
import torch
import matplotlib.pyplot as plt
import numpy as np
import torch.nn.functional as func
import PIL.ImageOps
from torch import nn
from torchvision import datasets,transforms
transform1=transforms.Compose([transforms.Resize((28,28)),transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))])
training_dataset=datasets.MNIST(root='./data',train=True,download=True,transform=transform1)
training_loader=torch.utils.data.DataLoader(dataset=training_dataset,batch_size=100,shuffle=True)
def im_convert(tensor):
image=tensor.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 image
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([labels[idx].item()])
class LeNet(nn.Module):
def __init__(self):
super().__init__()
self.conv1=nn.Conv2d(1,20,5,1)
self.conv2=nn.Conv2d(20,50,5,1)
self.fully1=nn.Linear(4*4*50,500)
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,4*4*50) #Reshaping the output into desired shape
x=func.relu(self.fully1(x)) #Applying relu activation function to our first fully connected layer
x=self.fully2(x) #We will not apply activation function here because we are dealing with multiclass dataset
return x
model=LeNet()