📜  卷积神经网络模型实现

📅  最后修改于: 2020-11-11 01:03:33             🧑  作者: Mango

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表示内核大小)和步幅长度(使用1表示步幅长度,因为如果选择更大的步幅长度,将导致提取效率降低)。我们将把整个命令解包为一个变量,并附加到类中的self-object上。

同样,我们将定义下一个卷积层并相应地调整其参数。

super().__init__()
self.conv1=nn.Con2d(1, 20, 5, 1)
self.conv2=nn.Con2d(20, 50, 5, 1)

第三步:

在下一步中,我们将使用带有适当参数的nn.Linear()定义两个完全连接的层。

第一个卷积将把输入图像的尺寸从28 x 28减小到24 x24。然后,数据将通过2 x 2合并层馈送,该合并层将缩小图像的大小并将其转换为12 x 12。图层将12 x 12图像的大小减小到8 x 8图像。另一个5 x 5合并层将8 x 8图像的大小切成4 x 4图像。因此,将进入第一个完全连接层的输入通道将是4×4×50和500个输出通道作为第二个参数。

同样,我们将通过相应地调整其参数来定义第二个完全连接的层。

self.fully1=nn.Linear(4*4*50,500)
self.fully2=nn.Linear(500,10)

第四步:

现在,我们将在forward函数定义池化层和每一层的激活函数,但在此之前,我们将导入torch.nn.functional包,然后使用forward()函数并将self放置为第一个参数和x作为输入,我们将尝试进行预测。

import torch.nn.functional as func
def forward(self,x):

现在,我们将定义relu函数并连接到我们的第一个卷积层,然后借助max_pool2d()和适当的参数来定义池化层。

第一个参数是前馈x值,接下来的两个参数将定义max-pooling内核的大小,并将其解包到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()