Pytorch-卷积神经网络CNN之lenet5的Pytorch代码实现
先说一个小知识,助于理解代码中各个层之间维度是怎么变换的。
卷积函数:一般只用来改变输入数据的维度,例如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代码实现的更多相关文章
- 写给程序员的机器学习入门 (八) - 卷积神经网络 (CNN) - 图片分类和验证码识别
这一篇将会介绍卷积神经网络 (CNN),CNN 模型非常适合用来进行图片相关的学习,例如图片分类和验证码识别,也可以配合其他模型实现 OCR. 使用 Python 处理图片 在具体介绍 CNN 之前, ...
- 卷积神经网络CNN总结
从神经网络到卷积神经网络(CNN)我们知道神经网络的结构是这样的: 那卷积神经网络跟它是什么关系呢?其实卷积神经网络依旧是层级网络,只是层的功能和形式做了变化,可以说是传统神经网络的一个改进.比如下图 ...
- 卷积神经网络(CNN)学习笔记1:基础入门
卷积神经网络(CNN)学习笔记1:基础入门 Posted on 2016-03-01 | In Machine Learning | 9 Comments | 14935 Vie ...
- 深度学习之卷积神经网络CNN
转自:https://blog.csdn.net/cxmscb/article/details/71023576 一.CNN的引入 在人工的全连接神经网络中,每相邻两层之间的每个神经元之间都是有边相连 ...
- 深度学习之卷积神经网络CNN及tensorflow代码实例
深度学习之卷积神经网络CNN及tensorflow代码实例 什么是卷积? 卷积的定义 从数学上讲,卷积就是一种运算,是我们学习高等数学之后,新接触的一种运算,因为涉及到积分.级数,所以看起来觉得很复杂 ...
- 深度学习之卷积神经网络CNN及tensorflow代码实现示例
深度学习之卷积神经网络CNN及tensorflow代码实现示例 2017年05月01日 13:28:21 cxmscb 阅读数 151413更多 分类专栏: 机器学习 深度学习 机器学习 版权声明 ...
- 卷积神经网络(CNN)前向传播算法
在卷积神经网络(CNN)模型结构中,我们对CNN的模型结构做了总结,这里我们就在CNN的模型基础上,看看CNN的前向传播算法是什么样子的.重点会和传统的DNN比较讨论. 1. 回顾CNN的结构 在上一 ...
- 卷积神经网络(CNN)反向传播算法
在卷积神经网络(CNN)前向传播算法中,我们对CNN的前向传播算法做了总结,基于CNN前向传播算法的基础,我们下面就对CNN的反向传播算法做一个总结.在阅读本文前,建议先研究DNN的反向传播算法:深度 ...
- 【深度学习系列】手写数字识别卷积神经--卷积神经网络CNN原理详解(一)
上篇文章我们给出了用paddlepaddle来做手写数字识别的示例,并对网络结构进行到了调整,提高了识别的精度.有的同学表示不是很理解原理,为什么传统的机器学习算法,简单的神经网络(如多层感知机)都可 ...
- 深度学习之卷积神经网络(CNN)详解与代码实现(二)
用Tensorflow实现卷积神经网络(CNN) 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/10737065. ...
随机推荐
- 学习ASP.NET Core Razor 编程系列文章目录
学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二--添加一个实体 学习ASP.NET Core Razor 编程系列三--创建数据表及创建项目 ...
- Spring5课堂笔记
Spring5 1..Spring 1.1.简介 Spring --> 春天,为开源软件带来了春天 2002,首次推出了Spring框架的雏形:interface21框架! Spring框架以i ...
- linux 三剑客命令
Linux 命令集合 目录 Linux 命令集合 基础概念 1 软连接和硬链接 1.1 基础概念 1.2 如何创建软链接 零.正则 01 区别 02 通配符 03 基础正则 04 扩展正则 一 awk ...
- autohotkey 设置快捷键 设置光标位置 (ctrl + alt + Numpad0)
autohotkey 设置快捷键 设置光标位置 (ctrl + alt + Numpad0) 原因 3个屏幕,所以鼠标设置的灵敏度非常高,经常就找不到鼠标在哪了. 设置个快捷键,让鼠标每次都初始化一个 ...
- [VueJsDev] 基础知识 - AutoNumber VsCode 插件开发
[VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html AutoNumber VsCode插件开发 ::: deta ...
- Spring Boot获取配置参数最简单常用的两种方式
一.自定义属性及常量 在开发过程中,我们常常用到的多环境配置文件,常用的有:dev,test,prod,在不同环境下,我们用到的一样的配置参数,例如:redis,mq,回调接口的url配置.这个情况, ...
- RabbitMQ集群运维实践
一.RabbitMQ的集群模式 主要有两种:普通集群模式和镜像队列模式.下面分别介绍这两种模式的原理: 1.普通集群模式: 在普通集群模式下,RabbitMQ的集群节点之间主要同步元数据,而不同步存储 ...
- Android之Window和弹窗问题
目录介绍 10.0.0.1 Window是什么?如何通过WindowManager添加Window(代码实现)?WindowManager的主要功能是什么? 10.0.0.2 Window概念解析?W ...
- 记录--vue3+setup+ts 知识总结
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 vue3 于 2020 年 09 月 18 日正式发布,2022 年 2 月 7 日 vue3 成为新的默认版本 距离 vue3 正式发布 ...
- 开发必会系列:《深入理解JVM(第二版)》读书笔记
一 开始前 HotSpot:http://xiaomogui.iteye.com/blog/857821 http://blog.csdn.net/u011521890/article/detail ...