先说一个小知识,助于理解代码中各个层之间维度是怎么变换的。

卷积函数:一般只用来改变输入数据的维度,例如3维到16维。

Conv2d()

Conv2d(in_channels:int,out_channels:int,kernel_size:Union[int,tuple],stride=1,padding=o):
"""
:param in_channels: 输入的维度
:param out_channels: 通过卷积核之后,要输出的维度
:param kernel_size: 卷积核大小
:param stride: 移动步长
:param padding: 四周添多少个零
"""

一个小例子:

import torch
import torch.nn
# 定义一个16张照片,每个照片3个通道,大小是28*28
x= torch.randn(16,3,32,32)
# 改变照片的维度,从3维升到16维,卷积核大小是5
conv= torch.nn.Conv2d(3,16,kernel_size=5,stride=1,padding=0)
res=conv(x) print(res.shape)
# torch.Size([16, 16, 28, 28])
# 维度升到16维,因为卷积核大小是5,步长是1,所以照片的大小缩小了,变成28

卷积神经网络实战之Lenet5:

下面放一个示例图,代码中的过程就是根据示例图进行的

  • 1.经过一个卷积层,从刚开始的[b,3,32,32]-->[b,6,28,28]
  • 2.经过一个池化层,从[b,6,28,28]-->[b,6,14,14]
  • 3.再经过一个卷积层,从[b,6,14,14]-->[b,16,10,10]
  • 4.再经过一个池化层,从[b,16,10,10]-->[b,16,5,5]
  • 5.经过三个个全连接层,将数据[b,16,5,5]-->[b,120]-->[b,84]-->[b,10]

Lenet5的构造如下:

Lenet5(
(conv_unit): Sequential(
(0): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))
(1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(fc_unit): Sequential(
(0): Linear(in_features=400, out_features=120, bias=True)
(1): ReLU()
(2): Linear(in_features=120, out_features=84, bias=True)
(3): ReLU()
(4): Linear(in_features=84, out_features=10, bias=True)
)
)

程序运行前,先启动visdom,如果没有配置好visdom环境的,先百度安装好visdom环境

  • 1.使用快捷键win+r,在输入框输出cmd,然后在命令行窗口里输入python -m visdom.server,启动visdom

代码实战

定义一个名为lenet5.py的文件,代码如下

import torch
from torch import nn
import torch.optim
import torch.nn
from torch.nn import functional as F class Lenet5(nn.Module):
# for cifar10 dataset.
def __init__(self):
super(Lenet5, self).__init__() # 卷积层 Convolutional
self.conv_unit = nn.Sequential(
# x:[b,3,32,32]==>[b,6,28,28]
nn.Conv2d(3, 6, kernel_size=5, stride=1, padding=0),
# x:[b,6,28,28]==>[b,6,14,14]
nn.MaxPool2d(kernel_size=2, stride=2, padding=0),
#[b,6,14,14]==>[b,16,10,10]
nn.Conv2d(6,16,kernel_size=5,stride=1,padding=0),
# x:[b,16,10,10]==>[b,16,5,5]
nn.MaxPool2d(kernel_size=2,stride=2,padding=0), ) # 全连接层fully connected
self.fc_unit=nn.Sequential(
nn.Linear(16*5*5,120),
nn.ReLU(),
nn.Linear(120,84),
nn.ReLU(),
nn.Linear(84,10)
) def forward(self,x):
"""
:param x:[b,3,32,32]
:return:
"""
batchsz=x.size(0)
# 卷积层池化层运算 [b,3,32,32]==>[b,16,5,5]
x=self.conv_unit(x) # 对数据进行打平,方便后边全连接层进行运算[b,16,5,5]==>[b,16*5*5]
x=x.view(batchsz,16*5*5) # 全连接层[b,16*5*5]==>[b,10]
logits=self.fc_unit(x) return logits
# loss=self.criteon(logits,y) def main():
net=Lenet5()
# [b,3,32,32]
temp = torch.randn(2, 3, 32, 32)
out = net(temp)
# [b,16,5,5]
print("lenet_out:", out.shape) if __name__ == '__main__':
main()

定义一个名为main.py的文件,代码如下

