【新手适用】手把手教你从零开始实现一个基于Pytorch的卷积神经网络CNN一: 创建model模块和加载数据集

教程:j从零开始实现一个基于Pytorch的卷积神经网络 - 知乎

目录

 网络结构

 1 初始化

2 前向传播forward函数

2.1 forward函数定义

2.2 view函数和size函数

 如何获取channels? 

如何获取batchsize? 

2.3 forward实现

2.4 main方法调用


模型命名为LeNet,创建一个名为LeNet的类,该类继承了nn.Module类,写法如下:

class LeNet(nn.Module):

 网络结构

从图中可以看出,其输入32x32的灰度图像,由于MNIST数据集的图像为28x28,因此,我们将输入改为28x28,并依次计算每一层输出的特征图大小。其每一层参数大致如下:

输入层:输入大小28x28,通道数为1。注意:本层不算LeNet-5的网络结构,一般情况下不将输入层视为网络层次结构之一

C1-卷积层:输入大小28x28,通道数为1;输出大小28x28,通道数为6;卷积核大小为5x5;步长为1;边缘补零为2;激活函数为ReLU。注意:为了提升卷积神经网络的效果,在每个卷积层后添加激活函数,本教程使用的激活函数为ReLU。

S2-池化层:输入大小28x28,通道数为6;输出大小14x14,通道数为6;池化核大小为2x2;步长为2;池化方式为最大池化。

C3-卷积层:输入大小14x14,通道数为6;输出大小10x10,通道数为16;卷积核大小为5x5;步长为1;边缘补零为0;激活函数为ReLU。

S4-池化层:输入大小10x10,通道数为16;输出大小5x5,通道数为16;池化核大小为2x2;步长为2;池化方式为最大池化。

C5-卷积层:输入大小5x5,通道数为16;输出大小1x1,通道数为120;卷积核大小为5x5;步长为1;边缘补零为0;激活函数为ReLU。注意:这层也可以看作全连接层,可以通过全连接的方法实现。

F6-全连接层:输入为120维向量;输出为84维向量;激活函数为ReLU。

OUTPUT-输出层:输入为84维向量;输出为10维向量。注意:该层也是全连接层,且不带激活函数。

 1 初始化

 __init__函数即初始化,主要用于定义每一层的构成,如卷积、池化层等;根据网络结构对每一层的参数进行定义。

# 初始化模型def __init__(self):super(LeNet,self).__init__()# 定义每一层的操作和参数self.C1 = nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5,stride=1,padding=2)self.R1 = nn.ReLU()self.S1 = nn.MaxPool2d(kernel_size=2)self.C2 = nn.Conv2d(in_channels=6,out_channels=16,kernel_size=5,stride=1,padding=0)self.R2 = nn.ReLU()self.S2 = nn.MaxPool2d(kernel_size=2)self.C3 = nn.Conv2d(in_channels=16,out_channels=120,kernel_size=5,padding=0,stride=1)self.R3 = nn.ReLU()#F6-全连接层:输入为120维向量;输出为84维向量;激活函数为ReLU。self.f = nn.Linear(in_features=120,out_features=84)self.R4 = nn.ReLU()# OUTPUT-输出层:输入为84维向量;输出为10维向量。注意:该层也是全连接层,且不带激活函数。self.OUT = nn.Linear(in_features=84,out_features=10)

2 前向传播forward函数

forward函数即前向传播,主要用于确定每一层之间的顺序,使得模型可以正常使用。

2.1 forward函数定义

前向传播函数需要传入self和输入的变量,一般写为x,即forward(self, x)。在函数内把之前定义好的层按顺序调用,每一层在计算后会返回结果;

我们需要一个变量进行保存,即c1 = self.C1(x),在最后将最后一步的计算结果返回。当网络中不存在跳跃连接或密集连接等分支结构的情况下,可以直接用x作为中间变量。

 forward函数定义步骤如下:

  1.  依次调用前面定义的网络层
  2. 修改需要变化的张量维度

2.2 view函数和size函数

在pytorch中,图像数据以一个四维张量传入模型,其形状为[batch_size, channels, h, w]

  • batch_size即批大小,我们一般会一次性将一批图像送进网络处理,这一批图像的数量即为批大小;
  • channel即通道数,也就是之前卷积层的channels;
  • h和w分别代表图像的高和宽。

Conv2d和MaxPool2d都接受以上形状的输入,ReLU接受任意形状的输入,而Linear只接受传入一个二维的张量,形状为[batch_size, length]

  • length表示长度,即向量的维度。

因此可以使用view()方法把卷积层输出的四维张量转换为二维张量。

e.g. 最后一个卷积层生成的特征图形状为[batch_size, channels, 1, 1],要将其转换为[batch_size, channels]。-> view(batchsize,channels)

 如何获取channels? 

可直接填入-1。

填写-1会让电脑自动计算这一栏所需参数的大小,这个方法在实际搭建模型的时候非常好用,因此大家一般都会写为-1。

