pytorch LeNet模型

网络结构图

LeNet-5模型是Yan Lecun在1998年提出的一种卷积神经网络模型,最初设计用于手写数字的识别,是早期卷积神经网络中最有代表性的实验系统之一
LeNet的网络结构如下图所示在这里插入图片描述

LeNet模型

LeNet分为卷积层块和全连接层块两个部分。

上图为LeNet-5识别手写体数字的过程,其包含输入层在内共有八层。

LeNet5由7层CNN(不包含输入层)组成,上图中输入的原始图像大小是32×32像素,卷积层用Ci表示,采样层(pooling,池化)用Si表示,全连接层用Fi表示。

输入层

数据输入层,输入图像的尺寸为32X32

1、C1层(卷积层):6@28×28

该层使用了6个卷积核,每个卷积核的大小为5×5,这样就得到了6个feature map(特征图)。

每个卷积核(5×5)与原始的输入图像(32×32)进行卷积,这样得到的feature map(特征图)大小为(32-5+1)×(32-5+1)= 28×28

2、S2层(下采样层,也称池化层):6@14×14

这一层主要是做池化或者特征映射(特征降维),池化单元为2×2,因此,6个特征图的大小经池化后即变为14×14。

3、C3层(卷积层):16@10×10

C3层有16个卷积核,卷积核大小为5×5。

4、S4(下采样层,也称池化层):16@5×5

与S2的分析类似,池化单元大小为2×2,因此,该层与C3一样共有16个特征图,每个特征图的大小为5×5。

5、C5层(卷积层):120
该层有120个卷积核,每个卷积核的大小仍为5×5,特征图大小为(5-5+1)×(5-5+1)= 1×1
6、F6层(全连接层):84
F6层有84个单元,之所以选这个数字的原因是来自于输出层的设计,对应于一个7×12的比特图,如下图所示,-1表示白色,1表示黑色,这样每个符号的比特图的黑白色就对应于一个编码
在这里插入图片描述

7、OUTPUT层(输出层):10
Output层也是全连接层,共有10个节点,分别代表数字0到9

在这里插入图片描述

代码实现

import torch
import torchvision
from torch import nn, optim

# 加载数据函数
def load_data_mnist(batch_size, resize=None, root='~/Datasets/'):
    """Download the fashion mnist dataset and then load into memory."""
    trans = []
    if resize:
        trans.append(torchvision.transforms.Resize(size=resize))
    trans.append(torchvision.transforms.ToTensor())
    
    transform = torchvision.transforms.Compose(trans)
    mnist_train = torchvision.datasets.MNIST(root=root, train=True, download=True, transform=transform)
    mnist_test = torchvision.datasets.MNIST(root=root, train=False, download=True, transform=transform)
    
    train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=0)
    test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=0)

    return train_iter, test_iter

# 定义网络
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(1, 6, 5,padding=2,padding=2), # in_channels, out_channels, kernel_size
            nn.ReLU(),
            nn.MaxPool2d(2, 2), # kernel_size, stride
            nn.Conv2d(6, 16, 5),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        self.fc = nn.Sequential(
            nn.Linear(16*5*5, 120),
            nn.ReLU(),
            nn.Linear(120, 84),
            nn.ReLU(),
            nn.Linear(84, 10)
        )

    def forward(self, img):
        feature = self.conv(img)
        output = self.fc(feature.view(img.shape[0], -1))
        return output


net = LeNet()

batch_size = 256

# 加载数据
train_iter, test_iter = load_data_mnist(batch_size=batch_size,root=root)

# 评估
def evaluate_accuracy(data_iter, net):
    acc_sum, n = 0.0, 0
    with torch.no_grad():
        for X, y in data_iter:   
            net.eval() # 评估模式, 这会关闭dropout
            acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
            net.train() # 改回训练模式
       
            n += y.shape[0]
    return acc_sum / n

# 训练
def train_ch5(net, train_iter, test_iter, batch_size, optimizer, num_epochs):
    loss = torch.nn.CrossEntropyLoss()
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n, batch_count = 0.0, 0.0, 0, 0
        for X, y in train_iter:
        
            y_hat = net(X)
            l = loss(y_hat, y)
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
            train_l_sum += l.item()
            train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()
            n += y.shape[0]
            batch_count += 1
        test_acc = evaluate_accuracy(test_iter, net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
              % (epoch + 1, train_l_sum / batch_count, train_acc_sum / n, test_acc))

lr, num_epochs = 0.001, 5
optimizer = torch.optim.Adam(net.parameters(), lr=lr)
train_ch5(net, train_iter, test_iter, batch_size, optimizer, num_epochs)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值