LeNet1、4模型

本文详细介绍LeNet系列网络的发展历程,包括LeNet-1、LeNet-4和LeNet-5的具体结构与实现,并通过修改网络结构和参数来提升模型性能。
部署运行你感兴趣的模型镜像

目录

1、LeNet网络

2、各种模型的介绍

2.1 LeNet-1

2.2.1 各层介绍

 卷积层C

 采样层S

 全连接层F

2.2.2 pytorch的代码实现

 导入需要的库和数据

 设计训练网络:

 设计LeNet1网络

2.2 LeNet-4

1、LeNet网络

LeNet是Yann LeCun在1998年发表的论文《Gradient-Based Learning Applied to Document Recognition》中提出来的一个模型,是第一个利用反向传播实现卷积的神经网络。最早应用于识别手写数字和印刷字符。由于模型比较简单,适合新手入门学习。

LeNet模型经历过3个发展阶段:

LeNet-1:5 层模型,一个简单的 CNN。

LeNet-4:6 层模型,是 LeNet-1 的改进版本。

LeNet-5:7 层模型,现在最常用的版本

其中LeNet是以LeCun的名字命名,现在最常用的是LeNet-5.

2、各种模型的介绍

2.1 LeNet-1

2.2.1 各层介绍

 卷积层C

目的:提取输入图片的不同特征。

第一层卷积层只能提取低级的特征如边缘、线条和角等,更多层能提取更复杂的特征。

 采样层S

又分为上采样下采样两种。

上采样主要目的是放大原图像,从而可以显示在更高分辨率的显示设备上;

下采样又称为池化层,主要目的:

1、使得图像符合显示区域的大小;

2、生成对应图像的缩略图。

      经过卷积后,图片大小没变,通道数变多;经过池化后,图片尺寸变小。卷积的作用是减少噪声,更好的提取图像特征;池化层的主要作用就是减少数据,降低数据纬度的同时保留最重要的信息。

 全连接层F

全连接层一般用于 CNN 的最后几层,负责提取卷积和池化之后的特征。

各个层的参数配置如下表所示。

layer_namekernal_sizekernel_numpadding

stride

C1卷积层

5401
S2平均池化层202
C3卷积层51201
S4平均池化层202
F5全连接层

输出参数的计算公式为:

 比如第1层,输入图片尺寸为32*32,也就是input_size=32,kernel_size=5,padding=0,stride=1,带入上式,计算出output_size=28,通道数为6。具体过程参考文献[2]的内容。

2.2.2 pytorch的代码实现

 导入需要的库和数据

利用手写字体识别为例。

import torch
import torchvision
import torch.nn as nn
import torchvision.transforms as transforms
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt

trans_to_tensor = transforms.Compose([
    transforms.ToTensor()
])

data_train = torchvision.datasets.MNIST(
    './data', 
    train=True, 
    transform=trans_to_tensor, 
    download=True)

data_test = torchvision.datasets.MNIST(
    './data', 
    train=False, 
    transform=trans_to_tensor, 
    download=True)

data_train, data_test

输出:'''
(Dataset MNIST
     Number of datapoints: 60000
     Root location: ./data
     Split: Train
     StandardTransform
 Transform: Compose(
                ToTensor()
            ),
 Dataset MNIST
     Number of datapoints: 10000
     Root location: ./data
     Split: Test
     StandardTransform
 Transform: Compose(
                ToTensor()
            ))
'''

代码运行完,MNIST数据集就下载到当前目录data文件夹下。

随即可视化一个数据

train_loader = torch.utils.data.DataLoader(data_train, batch_size=100, shuffle=True)

x, y = next(iter(train_loader))

plt.imshow(x[0].squeeze(0), cmap='gray'), y[0]

输出:

 设计训练网络:

def test(net):
    net.eval()
    
    test_loader = torch.utils.data.DataLoader(data_train, batch_size=10000, shuffle=False)
    test_data = next(iter(test_loader))
    
    with torch.no_grad():
        x, y = test_data[0], test_data[1]
    
        outputs = net(x)

        pred = torch.max(outputs, 1)[1]
        print(f'test acc: {sum(pred == y) / outputs.shape[0]}')
    
    net.train()
    
