Pytorch搭建LeNet5网络

本讲目标:
介绍Pytorch搭建LeNet5网络的流程。

Pytorch八股法搭建LeNet5网络

1.LeNet5网络介绍

借鉴点:共享卷积核,减少网络参数(通过共享卷积参数,避免了像全连接层那样存在大量参数)。

LeNet由Yann LeCun于1998年提出,是卷积网络的开篇之作。LeNet-5提出以后,卷积神经网络成功的被商用,广泛的应用在邮政编码、支票号码识别等相关任务中。本节用LeNet网络实现Cifar10数据集的识别任务。

在统计卷积神经网络的层数时,一般只统计卷积计算层和全连接层,其余操作可以认为是卷积层的附属。
LeNet共5层网络(如下图),两层卷积层(C1、C2,前面两个卷积层,我们定义卷积层为包含了 convbatch normalizationactivationpooldropout等层的单元,这五部分不一定全部具备)和三层全连接层(D1、D2、D3,最后三个Dense层)。

Pytorch搭建LeNet5网络

卷积就是特征提取器:CBAPB

Conv2D、 BatchNormalization、 Activation、 Pooling、 Dropout

特征提取器(卷积层):
C1:
C(核k:6x5x5,步长s:1,填充p:valid)
B(None)
A(sigmoid)
P(max,核k:2×2,步长s:2,填充p:valid)
D(None)
C2:
C(核k:16x5x5,步长s:1,填充k:valid)
B(None)
A(sigmoid)
P(max,核k:2×2,步长s:2,填充p:valid)
D(None)
分类器(全连接层):
D1:
Dense(神经元:120,激活:sigmoid)
D2:
Dense(神经元: 84,激活:sigmoid)
D3:
Dense(神经元: 10,激活:softmax)

; 2.Pytorch搭建LeNet5网络

2.1搭建LeNet网络

搭建网络在 model.py文件中。

import torch
import torch.nn as nn
import torch.nn.functional as F

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet,self).__init__()

        self.conv1=nn.Conv2d(in_channels=3,out_channels=16,kernel_size=5)
        self.pool1=nn.MaxPool2d(2,2)
        self.conv2=nn.Conv2d(16,32,5)
        self.pool2=nn.MaxPool2d(2,2)
        self.fc1=nn.Linear(32*5*5,120)
        self.fc2=nn.Linear(120,84)
        self.fc3=nn.Linear(84,10)

    def forward(self,x):
        x=F.relu(self.conv1(x))
        x=self.pool1(x)
        x=F.relu(self.conv2(x))
        x=self.pool2(x)
        x=x.view(-1,32*5*5)
        x=F.relu((self.fc1(x)))
        x=F.relu((self.fc2(x)))
        x=self.fc3(x)
        return x

2.2测试LeNet网络输出

我们输入的数据是一个32×32大小的3通道图像(3,32,32):input(3,32,32)->C1(16,28,28)->P1(16,14,14)->C2(32,10,10)->P2(32,5,5)->reshape(1,32 _5_5)->fc1(120)->fc2(80)->fc3(10)->output
测试网络如下:生成一个[1,3,32,32]大小的张量,其中1为batch_size,3为通道数,32为图像尺寸。观察输出是否为[1,10]。

input=torch.rand([1,3,32,32])
model=LeNet()
output=model(input)
print(model)
print(output.shape)

输出结果如下:

LeNet(
  (conv1): Conv2d(3, 16, kernel_size=(5, 5), stride=(1, 1))
  (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (conv2): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1))
  (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (fc1): Linear(in_features=800, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)
torch.Size([1, 10])

2.3下载数据集

下载数据集在 train.py文件中。

import torch.optim as optim
import torch.utils.data
import torchvision.datasets
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
import  torch.nn as nn

from model import  LeNet

transform=transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5,0.5,0.5,),(0.5,0.5,0.5))
    ]
)