import torch
from torchvision import datasets
from torchvision import transforms
from torch.utils.data import DataLoader
from torch import nn,optim
from visdom import Visdom
from lenet5 import Lenet5 def main():
batch_siz=32
cifar_train = datasets.CIFAR10('cifar',True,transform=transforms.Compose([
transforms.Resize((32,32)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
]),download=True)
cifar_train=DataLoader(cifar_train,batch_size=batch_siz,shuffle=True) cifar_test = datasets.CIFAR10('cifar',False,transform=transforms.Compose([
transforms.Resize((32,32)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
]),download=True)
cifar_test=DataLoader(cifar_test,batch_size=batch_siz,shuffle=True) x,label = iter(cifar_train).next()
print('x:',x.shape,'label:',label.shape) # 指定运行到cpu //GPU
device=torch.device('cpu')
model = Lenet5().to(device) # 调用损失函数use Cross Entropy loss交叉熵
# 分类问题使用CrossEntropyLoss比MSELoss更合适
criteon = nn.CrossEntropyLoss().to(device)
# 定义一个优化器
optimizer=optim.Adam(model.parameters(),lr=1e-3)
print(model) viz=Visdom()
viz.line([0.],[0.],win="loss",opts=dict(title='Lenet5 Loss'))
viz.line([0.],[0.],win="acc",opts=dict(title='Lenet5 Acc')) # 训练train
for epoch in range(1000):
# 变成train模式
model.train()
# barchidx:下标,x:[b,3,32,32],label:[b]
for barchidx,(x,label) in enumerate(cifar_train):
# 将x,label放在gpu上
x,label=x.to(device),label.to(device)
# logits:[b,10]
# label:[b]
logits = model(x)
loss = criteon(logits,label) # viz.line([loss.item()],[barchidx],win='loss',update='append')
# backprop
optimizer.zero_grad()
loss.backward()
optimizer.step()
viz.line([loss.item()],[epoch],win='loss',update='append')
print(epoch,'loss:',loss.item()) # 变成测试模式
model.eval()
with torch.no_grad():
# 测试test
# 正确的数目
total_correct=0
total_num=0
for x,label in cifar_test:
# 将x,label放在gpu上
x,label=x.to(device),label.to(device)
# [b,10]
logits=model(x)
# [b]
pred=logits.argmax(dim=1)
# [b] = [b'] 统计相等个数
total_correct+=pred.eq(label).float().sum().item()
total_num+=x.size(0)
acc=total_correct/total_num
print(epoch,'acc:',acc) viz.line([acc],[epoch],win='acc',update='append')
# viz.images(x.view(-1, 3, 32, 32), win='x') if __name__ == '__main__':
main()

测试结果

准确率刚开始是有一定的上升的,最高可达64%,后来准确率就慢慢的下降。

Pytorch-卷积神经网络CNN之lenet5的Pytorch代码实现的更多相关文章

  1. 写给程序员的机器学习入门 (八) - 卷积神经网络 (CNN) - 图片分类和验证码识别

    这一篇将会介绍卷积神经网络 (CNN),CNN 模型非常适合用来进行图片相关的学习,例如图片分类和验证码识别,也可以配合其他模型实现 OCR. 使用 Python 处理图片 在具体介绍 CNN 之前, ...

  2. 卷积神经网络CNN总结

    从神经网络到卷积神经网络(CNN)我们知道神经网络的结构是这样的: 那卷积神经网络跟它是什么关系呢?其实卷积神经网络依旧是层级网络,只是层的功能和形式做了变化,可以说是传统神经网络的一个改进.比如下图 ...

  3. 卷积神经网络(CNN)学习笔记1:基础入门

    卷积神经网络(CNN)学习笔记1:基础入门 Posted on 2016-03-01   |   In Machine Learning  |   9 Comments  |   14935  Vie ...

  4. 深度学习之卷积神经网络CNN

    转自:https://blog.csdn.net/cxmscb/article/details/71023576 一.CNN的引入 在人工的全连接神经网络中,每相邻两层之间的每个神经元之间都是有边相连 ...

  5. 深度学习之卷积神经网络CNN及tensorflow代码实例

    深度学习之卷积神经网络CNN及tensorflow代码实例 什么是卷积? 卷积的定义 从数学上讲,卷积就是一种运算,是我们学习高等数学之后,新接触的一种运算,因为涉及到积分.级数,所以看起来觉得很复杂 ...

  6. 深度学习之卷积神经网络CNN及tensorflow代码实现示例

    深度学习之卷积神经网络CNN及tensorflow代码实现示例 2017年05月01日 13:28:21 cxmscb 阅读数 151413更多 分类专栏: 机器学习 深度学习 机器学习   版权声明 ...

  7. 卷积神经网络(CNN)前向传播算法

    在卷积神经网络(CNN)模型结构中,我们对CNN的模型结构做了总结,这里我们就在CNN的模型基础上,看看CNN的前向传播算法是什么样子的.重点会和传统的DNN比较讨论. 1. 回顾CNN的结构 在上一 ...

  8. 卷积神经网络(CNN)反向传播算法

    在卷积神经网络(CNN)前向传播算法中,我们对CNN的前向传播算法做了总结,基于CNN前向传播算法的基础,我们下面就对CNN的反向传播算法做一个总结.在阅读本文前,建议先研究DNN的反向传播算法:深度 ...

  9. 【深度学习系列】手写数字识别卷积神经--卷积神经网络CNN原理详解(一)

    上篇文章我们给出了用paddlepaddle来做手写数字识别的示例,并对网络结构进行到了调整,提高了识别的精度.有的同学表示不是很理解原理,为什么传统的机器学习算法,简单的神经网络(如多层感知机)都可 ...

  10. 深度学习之卷积神经网络(CNN)详解与代码实现(二)

    用Tensorflow实现卷积神经网络(CNN) 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/10737065. ...

随机推荐

  1. 因IPv4和IPv6协议不同而引发的第三方接口调用失效的问题

    记录一次因IPv4和IPv6协议不同而引发的第三方接口调用失效的问题,仅供大家参考!!! 背景介绍 公司有一个微信小程序,我做后端的,负责给小程序提供数据接口.后来因为一系列原因小程序要对接一个中控( ...

  2. 完整塔建一个spring 注解版 mybaties 过程可供复制代码

    第一步引导包.新建工程maven模块 pom.xml 中导入相对应包 ++++++++++++++++++++++++++++++++++++++++++++       1      +++++++ ...

  3. MYSQL索引-下

    前言 丁奇老师的 MYSQL45讲 的关于索引的的两节 深入浅出索引,做个笔记 覆盖索引 插入一个实例表 mysql> create table T ( ID int primary key, ...

  4. Seata的技术调研

    引子 本文不剖析业内分布式组件,只剖析seata这一组件的技术调研.看看是否存在接入价值. 一.概述 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata ...

  5. 封装TornadoFx常用控件库

    github:https://github.com/Stars-One/common-controls 为TornadoFx的封装的常用控件与工具,基于Jfoenix,借鉴Kfoenix 前言 这个开 ...

  6. 20_使用SDL显示BMP图片

    文本的主要内容是:使用SDL显示一张BMP图片,算是为后面的<显示YUV图片>做准备. 为什么是显示BMP图片?而不是显示JPG或PNG图片? 因为SDL内置了加载BMP的API,使用起来 ...

  7. 使用zxing来生成二维码

    使用zxing来生成二维码 二维码已经成为了现代生活中不可或缺的一部分,无论是商业还是个人使用,二维码都有着广泛的应用.而在二维码的生成过程中,zxing是一款非常优秀的开源库,它提供了一系列的API ...

  8. r-nacos v0.4.0版本发布

    r-nacos是一个用 rust重新实现的nacos. r-nacos比java实现的nacos更轻量.快速.稳定:合适在开发.测试.受资限服务等环境平替nacos服务使用. r-nacos v0.4 ...

  9. Oracle 索引原理

    B-Tree索引 一个B树索引只有一个根节点,它实际就是位于树的最顶端的分支节点. 可以用下图一来描述B树索引的结构.其中,B表示分支节点,而L表示叶子节点. 对于分支节点块(包括根节点块)来说,其所 ...

  10. KingbaseES V8R6 备份恢复案例--异机备份ssh认证失败

    案例说明: 在生产环境,数据库服务被重启后,监控发现数据库物理备份的脚本无法执行,故障现象如下所示,从备份日志和sys_log中都出现了远程主机连接认证错误. 1)备份日志:(连接数据库服务器认证错误 ...