def fit(net, epoch=1):
    net.train()
    run_loss = 0
    
    for num_epoch in range(epoch):
        print(f'epoch {num_epoch}')
        
        for i, data in enumerate(train_loader):
            x, y = data[0], data[1]

            outputs = net(x)
            loss = criterion(outputs, y)

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            run_loss += loss.item()

            if i % 100 == 99:
                print(f'[{(i+1) * 100} / 60000] loss={run_loss / 100}')
                run_loss = 0
                
                test(net)

 设计LeNet1网络

class LeNet1(nn.Module):
    
    def __init__(self):
        super().__init__()
        
        self.conv1 = nn.Conv2d(1, 4, [5, 5])
        self.pool1 = nn.AvgPool2d([2, 2])
        self.conv2 = nn.Conv2d(4, 12, [5, 5])
        self.pool2 = nn.AvgPool2d([2, 2])
        self.fc1 = nn.Linear(12 * 4 * 4, 10)
    
    def forward(self, x):
        x = torch.tanh(self.conv1(x))
        x = self.pool1(x)
        x = torch.tanh(self.conv2(x))
        x = self.pool2(x)
        x = x.view(-1, 12 * 4 * 4)
        x = self.fc1(x)
        
        return x

 训练

net_1 = LeNet1()

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net_1.parameters())

fit(net_1, epoch=20)

训练结果

epoch 0
[10000 / 60000] loss=1.4352531778812407
test acc: 0.8274000287055969
[20000 / 60000] loss=0.5417736759781837
test acc: 0.8774999976158142
[30000 / 60000] loss=0.4155699674785137
test acc: 0.8949999809265137
[40000 / 60000] loss=0.3654126772284508
test acc: 0.9072999954223633
[50000 / 60000] loss=0.3255393598973751
test acc: 0.916100025177002
[60000 / 60000] loss=0.2761921301484108
test acc: 0.9244999885559082
...
epoch 19
[10000 / 60000] loss=0.03766480586025864
test acc: 0.9886999726295471
[20000 / 60000] loss=0.03968163290992379
test acc: 0.9879999756813049
[30000 / 60000] loss=0.04004986075684428
test acc: 0.9886999726295471
[40000 / 60000] loss=0.03971000960096717
test acc: 0.9872999787330627
[50000 / 60000] loss=0.041877440316602586
test acc: 0.9883000254631042
[60000 / 60000] loss=0.04341953368857503
test acc: 0.9886999726295471
经过20个epoch以后,测试集精度达到98.8%,loss=0.0435。

2.2 LeNet-4

LeNet-4比LeNet-1多一个全连接层。

layer_namekernal_sizekernal_numpaddingstride
C1卷积层5401
S2均值池化层202
C3卷积层51601
S4均值池化层20

2

F5全连接层120
F6全连接层10

只需要修改模型实现代码即可,其他程序不变:

class LeNet4(nn.Module):
    
    def __init__(self):
        super().__init__()
        
        self.conv1 = nn.Conv2d(1, 4, [5, 5])
        self.pool1 = nn.AvgPool2d([2, 2],stride=2)
        self.conv2 = nn.Conv2d(4, 16, [5, 5])
        self.pool2 = nn.AvgPool2d([2, 2],stride=2)
        self.fc1 = nn.Linear(16 * 4 * 4, 120)
        self.fc2 = nn.Linear(120,10)
    
    def forward(self, x):
        x = torch.tanh(self.conv1(x))
        x = self.pool1(x)
        x = torch.tanh(self.conv2(x))
        x = self.pool2(x)
        x = x.view(-1, 16 * 4 * 4)
        x = self.fc1(x)
        x = self.fc2(x)
        
        return x

net_1 = LeNet4()

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net_1.parameters())

fit(net_1, epoch=20)

训练结果:

训练结果能达到100%。

参考文献:

[3] 从0开始撸代码--手把手教你搭建LeNet-5网络模型

[4] 经典卷积神经网络 LeNet【动手学深度学习v2】

[5] LeNet5--手写数字识别(Pytorch)

[6] 采样层介绍

您可能感兴趣的与本文相关的镜像

PyTorch 2.7

PyTorch 2.7

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值