目录

一、LeNet

二、LeNet实现CIFAR10图像分类

1、CIFAR10

2、model部分代码

3、train部分代码

3.1导入库

3.2是否可以使用GPU

3.3预处理并加载CIFAR10

3.4显示图片

3.5建立模型

3.6训练模型

3.7保存模型

4、predict部分代码

4.1导入库

4.2预处理

4.3读取模型并预测新图片


一、LeNet

LeNet诞生于1994年,作为最早的深度学习模型之一,被用于训练手写体识别。

LeNet模型构造如下图:

下面对上图中矩阵尺寸如何计算进行解释:

矩阵尺寸计算公式:N=(W-F+2P)/S+1

W 输入图片尺寸W*W
F Filter大小F*F,卷积核大小
P Padding,填充在上下左右的行数,一般对称填充所以乘以2
S Stride,步长

例如:C1(第一个卷积层):

输入:32*32 ---W*W

卷积核大小:5*5 ---F*F

填充区域:默认为0

步长:默认为1

输出:28*28        (32-5+0)/1+1=28

P1(第一个池化层):

输入:28*28 ---W*W

采样区域:2*2     默认采样区域等于步长,步长为2

输出:14*14       28/2=14

LeNet详解参见:LeNet详解_CharlesOAO的博客-CSDN博客_lenet

二、LeNet实现CIFAR10图像分类

1、CIFAR10

CIFAR-10 是由 Hinton 的学生整理的一个用于识别物体的小型数据集。一共包含 10 个类别的 RGB 彩色图片,图片尺寸为32*32,共500张训练图片,和10000张测试图片。数据集类别为'plane','car','bird','cat','deer','dog','frog','horse','ship','truck'。

2、model部分代码

import torch.nn as nn
import torch.nn.functional as Fclass LeNet(nn.Module):def __init__(self):                     #矩阵尺寸计算大小:N=(W-F+2P)/S+1super(LeNet,self).__init__()self.conv1=nn.Conv2d(3,16,5)        #(self,in_channels,out_channels,kernel_size,stride=1,#padding=0,dilation=1,groups=1,bias=True,padding_mode='zeros')self.pool1=nn.MaxPool2d(2,2)        #(self,kernal_size,stride=None,padding=0,dilation=1,#return_indices=False,ceil_mode=False)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)                #全连接之前进行reshape,行数基于张量长度除以列数决定x=F.relu(self.fc1(x))x=F.relu(self.fc2(x))x=self.fc3(x)                      return xif __name__=="__main__":import torchmodel=LeNet()print(model)                            #输出模型

初始化部分,后面的注释为该函数的参数顺序。

前向传播forward部分,每次卷积和全连接都加入激活函数。最后一次全连接不添加softmax层是由于train.py中使用了cross_entropy_loss(损失交叉熵)函数,其中添加了softmax的部分,而前向传播再次加入softmax会导致二次权值差异压缩,模型会向错误的方向更新。

3、train部分代码

3.1导入库

import torch
import torchvision
import torch.nn as nn
from model import LeNet
import torch.optim as optim
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np

3.2是否可以使用GPU

device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")    #device设为有gpu使用gpu
print(device)

输出cuda:0则可用GPU运行,输出CPU则使用CPU运行。

在使用GPU和使用CPU替换时,需要在后文修改五处位置,分别在建立模型,正向传播和计算损失交叉熵,准确率计算中添加.to(device)

如遇到警告,请检查python版本和cuda版本之间关系,cuda版本与电脑显存cuda之间关系,python虚拟环境中若干库与当前pytorch兼容关系,当前pytorch是否为GPU版本(cuda版本)等若干问题。

3.3预处理并加载CIFAR10