如何获取batchsize? 

 若已知批大小,就可以直接把batch_size填入。但是,在实际使用中batch_size可能会随着超参数的变化而改变。

使用size()方法获取batchsize。

在size方法的括号内填上维度即可返回所在维度的大小,如x是一个形状为[16, 3, 384, 256]的张量,x.size(0)可获取张量中第一个维度的大小,即16,为批大小。

 最后,使用x保存返回值,x = x.view(x.size(0), -1)

2.3 forward实现

    def forward(self,x):x = self.C1(x)x = self.R1(x)x = self.S1(x)x = self.C2(x)x = self.R2(x)x = self.S2(x)x = self.C3(x)x = self.R3(x)# 改变维度x = x.view(x.size(0),-1)x = self.f(x)x = self.R4(x)x = self.OUT(x)return x

2.4 main方法调用

if __name__ == "__main__":model = LeNet()
# 测试数据a = torch.randn(1, 1, 28, 28)b = model(a)print(b)

2.5 代码 

import torch
import torch.nn as nnclass LeNet(nn.Module):# 初始化模型def __init__(self):super(LeNet,self).__init__()# 定义每一层的操作和参数self.C1 = nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5,stride=1,padding=2)self.R1 = nn.ReLU()self.S1 = nn.MaxPool2d(kernel_size=2)self.C2 = nn.Conv2d(in_channels=6,out_channels=16,kernel_size=5,stride=1,padding=0)self.R2 = nn.ReLU()self.S2 = nn.MaxPool2d(kernel_size=2)self.C3 = nn.Conv2d(in_channels=16,out_channels=120,kernel_size=5,padding=0,stride=1)self.R3 = nn.ReLU()#F6-全连接层:输入为120维向量;输出为84维向量;激活函数为ReLU。self.F4 = nn.Linear(in_features=120,out_features=84)self.R4 = nn.ReLU()# OUTPUT-输出层:输入为84维向量;输出为10维向量。注意:该层也是全连接层,且不带激活函数。self.OUT = nn.Linear(in_features=84,out_features=10)# 定义前向传播层def forward(self,x):x = self.C1(x)x = self.R1(x)x = self.S1(x)x = self.C2(x)x = self.R2(x)x = self.S2(x)x = self.C3(x)x = self.R3(x)# 改变维度x = x.view(x.size(0),-1)x = self.F4(x)x = self.R4(x)x = self.OUT(x)return xif __name__ == "__main__":model = LeNet()a = torch.randn(1, 1, 28, 28)b = model(a)print(b)

 

3  数据集

download_dataset.py 

import torchvision
torchvision.datasets.MNIST('./data', download=True)

导入torchvision包,torchvision.dataset中有很多经典的数据集可以下载。

下载MNIST数据集:torchvision.datasets.MNIST(root, train, transform, target_transform, download)

设置root为data文件夹,将download设置为True,运行该文件可完成下载。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业微信变更主体对用户有影响吗?

企业微信变更主体有什么作用?现在很多公司都用企业微信来加客户,有时候辛辛苦苦积累了很多客户,但是公司却因为各种各样的原因需要注销,那么就需要通过企业微信变更主体的方法,把企业微信绑定的公司更改为最新的。企业…

arduino 编程esp8266

概述: 1.wifi连接,扫描WiFi连接json序列化,http.get和http.post。 2.数据的存储和全局常量的flash定义。 3.文件的存储读写。 4.板子外设资源的访问:Libraries - Arduino Reference 注意:开发板未nodeMCU1.0(esp-12e)…

ISIS知识点【笔记】

isis配置 【Isis进程,Isis实体认证,Is-level,Isis接口开启功能:isis enable 1】 【Isis接口认证】 【49.0002.0000.0000.0004.00 前两段:区域ID。第三,四,五:主机ID。00&#xff…

Java后端八股------消息中间件篇

自动确认没收到,实现重复消费问题,可以用业务唯一标识来确定业务是否被消费。 TTL也就是超时时间,一般去dead letter的时间为min(消息的ttl,queue的ttl)。 acksall设置是最安全的,但是效率太低了,实际的生…

鲜花销售小程序|基于微信小程序的鲜花销售系统设计与实现(源码+数据库+文档)

鲜花销售小程序目录 目录 基于微信小程序的鲜花销售系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1前台功能模块 2、后台功能模块 1、管理员功能模块 四、数据库设计 1、实体ER图 2、具体的表设计如下所示: 五、核心代码 六、论文参考 七、…

Java开发从入门到精通(一):ZK 集群的部署

ZK 集群的部署 server.<节点ID>:<数据同步端口>:<选举端口> 节点 ID&#xff1a;为 1 到 125 之间的数字&#xff0c;写到对应服务节点的{dataDir}/myid 文件中。 IP 地址&#xff1a;节点的远程 IP 地址&#xff0c;可以相同&#xff0c;生产环境建议用不同…

