LeNet识别MNIST数据集

1.什么是LeNet模型

在这里插入图片描述
LeNet分为卷积层块和全连接层块两个部分。下面我们分别介绍这两个模块。

卷积层块里的基本单位是卷积层后接最大池化层:卷积层用来识别图像里的空间模式,如线条和物体局部,之后的最大池化层则用来降低卷积层对位置的敏感性。卷积层块由两个这样的基本单位重复堆叠构成。在卷积层块中,每个卷积层都使用5×55×5的窗口,并在输出上使用sigmoid激活函数。第一个卷积层输出通道数为6,第二个卷积层输出通道数则增加到16。这是因为第二个卷积层比第一个卷积层的输入的高和宽要小,所以增加输出通道使两个卷积层的参数尺寸类似。卷积层块的两个最大池化层的窗口形状均为2×22×2,且步幅为2。由于池化窗口与步幅形状相同,池化窗口在输入上每次滑动所覆盖的区域互不重叠。

卷积层块的输出形状为(批量大小, 通道, 高, 宽)。当卷积层块的输出传入全连接层块时,全连接层块会将小批量中每个样本变平(flatten)。也就是说,全连接层的输入形状将变成二维,其中第一维是小批量中的样本,第二维是每个样本变平后的向量表示,且向量长度为通道、高和宽的乘积。全连接层块含3个全连接层。它们的输出个数分别是120、84和10,其中10为输出的类别个数。

2.导入数据包

import torch 
import torchvision
import torchvision.transforms as transforms
import torch.nn as nn
import matplotlib.pyplot as plt

3.加载图片,并显示第一张图片的尺寸

train_data = torchvision.datasets.MNIST(root='E:\PycharmProjects\data',train=True, download=True, transform=transforms.ToTensor())
test_data = torchvision.datasets.MNIST(root='E:\PycharmProjects\data',train=False, download=True, transform=transforms.ToTensor())
train_data[0][0].shape

在这里插入图片描述
train_data分为2个部分,train_data[0][0]是第一张图像,train_data[0][1]是第一张图像的正确类别

4.显示前十张数字

def show_image(images):
    _,figs = plt.subplots(1,10,figsize=(12,12))
    for fig,img in zip(figs,images):
        fig.imshow(img.view(28,28))
        fig.axes.get_xaxis().set_visible(False)
        fig.axes.get_yaxis().set_visible(False)
    plt.show()

x=[]
for i in range(10):
    x.append(train_data[i][0])
show_image(x)

在这里插入图片描述

5.构造LeNet网络

net = nn.Sequential(
    nn.Conv2d(1,6,kernel_size=5,padding=2),
    #因为传入的x.shape=256*28*28,所以在原来模型基础上,增加padding,使与后面LeNet网络对应
    nn.Sigmoid(),#每个卷积层之后需要接一个激活函数
    nn.MaxPool2d(kernel_size=2,stride=2),#最大池化,减少参数量
    nn.Conv2d(6,16,kernel_size=5),
    nn.Sigmoid(),
    nn.MaxPool2d(kernel_size=2,stride=2),
    nn.Flatten(),#将图片拉直为一维向量
    nn.Linear(16*5*5,120),
    nn.Sigmoid(),
    nn.Linear(120,84),
    nn.Sigmoid(),
    nn.Linear(84,10),
)
net

在这里插入图片描述

6.精确函数

def evaluate_accuracy(data_iter,net):
    acc_sum, n = 0.0, 0
    for x,y in data_iter:
        acc_sum += (net(x).argmax(dim=1)==y).float().sum().item()
        n += len(y)
    return acc_sum / n

7.训练数据

import torch.optim as optim
import time
batch_size= 256
train_iter = torch.utils.data.DataLoader(train_data,batch_size)
test_iter = torch.utils.data.DataLoader(test_data,batch_size)
lr=0.01
optimizer=optim.Adam(net.parameters(),lr)
loss=nn.CrossEntropyLoss() 
for epoch in range(4):
    train_l,test_l,start=0.0,0.0,time.time()
    for x,y in train_iter:
        y_hat=net(x)
        l=loss(y_hat,y).sum()/len(y)
        optimizer.zero_grad()
        l.backward()
        optimizer.step()
    train_l = evaluate_accuracy(train_iter,net)
    test_l = evaluate_accuracy(test_iter,net)
    print('loss= %.4f, train_l= %.4f, test_l= %.4f, time= %.2f' % (l,train_l,test_l,time.time()-start))

在这里插入图片描述

总结 以上训练结果,可以先用一个批量测试一下

for x,y in train_iter:
    print(net(x).argmax(dim=1)-y)
    break

#不等于0 表示分类错误
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lins H

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值