transform=transforms.Compose(                              #数据预处理[transforms.ToTensor(),                                #将数据转换为tensor结构,原数据PIL Image或numpy结构为[H,W,C],范围为(0,255)#转换为[C,H,W],范围为[0,1]transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))]    #transforms.Normalize(std=(0.5,0.5,0.5),mean=(0.5,0.5,0.5)),则其作用就是先将输入归一化到(0,1),再使用公式"(x-mean)/std",将每个元素分布到(-1,1)
)
trainset=torchvision.datasets.CIFAR10(root='./data',train=True,            #下载路径为当前文件夹下data文件夹,用作traindownload=True,transform=transform)   #download为True代表进行下载,下完即可用False,transform使用上面的归一化操作,进行数据预处理
trainloader=torch.utils.data.DataLoader(trainset,batch_size=36,            #训练使用trainset训练集,每批次使用36张,shuffle=True为随机打乱shuffle=True,num_workers=0)        #num_workers为0默认值,值为8,4,2代表的是CPU的进程数,而不是GPU
testset=torchvision.datasets.CIFAR10(root='./data',train=False,download=True,transform=transform)
testloader=torch.utils.data.DataLoader(testset,batch_size=10000,shuffle=True,num_workers=0)

testloader中batch_size=10000一批次同时加载10000张图片,在显示图片时记得调整参数

3.4显示图片

test_image,test_label=next(iter(testloader))
#print(test_image,test_label)
classes=('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')def imshow(img):img=img/2+0.5                                #逆转了归一化,但是没有逆转totensor中将255->1的操作,所以像素较低npimg=img.numpy()plt.imshow(np.transpose(img,(1,2,0)))        #图片输出遵循[H,W,C]需要在逆转回来plt.show()
#显示当前画图的label
print(' '.join('%5s'%classes[test_label[j]]for j in range(16)))
#画图,根据test_loader此时batch_size共16张显示图像
imshow(torchvision.utils.make_grid(test_image))  #把若干图片拼成一副图像,并显示

3.5建立模型

net=LeNet()
net.to(device)                                   #用gpu跑,存在device
loss_function=nn.CrossEntropyLoss()              #损失交叉熵
optimizer=optim.Adam(net.parameters(),lr=0.0001) #网络中若干参数,包括权重W,偏置bias

3.6训练模型

for epoch in range(50):running_loss=0.0for step,data in enumerate(trainloader,start=0):inputs,labels=dataoptimizer.zero_grad()                          #清除历史梯度,防止对历史梯度进行累加outputs=net(inputs.to(device))                 #正向传播,存在deviceloss=loss_function(outputs,labels.to(device))  #计算损失交叉熵,存在deviceloss.backward()                     #反向传播optimizer.step()                    #学习率更新,由于Adam计算方式running_loss+=loss.item()           #计算误差损失if step%500==499:                   #每500次计算一次误差和accwith torch.no_grad():                           #with中的语句不计算误差损失梯度,防止内存崩掉outputs=net(test_image.to(device))          #正向传播,存在devicepredict_y=torch.max(outputs,dim=1)[1]       #网络输出最优解的索引,即标签类别accuracy=(predict_y==test_label.to(device)).sum().item()/test_label.size(0)  #用最优解的标签类别与真实的标签类别比较,求和,item()返回0或1值,# 而不返回tensor值,总和除以总测试集数量,存在deviceprint('[%d,%5d] train_loss: %.3f test_accuracy: %.3f'%    #迭代epoch和step(epoch+1,step+1,running_loss/500,accuracy))running_loss=0
print('Finish Training')

3.7保存模型

save_path='./Lenet.pth'                  #保存模型
torch.save(net.state_dict(),save_path)   

net.state_dict()获取网络中各层参数字典形式,net.parameters()获取网络中参数值,但没有标签,tensor型

4、predict部分代码

4.1导入库

import torch
import torchvision.transforms as transforms
from PIL import Image
from model import LeNet

4.2预处理

transforms=transforms.Compose([transforms.Resize((32,32)),            #将预测图片转换成32*32的与lenet网络相同的input模型transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))]
)

4.3读取模型并预测新图片

net=LeNet()
net.load_state_dict(torch.load('Lenet.pth'))               #读取模型img=Image.open('plane.jpeg')                                 #打开新图片
img=transforms(img)                                        #对图片进行预处理
im=torch.unsqueeze(img,dim=0)                              #由于模型训练所需的四维张量顺序是[B,C,H,W],而当前顺序为[C,H,W],缺少batch维度。with torch.no_grad():                                      outputs=net(img)                                       #正向传播predict=torch.max(outputs,dim=1)[1].data.numpy()       #预测的最大可能性类别索引print((torch.softmax(outputs,dim=1).numpy())[0].max()) #输出预测率classes=('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')
print(classes[int(predict)])                               

测试图片为下图:

输出准确率为0.9999,类别为plane

参考视频:2.1 pytorch官方demo(Lenet)_哔哩哔哩_bilibili

深度学习(1)--LeNet相关推荐

  1. 深度学习笔记-LeNet和AlexNet

    目录 LeNet模型 AlexNet模型 LeNet模型 卷积层尝试解决这两个问题: (1)卷积层保留输入形状,使图像的像素在高和宽两个方向上的相关性均可能被有效识别: (2)卷积层通过滑动窗口将同一 ...

  2. [深度学习-总结]LeNet网络的权重的大小的计算

    LeNet 的权重总量计算 上面这个图的左下角就是每层的权重多少的计算. 注意-下采样(池化层)不需要训练权重 Conv 1: 1x6x5x5 +6 = 156 Conv3: 6x16x5x5 + 1 ...

  3. pytorch深度学习框架——实现病虫害图像分类

    一.pytorch框架 1.1.概念 PyTorch是一个开源的Python机器学习库,基于Torch,用于自然语言处理等应用程序. 2017年1月,由Facebook人工智能研究院(FAIR)基于T ...

  4. 深度学习(DL)与卷积神经网络(CNN)学习随笔-05-基于Python的LeNet之CNN

    本文原链接可以查看更多文章    博文01介绍了CNN的基本结构.博文02.03.04依次介绍了卷积操作.LR模型的建立及实现,MLP模型及实现.这些都是作为实现LeNet的铺垫.因为LeNet的实现 ...

  5. MINIST深度学习识别:python全连接神经网络和pytorch LeNet CNN网络训练实现及比较(三)...

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 在前两篇文章MINIST深度学习识别:python全连接神经网络和pytorch LeNet CNN网 ...

  6. 机器学习——深度学习之卷积神经网络(CNN)——LeNet卷积神经网络结构

    目录 一.卷积神经网络 1.卷积神经的作用 2.LeNet 1)数据库准备--minst 2)模型· 二.关于卷积神经网络结构的一些术语定义 1.特征图(Feature map) 2.height(长 ...

  7. [人工智能-深度学习-33]:卷积神经网络CNN - 常见分类网络- LeNet网络结构分析与详解

    作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/detai ...

  8. 《动手学深度学习》(四) -- LeNet、AlexNet、VGG、NiN、GoogLeNet、ResNet、DenseNet 实现

    上一小节学习了卷积神经网络的卷积层和池化层的实现,趁热打铁继续学习现代卷积神经网络的搭建,欢迎小伙伴们一起学习和交流~ 为了能够应⽤softmax回归和多层感知机,我们⾸先将每个⼤小为28×2828 ...

  9. 深度学习面试题12:LeNet(手写数字识别)

    目录 神经网络的卷积.池化.拉伸 LeNet网络结构 LeNet在MNIST数据集上应用 参考资料 LeNet是卷积神经网络的祖师爷LeCun在1998年提出,用于解决手写数字识别的视觉任务.自那时起 ...

  10. 【深度学习】MLP/LeNet/AlexNet/GoogLeNet/ResNet在三个不同数据集上的分类效果实践

    本文是深度学习课程的实验报告 使用了MLP/LeNet/AlexNet/GoogLeNet/ResNet五个深度神经网络模型结构和MNIST.Fashion MNIST.HWDB1三个不同的数据集,所 ...

最新文章

  1. linux 一个超简单的makefile
  2. MacOS安装过程需要注意的几个问题
  3. mysqldump备份还原
  4. 使用java写js中类似setTimeout的代码
  5. 【Flink】Flink Exceeded checkpoint tolerable failure threshold
  6. 一、Oracle学习笔记:认识数据库
  7. Java语言程序设计(第3版)沈泽刚主编第6,7,8章课后习题答案
  8. vscode下载历史版本
  9. Android之ContentProvider总结
  10. Blazor使用PDFObject预览pdf文件
  11. opencv实现摄像头的实时人脸识别
  12. 关于树莓派(一):如何让树莓派和笔记本直连SSH
  13. CANopen基本原理及其应用(二)——对象字典和通讯机制
  14. 解决图片处理插件image-conversion压缩后图片底色变黑
  15. STL常用——acwing——yxc
  16. 讨论读书与命运及人生的意义
  17. MATLAB指数拟合
  18. java系统高并发的解决方案
  19. cmake使用教程(实操版)(六)
  20. debugx5.qq.com清除微信浏览器缓存

热门文章

  1. 软件测试中性能调优的过程解析
  2. python二维数组切片规则_详解Python二维数组与三维数组切片的方法
  3. oracle批量替换空格
  4. Babel的presets和plugins笔记
  5. 《林超:给年轻人的跨学科通识课》导图 02:系统论模型
  6. git保存用户名和密码,不用每次输入账号
  7. HTC仅限拨打紧急电话
  8. 微信小程序怎么实现轮播图
  9. 多线程与高并发(四)
  10. X64驱动:内核中的文件回调