1. LeNet5网络结构
    LeNet-5共有7层,不包含输入,每层都包含可训练参数;每个层有多个Feature Map,每个FeatureMap通过一种卷积滤波器提取输入的一种特征,然后每个FeatureMap有多个神经元。
    在论文上的LeNet5的结构如下,由于论文的数据集是32x32的,mnist数据集是28x28的,所有只有INPUT变了,其余地方会严格按照LeNet5的结构编写程序:

  1. 网络模型

class LeNet(nn.Module):def __init__(self):super(LeNet, self).__init__()self.conv1 = nn.Sequential(  # input_size=(1*28*28)nn.Conv2d(1, 6, 5, 1, 2),  # padding=2保证输入输出尺寸相同nn.ReLU(),  # input_size=(6*28*28)nn.MaxPool2d(kernel_size=2, stride=2),  # output_size=(6*14*14))self.conv2 = nn.Sequential(nn.Conv2d(6, 16, 5),nn.ReLU(),  # input_size=(16*10*10)nn.MaxPool2d(2, 2)  # output_size=(16*5*5))self.fc1 = nn.Sequential(nn.Linear(16 * 5 * 5, 120),nn.ReLU())self.fc2 = nn.Sequential(nn.Linear(120, 84),nn.ReLU())self.fc3 = nn.Linear(84, 10)# 定义前向传播过程,输入为xdef forward(self, x):x = self.conv1(x)fp1 = x.detach()  # 核心代码x = self.conv2(x)# nn.Linear()的输入输出都是维度为一的值,所以要把多维度的tensor展平成一维x = x.view(x.size()[0], -1)x = self.fc1(x)x = self.fc2(x)x = self.fc3(x)return x  # F.softmax(x, dim=1)
  1. 训练代码
def train(epoch):  # 定义每个epoch的训练细节model.train()  # 设置为trainning模式for batch_idx, (data, target) in enumerate(train_loader):data = data.to(device)target = target.to(device)data, target = Variable(data), Variable(target)  # 把数据转换成Variableoptimizer.zero_grad()  # 优化器梯度初始化为零output = model(data)  # 把数据输入网络并得到输出,即进行前向传播loss = F.cross_entropy(output, target)  # 交叉熵损失函数loss.backward()  # 反向传播梯度optimizer.step()  # 结束一次前传+反传之后,更新参数if batch_idx % log_interval == 0:  # 准备打印相关信息print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))
  1. 测试代码
def test():model.eval()  # 设置为test模式test_loss = 0  # 初始化测试损失值为0correct = 0  # 初始化预测正确的数据个数为0for data, target in test_loader:data = data.to(device)target = target.to(device)data, target = Variable(data), Variable(target)  # 计算前要把变量变成Variable形式,因为这样子才有梯度output = model(data)test_loss += F.cross_entropy(output, target, size_average=False).item()  # sum up batch loss 把所有loss值进行累加pred = output.data.max(1, keepdim=True)[1]  # get the index of the max log-probabilitycorrect += pred.eq(target.data.view_as(pred)).cpu().sum()  # 对预测正确的数据个数进行累加test_loss /= len(test_loader.dataset)  # 因为把所有loss值进行过累加,所以最后要除以总得数据长度才得平均lossprint('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset),100. * correct / len(test_loader.dataset)))
  1. LeNet.py完整代码
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.autograd import Variablelr = 0.01  # 学习率
momentum = 0.5
log_interval = 10  # 跑多少次batch进行一次日志记录
epochs = 10
batch_size = 64
test_batch_size = 1000class LeNet(nn.Module):def __init__(self):super(LeNet, self).__init__()self.conv1 = nn.Sequential(  # input_size=(1*28*28)nn.Conv2d(1, 6, 5, 1, 2),  # padding=2保证输入输出尺寸相同nn.ReLU(),  # input_size=(6*28*28)nn.MaxPool2d(kernel_size=2, stride=2),  # output_size=(6*14*14))self.conv2 = nn.Sequential(nn.Conv2d(6, 16, 5),nn.ReLU(),  # input_size=(16*10*10)nn.MaxPool2d(2, 2)  # output_size=(16*5*5))self.fc1 = nn.Sequential(nn.Linear(16 * 5 * 5, 120),nn.ReLU())self.fc2 = nn.Sequential(nn.Linear(120, 84),nn.ReLU())self.fc3 = nn.Linear(84, 10)# 定义前向传播过程,输入为xdef forward(self, x):x = self.conv1(x)fp1 = x.detach()  # 核心代码x = self.conv2(x)# nn.Linear()的输入输出都是维度为一的值,所以要把多维度的tensor展平成一维x = x.view(x.size()[0], -1)x = self.fc1(x)x = self.fc2(x)x = self.fc3(x)return x  # F.softmax(x, dim=1)def train(epoch):  # 定义每个epoch的训练细节model.train()  # 设置为trainning模式for batch_idx, (data, target) in enumerate(train_loader):data = data.to(device)target = target.to(device)data, target = Variable(data), Variable(target)  # 把数据转换成Variableoptimizer.zero_grad()  # 优化器梯度初始化为零output = model(data)  # 把数据输入网络并得到输出,即进行前向传播loss = F.cross_entropy(output, target)  # 交叉熵损失函数loss.backward()  # 反向传播梯度optimizer.step()  # 结束一次前传+反传之后,更新参数if batch_idx % log_interval == 0:  # 准备打印相关信息print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))def test():model.eval()  # 设置为test模式test_loss = 0  # 初始化测试损失值为0correct = 0  # 初始化预测正确的数据个数为0for data, target in test_loader:data = data.to(device)target = target.to(device)data, target = Variable(data), Variable(target)  # 计算前要把变量变成Variable形式,因为这样子才有梯度output = model(data)test_loss += F.cross_entropy(output, target, size_average=False).item()  # sum up batch loss 把所有loss值进行累加pred = output.data.max(1, keepdim=True)[1]  # get the index of the max log-probabilitycorrect += pred.eq(target.data.view_as(pred)).cpu().sum()  # 对预测正确的数据个数进行累加test_loss /= len(test_loader.dataset)  # 因为把所有loss值进行过累加,所以最后要除以总得数据长度才得平均lossprint('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset),100. * correct / len(test_loader.dataset)))if __name__ == '__main__':device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')  # 启用GPUtrain_loader = torch.utils.data.DataLoader(  # 加载训练数据datasets.MNIST('../data', train=True, download=True,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))  # 数据集给出的均值和标准差系数,每个数据集都不同的,都数据集提供方给出的])),batch_size=batch_size, shuffle=True)test_loader = torch.utils.data.DataLoader(  # 加载训练数据,详细用法参考我的Pytorch打怪路(一)系列-(1)datasets.MNIST('../data', train=False, transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))  # 数据集给出的均值和标准差系数,每个数据集都不同的,都数据集提供方给出的])),batch_size=test_batch_size, shuffle=True)model = LeNet()  # 实例化一个网络对象model = model.to(device)optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)  # 初始化优化器for epoch in range(1, epochs + 1):  # 以epoch为单位进行循环train(epoch)test()torch.save(model, 'model.pth')  # 保存模型
  1. 中间层特征提取代码
class FeatureExtractor(nn.Module):def __init__(self, submodule, extracted_layers):super(FeatureExtractor, self).__init__()self.submodule = submoduleself.extracted_layers = extracted_layersdef forward(self, x):outputs = []print(self.submodule._modules.items())for name, module in self.submodule._modules.items():if "fc" in name:print(name)x = x.view(x.size(0), -1)print(module)x = module(x)print(name)if name in self.extracted_layers:outputs.append(x)return outputs
  1. LeNet5Pre.py完整代码
import torch
import torch.nn as nn
import cv2
import torch.nn.functional as F
from LeNet5 import LeNet  # 重要,虽然显示灰色(即在次代码中没用到),但若没有引入这个模型代码,加载模型时会找不到模型
from torch.autograd import Variable
from torchvision import datasets, transforms
import numpy as np
import matplotlib.pyplot as plt# 中间特征提取
class FeatureExtractor(nn.Module):def __init__(self, submodule, extracted_layers):super(FeatureExtractor, self).__init__()self.submodule = submoduleself.extracted_layers = extracted_layersdef forward(self, x):outputs = []print(self.submodule._modules.items())for name, module in self.submodule._modules.items():if "fc" in name:print(name)x = x.view(x.size(0), -1)print(module)x = module(x)print(name)if name in self.extracted_layers:outputs.append(x)return outputsif __name__ == '__main__':device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')model = torch.load('model.pth')  # 加载模型model = model.to(device)model.eval()  # 把模型转为test模式img = cv2.imread("8.jpg")  # 读取要预测的图片trans = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 图片转为灰度图,因为mnist数据集都是灰度图img = trans(img)img = img.to(device)img = img.unsqueeze(0)  # 图片扩展多一维,因为输入到保存的模型中是4维的[batch_size,通道,长,宽],而普通图片只有三维,[通道,长,宽]# 扩展后,为[1,1,28,28]output = model(img)prob = F.softmax(output, dim=1)prob = Variable(prob)prob = prob.cpu().numpy()  # 用GPU的数据训练的模型保存的参数都是gpu形式的,要显示则先要转回cpu,再转回numpy模式print(prob)  # prob是10个分类的概率pred = np.argmax(prob)  # 选出概率最大的一个print(pred.item())# 特征输出net = LeNet().to(device)exact_list = ["conv1", "conv2"]myexactor = FeatureExtractor(net, exact_list)x = myexactor(img)# 特征输出可视化for i in range(6):ax = plt.subplot(1, 6, i + 1)ax.set_title('Feature {}'.format(i))ax.axis('off')plt.imshow(x[0].data.cpu()[0, i, :, :], cmap='jet')plt.show()
  1. LeNet5Pre.py输入图像
    输入图像为28*28像素的黑底白字手写数字图像。

  2. 运行结果



  3. 参考文献:
    pytorch用LeNet5识别Mnist手写体数据集(训练+预测单张输入图片代码)
    基于Pytorch的特征图提取

pytorch实现LeNet5手写数字识别+各层特征图可视化相关推荐

  1. Pytorch实现mnist手写数字识别

    2020/6/29 Hey,突然想起来之前做的一个入门实验,用pytorch实现mnist手写数字识别.可以在这个基础上增加网络层数,或是尝试用不同的数据集,去实现不一样的功能. Mnist数据集如图 ...

  2. 卷积神经网络案例:LeNet-5手写数字识别

    一.LeNet-5网络结构 1.1 LeNet-5介绍: 由Yann LeCun(杨立昆)于1998年提出的一种经典的卷积网络结构. 第一个成功应用于数字识别问题的卷积神经网络. 1.2 LeNet- ...

  3. 用PyTorch实现MNIST手写数字识别(非常详细)

    ​​​​​Keras版本: Keras入门级MNIST手写数字识别超级详细教程 2022/4/17 更新修复下代码.完善优化下文章结构,文末提供一个完整版代码. 可以在这里下载源码文件(免积分): 用 ...

  4. 深度学习练手项目(一)-----利用PyTorch实现MNIST手写数字识别

    一.前言 MNIST手写数字识别程序就不过多赘述了,这个程序在深度学习中的地位跟C语言中的Hello World地位并驾齐驱,虽然很基础,但很重要,是深度学习入门必备的程序之一. 二.MNIST数据集 ...

  5. 深度学习入门项目:PyTorch实现MINST手写数字识别

    完整代码下载[github地址]:https://github.com/lmn-ning/MNIST_PyTorch.git 目录 一.MNIST数据集介绍及下载地址 二.代码结构 三.代码 data ...

  6. Pytorch入门——MNIST手写数字识别代码

    MNIST手写数字识别教程 本文仅仅放出该教程的代码 具体教程请看 Pytorch入门--手把手教你MNIST手写数字识别 import torch import torchvision from t ...

  7. 基于Pytorch的MNIST手写数字识别实现(含代码+讲解)

    说明:本人也是一个萌新,也在学习中,有代码里也有不完善的地方.如果有错误/讲解不清的地方请多多指出 本文代码链接: GitHub - Michael-OvO/mnist: mnist_trained_ ...

  8. (一)Lenet5 手写数字识别原理及代码解析

    模型简单,本地可跑 论文参考:Gradient-based learning applied to document recognition MNIST手写数据集 50000个训练数据 10000个测 ...

  9. Pytorch+CNN+MNIST手写数字识别实战

    文章目录 1.MNIST 2.数据预处理 2.1相关包 2.2数据载入和预处理 3.网络结构 4.优化器.损失函数.网络训练以及可视化分析 4.1定义优化器 4.2网络训练 4.3可视化分析 5.测试 ...

  10. lenet5手写数字识别 matlab,LeNet5实现手写体数字识别(基于PyTorch实现)

    import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from  ...

最新文章

  1. jax-ws服务使用
  2. MySql分区表性能测试及切换案例
  3. Java处理文件BOM头的方式推荐
  4. android tcp ip modem ppp gprs,为什么GPRS调制解调器提供嵌入式TCP/IP协议栈
  5. 菜鸟python 正则表达式_python基础知识(进阶篇--正则表达式)
  6. word页面顺序倒过来_Word里的表格,行之间的顺序如何颠倒过来?
  7. Q96:PT(3.3):大理石纹理(Marble Texture)
  8. 盘点Mac最受欢迎的优化清理软件2020|最新|集合|排行榜
  9. 【专栏必读】数据库系统概论第五版(王珊)专栏学习笔记目录导航及课后习题答案详解
  10. ado控件连接mysql_VB利用ADO控件连接access数据库
  11. win10卸载程序灾难性故障_win10新建文件夹出现0X8000FFFF:灾难性故障的错误提示解决方法...
  12. 团队博客-应用功能说明书
  13. 埃默里大学计算机值得读吗,埃默里大学计算机科学-计算科学硕士研究生Offer及录取要求...
  14. 推荐一款HTML在线编辑器
  15. 原来《羊了个羊》也求助了云,拦截bot自动化攻击达5000万次 | CCF C³
  16. 京东/淘宝的手机销售榜(前4名 -- 手机品牌 --手机型号*3 --手机分辨率 -- 手机操作系统 --安卓版本号)...
  17. 复杂网络分析总结[Network Analysis]
  18. 什么才是真正的云主机?辨别真假云主机
  19. Buxwiz注册详解
  20. 云计算行业发展呈上升趋势,技术成为重要驱动因素

热门文章

  1. Power BI分解销售目标
  2. halcon修改图像的灰度值02
  3. MFS分布式文件系统
  4. 用python画钢铁侠图片_Photoshop快速把钢铁侠图片转为素描水墨风格教程
  5. 运行海康威视sdk实现拍照遇到的问题与解决
  6. 百度大脑人脸识别助力企业实现无感考勤
  7. 全国各省手机号测试用例
  8. 大小写字母ASCII码对照表
  9. 苹果手机还原后无法激活
  10. 无显示器主机配置服务器