突破编程_C++_设计模式(享元模式)

1 享元模式的基本概念 享元模式&#xff08;Flyweight Pattern&#xff09;是一种主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能的设计模式。它通过使用共享对象来支持大量的细粒度对象&#xff0c;从而减少了内存占用。在享元模式中&#xff0c;有些对象可…

【io.net】问题汇总

【io.net】问题汇总 大家最近挖挖的如火如荼&#xff0c;可是不论是社区活动积分和参与挖矿积分&#xff0c;大家遇到了很多类似问题&#xff0c;重复解决。 因此我这里整理了一下常见的相关问题&#xff0c;大家可以一站式找到解决方案。解决方案主要分为运营和挖矿两个两面…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的障碍物检测系统(Python+PySide6界面+训练代码)

摘要&#xff1a;开发障碍物检测系统对于道路安全性具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个障碍物检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0c;展示了不同模型间的性能…

如何解决由触发器导致 MySQL 内存溢出?

由触发器导致得 OOM 案例分析过程和解决方式。 作者&#xff1a;龚唐杰&#xff0c;爱可生 DBA 团队成员&#xff0c;主要负责 MySQL 技术支持&#xff0c;擅长 MySQL、PG、国产数据库。 爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转载请联系小编…

JavaScript 面试题

问题 1 // 请解释下面代码的输出结果 console.log(1 "2" "2"); console.log(1 "2" "2"); console.log(1 -"1" "2"); console.log("A" - "B" "2"); console.log(&qu…

零基础学习JS--基础篇--使用对象

JavaScript 的设计是一个简单的基于对象的范式。一个对象就是一系列属性的集合&#xff0c;一个属性包含一个名和一个值。一个属性的值可以是函数&#xff0c;这种情况下属性也被称为方法。除了浏览器里面预定义的那些对象之外&#xff0c;你也可以定义你自己的对象。本章节讲述…

苹果cms模板保护设置,防止被扒

苹果cms模板保护设置&#xff0c;防止被扒 如今互联网时代&#xff0c;网站模板前端被扒是常有的事&#xff0c;如何防止模板数据被扒&#xff1f; 保护设置方法&#xff1a; 登录宝塔 找到安装模板的网站 设置禁止访问文件 方法参考截图后缀填&#xff1a;php|html 目录填&a…

OA系统中的九大常用审批场景,你都晓得吗?

Hi&#xff0c;我是贝格前端工场&#xff0c;今天继续来剖析OA的功能&#xff0c;这次重点分析审批功能&#xff0c;欢迎老铁们点赞评论转发。 一、OA的审批功能和流程 OA的审批功能是指在办公自动化系统中&#xff0c;通过电子化的方式实现对各种申请、请求或业务流程的审批管…

项目管理工具及模板(甘特图、OKR周报、任务管理、头脑风暴等)

项目管理常用模板大全&#xff1a; 1. 项目组OKR周报 2. 项目组传统周报工作法 3. 项目甘特图 4. 团队名单 5. 招聘跟进表 6. 出勤统计 7. 年度工作日历 8. 项目工作年计划 9. 版本排期 10. 项目组任务管理 11. 项目规划模板 12. 产品分析报告 13. 头脑风暴 信息化项目建设全套…

阻塞队列学习

1、什么是阻塞队列&#xff1f; 顾名思义&#xff0c;就是支持阻塞的队列&#xff0c;相比于其他的队列&#xff0c;阻塞队列支持以下特性&#xff1a; 队列为空的时候&#xff0c;获取元素的线程会等待队列变为非空。队列为满的时候&#xff0c;存储元素的线程会等待队列可以…

Python 单元测试

本篇为Python的单元测试的方法及示例 目录 概念 结果 示例 对函数进行测试 创建函数文件 创建测试文件 测试结果 对类进行测试 创建待测试类 创建测试文件 文档测试 创建函数 进行测试 总结 概念 用来对一个函数、一个类或者一个模块来进行正确性校验工作 结果 …

提取B站视频教程详情

提取B站视频教程详情 背景 B站这个视频列表是真的体验感太差了,有时候想把章节复制下来,再对应的章节下面做笔记,实在是太难搞了,于是就有了这篇文文章 根据关键字获取视频id Test public void list() {String url "https://api.bilibili.com/x/web-interface/wbi/sea…

虚拟机(KVM)克隆

当需要批量部署虚拟机时&#xff0c;可以使用克隆虚拟机的方式来进行。 使用图形界面来克隆虚拟机。 [rootzhoujunru_node1 zhou]# virsh list --allId Name State ------------------------------ vm01 shut off- vm01-clone shut off克隆完成。

Django入门 整体流程跑通

Django学习笔记 一、Django整体流程跑通 1.1安装 pip install django //安装 import django //在python环境中导入django django.get_version() //获取版本号&#xff0c;如果能获取到&#xff0c;说明安装成功Django目录结构 Python310-Scripts\django-admi…