trainset=torchvision.datasets.CIFAR10(
    root='./data',
    train=True,
    download=True,
    transform=transform
    )

trainloader=torch.utils.data.DataLoader(
    trainset,
    batch_size=36,
    shuffle=True,
    num_workers=0
    )

testset=torchvision.datasets.CIFAR10(
    root='./data',
    train=False,
    download=True,
    transform=transform
    )

testloader=torch.utils.data.DataLoader(
    testset,
    batch_size=10000,
    shuffle=False,
    num_workers=0
    )
test_data_iter=iter(testloader)
test_image,test_label=test_data_iter.next()

2.4加载并配置网络

仍然在 train.py文件中。

net=LeNet()
loss_function=nn.CrossEntropyLoss()
optimizer=optim.Adam(net.parameters(),lr=0.001)

2.5训练并保存网络

仍然在 train.py文件中。
总共训练5个epoch,之前将batch_size设置为32,训练过程中,每100次batch_size,就打印以此在testloader上的损失。最后保存训练好的模型。

for epoch in range(5):
    running_loss=0.0
    for step,data in enumerate(trainloader,start=0):
        inputs,labels=data
        optimizer.zero_grad()
        outputs=net(inputs)
        loss=loss_function(outputs,labels)
        loss.backward()
        optimizer.step()

        running_loss+=loss.item()
        if step % 100==99:
            with torch.no_grad():
                outputs=net(test_image)
                predict_y=torch.max(outputs,dim=1)[1]
                accuracy=torch.eq(predict_y,test_label).sum().item()/test_label.size(0)

                print('[%d,%5d train_loss:%.3f test_accuracy:%.3f'%
                      (epoch+1,step+1,running_loss/500,accuracy))
                running_loss=0.0
print('Finish Training')

save_path= 'LeNet.pth'
torch.save(net.state_dict(),save_path)

最后一次epoch的打印信息如下,可以观察到识别精度已经达到了65.8%,对于一个古老的网络,这个精度已经是非常高了。

[5,  100 train_loss:0.163 test_accuracy:0.649
[5,  200 train_loss:0.171 test_accuracy:0.658
[5,  300 train_loss:0.172 test_accuracy:0.658
[5,  400 train_loss:0.173 test_accuracy:0.654
[5,  500 train_loss:0.170 test_accuracy:0.647
[5,  600 train_loss:0.175 test_accuracy:0.655
[5,  700 train_loss:0.176 test_accuracy:0.668
[5,  800 train_loss:0.172 test_accuracy:0.658
[5,  900 train_loss:0.168 test_accuracy:0.640
[5, 1000 train_loss:0.173 test_accuracy:0.658
[5, 1100 train_loss:0.173 test_accuracy:0.643
[5, 1200 train_loss:0.169 test_accuracy:0.661
[5, 1300 train_loss:0.167 test_accuracy:0.658
Finish Training

2.6测试图片

测试图片程序在 predict.py文件中。

Pytorch搭建LeNet5网络
import torch
import torchvision.transforms as transforms
from PIL import  Image
from  model import  LeNet

transform=transforms.Compose(
    [transforms.Resize((32,32)),
     transforms.ToTensor(),
     transforms.Normalize((0.5,0.5,0.5,),(0.5,0.5,0.5))
    ]
)

classes=('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')

net = LeNet()
net.load_state_dict(torch.load('LeNet.pth'))
im=Image.open('1.jpg')
im=transform(im)
im=torch.unsqueeze(im,dim=0)
with torch.no_grad():
    outputs=net(im)
    predict=torch.softmax(outputs,dim=1)
    predict_class=torch.max(outputs,dim=1)[1].numpy()

print(classes[predict_class[0]],predict[0][predict_class[0]].numpy())

输出结果:

plane 0.8187075

Original: https://blog.csdn.net/qq_39400324/article/details/124383550
Author: AI Chen
Title: Pytorch搭建LeNet5网络

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/709218/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球