搭建不同网络训练MNIST

Posted 算法与编程之美

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搭建不同网络训练MNIST相关的知识,希望对你有一定的参考价值。

问题
在之前的学习过程中,我们学习了如何搭建全连接神经网络训练Mnist数据集。初始时,全连接神经网络训练结果验证集和训练集的精确度不高,在对数据进行归一化,调参等操作提高了精确度。我们这次使用Le-Net5和VGG对MNIST进行训练,VGG采样层太多,计算量庞大,我们只进行搭建,也可以采用Google Colab进行训练。比较全连接和卷积神经网络异同。
Le-net5网络如下。

方法
搭建le-net5神经网络,定义了两层卷积层、两个均值池化以及三层全连接网络。使用summary可查看得到每层网络的输入和输出。

import torch
from torch import nn
from torchinfo import summary
import torch.nn.functional as F
import torchvision
from torchvision import datasets,transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
from torchvision.transforms import ToTensor
from torchvision.transforms import Normalize
import time
start=time.time()
class MyNet(nn.Module):
   # x=1*28*28 c*h*w c表示通道数,h表示图像高度,w表示图像宽度
   #定义网络有哪些层,层作为成员变量
   def __init__(self) -> None:
       super().__init__()
       self.conv1=nn.Conv2d(in_channels=1,
                  out_channels=6,
                  kernel_size=5,
                  stride=1,
                  padding=0)#[28]
       self.avg_pool1 = nn.AvgPool2d(
           2,
           stride=2,
       )
       self.conv2=nn.Conv2d(in_channels=6,
                  out_channels=16,
                  kernel_size=5,
                  stride=1,
                 )
       self.avg_pool2 = nn.AvgPool2d(
           2,
           stride=2,
       )
       self.fc1=nn.Linear(in_features=4 * 4 * 16,
                       out_features=120,
                                   )
       self.fc2=nn.Linear(in_features=120,
                       out_features=84,
                                   )
       self.fc3 = nn.Linear(in_features=84,
                            out_features=10,
                            )
   def forward(self,x):
       x=torch.relu(self.conv1(x))
       x=torch.relu(self.avg_pool1(x))
       x=torch.relu(self.conv2(x))
       x=torch.relu(self.avg_pool2(x))
       x=torch.flatten(x,1)# nn.Flatten()默认从dim=1开始 torch.flatten()默认从dim=0开始
       x=torch.relu(self.fc1(x))
       x=torch.relu(self.fc2(x))
       out=torch.relu(self.fc3(x))
       return out

搭建VGG11,定义了八个卷积层,五个最大池化层和三层全连接层。由于网络搭建复杂,计算量过大,运行很慢。VGG模型框架如下。

class MyNet(nn.Module):
   # x=1*28*28 c*h*w c表示通道数,h表示图像高度,w表示图像宽度
   #定义网络有哪些层,层作为成员变量
   def __init__(self) -> None:
       super().__init__()
       self.conv1=nn.Conv2d(in_channels=1,
                  out_channels=64,
                  kernel_size=3,
                  stride=1,
                  padding=1)#[B,64,224,224]
  self.MaxPool_1=nn.MaxPool2d(kernel_size=2,
                                 stride=2)#[64,112,112]
       self.conv2=nn.Conv2d(in_channels=64,
                            out_channels=128,  # [B,128,112,112]
                           kernel_size=3,
                            stride=1,
                            padding=1)
       self.MaxPool_2= nn.MaxPool2d(kernel_size=2,
                                 stride=2)#[128,56,56]
       self.conv3=nn.Conv2d(in_channels=128,
                            out_channels=256,  # [B,256,56,56]
                           kernel_size=3,
                            stride=1,
                            padding=1)
       self.conv4 = nn.Conv2d(
           in_channels=256,
           out_channels=256,
           kernel_size=3,
           stride=1,
           padding=1#[256,56,56]
       )
       self.MaxPool_3 = nn.MaxPool2d(
           kernel_size=2,
           stride=2)#[256,28,28]
       self.conv5 = nn.Conv2d(
           in_channels=256,
           out_channels=512,
           kernel_size=3,
           stride=1,
           padding=1#[512,56,56]
       )
       self.conv6 = nn.Conv2d(
           in_channels=512,
           out_channels=512,
           kernel_size=3,
           stride=1,
           padding=1#[512,56,56]
       )
       self.MaxPool_4 = nn.MaxPool2d(
           kernel_size=2,
           stride=2)#[512,14,14]
       self.conv7 = nn.Conv2d(
           in_channels=512,
           out_channels=512,
           kernel_size=3,
           stride=1,#[512,28,28]
           padding=1
       )
       self.conv8 = nn.Conv2d(
           in_channels=512,
           out_channels=512,
           kernel_size=3,
           stride=1,#[512,56,56]
           padding=1
       )
       self.MaxPool_5=nn.MaxPool2d(
           kernel_size=2,
           stride=2)#[512,7,7]
       self.fc1 = nn.Linear(
           in_features=512 * 7 * 7,
           out_features=4096
       )
       self.fc2 = nn.Linear(
           in_features=4096,
           out_features=4096
       )
       self.fc3 = nn.Linear(
           in_features=4096,
           out_features=10
       )
   def forward(self,x):
       x=torch.relu(self.conv1(x))
       x=torch.relu(self.MaxPool_1(x))
       x=torch.relu(self.conv2(x))
       x=torch.relu(self.MaxPool_2(x))
       x = torch.relu(self.conv3(x))
       x = torch.relu(self.conv4(x))
       x = torch.relu(self.MaxPool_3(x))
       x = torch.relu(self.conv5(x))
       x = torch.relu(self.conv6(x))
       x = torch.relu(self.MaxPool_4(x))
       x = torch.relu(self.conv7(x))
       x = torch.relu(self.conv8(x))
       x = torch.relu(self.MaxPool_5(x))
       x=torch.flatten(x,1)# nn.Flatten()默认从dim=1开始 torch.flatten()默认从dim=0开始
       x=torch.relu(self.fc1(x))
       x=torch.relu(self.fc2(x))
       out=torch.relu(self.fc3(x))
       return out

对比batch_size=64的全连接网络和le-net5卷积神经网络对MNIST数据集的效果。对数据结果进行数据可视化。

结语

图像的数据是一个矩阵,也就是一个像素点的和它所在位置的上下左右像素点有很大的相关性,将像素矩阵flatten后,左右的位置关系保留了,但是上下的位置关系却被破坏了。

卷积神经网络和全连接神经网络的不同之处在于,卷积神经网络的输入是图像的原始矩阵,这样保留了图像的上下左右位置关系。

数据可视化的结果显示,fcn和Le-net5的精确度达到最好的效果,验证集和训练集的精确度高达99%,FCN这组数据有些过拟合,FCN存在参数过多,而使用CNN可以减少参数,降低过拟合,在 Le-net5模型搭建为了降低过拟合,使用了Dropout方法。在训练VGG过程中可以降低batch_size,也可通过Google Colab进行训练。

以上是关于搭建不同网络训练MNIST的主要内容,如果未能解决你的问题,请参考以下文章

基于PaddlePaddle的LeNet神经网络MNIST数据集分类

Keras训练神经网络DEMO——全连接神经网络训练MNIST

Keras训练神经网络DEMO——全连接神经网络训练MNIST

用tensorflow搭建简单神经网络测试iris 数据集和MNIST 数据集

PyTorch搭建全连接网络训练MNIST数据集分类任务和气温预测回归任务及全连接网络过拟合和欠拟合的调参方式

2.搭建一个神经网络模型训练MNIST手写体数字数据集中遇到的问题及解决方法