PyTorch 深度学习实践-卷积神经网络基础篇

视频指路
参考博客笔记
参考笔记二

文章目录

  • 上课笔记
  • 代码实现
  • 作业实现

上课笔记

如果一个网络全都是由线性层串联起来(torch.nn.Linear(xx, yy)),就叫他全连接的网络(左边节点到右边节点任意两个都存在权重)

先看一下吴恩达或者李宏毅老师的视频了解一下卷积

通过卷积层保留图像的空间特征(结构)

张量的维度是(b, c, w, h) batch, channel, width, height

经过5 * 5的卷积层变成一个4 * 24 * 24的特征图,经过2*2的下采样(减少元素数量,降低运算需求)变成4 * 12 * 12的特征图,再做5 * 5 的卷积, 2 * 2的下采样,变成8 * 4 * 4的特征图(前面是特征提取层),展开成1维向量,最后线性变换映射成10维的输出,用softmax计算分布(分类器)

必须知道输入输出的尺寸

在这里插入图片描述

卷积的例子:

在这里插入图片描述

通道内的每个位置和卷积核的同一位置进行内积,计算后的尺寸大小为原来的长宽-卷积核长宽+1,最后把所有通道计算的结果进行加法得到输出。

在这里插入图片描述

卷积核通道数 = 卷积输入层的通道数;卷积输出层通道数 = 卷积核(组)的个数。

在这里插入图片描述

m个卷积核进行运算后将结果拼接,输出尺寸为m * w * h

在这里插入图片描述

w权重的维度为: m * n * w * h

默认情况下缩小的圈数为卷积核大小/2向下取整,比如(1,28,28)进行5 * 5卷积后是(1, 24, 24) 5 / 2 = 2 缩小两圈等于宽高-4

padding:在输入图像外面周围进行填充0,如果对于3*3的卷积核想让输入输出大小相同设置padding=1,如果对于5 * 5的卷积核想让输入输出大小相同设置padding=2

stride步长,每次滑动的长度

Stride的作用:是成倍缩小尺寸,而这个参数的值就是缩小的具体倍数,比如步幅为2,输出就是输入的1/2;步幅为3,输出就是输入的1/3

下采样:常用的max pooling,最大池化层,运算后通道数量不变,如果是2 * 2的maxpooling,输出尺寸变原来的一半:torch.nn.MaxPool2d(kernel

_size=2)

在这里插入图片描述

class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)self.pooling = torch.nn.MaxPool2d(2)self.fc = torch.nn.Linear(320, 10)def forward(self, x):# flatten data from (n,1,28,28) to (n, 784)batch_size = x.size(0)x = F.relu(self.pooling(self.conv1(x)))x = F.relu(self.pooling(self.conv2(x)))x = x.view(batch_size, -1) # view()函数用来转换size大小。x = x.view(batchsize, -1)中batchsize指转换后有几行,而-1指根据原tensor数据和batchsize自动分配列数。 -1 此处自动算出的是x平摊的元素值/batch_size=320x = self.fc(x)#用交叉熵损失所以最后一层不用激活return xmodel = Net()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

在这里插入图片描述

代码实现

1、torch.nn.Conv2d(1,10,kernel_size=3,stride=2,bias=False)

1是指输入的Channel,灰色图像是1维的;10是指输出的Channel,也可以说第一个卷积层需要10个卷积核;kernel_size=3,卷积核大小是3x3;stride=2进行卷积运算时的步长,默认为1;bias=False卷积运算是否需要偏置bias,默认为False。padding = 0,卷积操作是否补0。

2、self.fc = torch.nn.Linear(320, 10),这个320获取的方式,可以通过x = x.view(batch_size, -1) # print(x.shape)可得到(64,320),64指的是batch,320就是指要进行全连接操作时,输入的特征维度。

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim# prepare datasetbatch_size = 64
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)# design model using classclass Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)self.pooling = torch.nn.MaxPool2d(2)self.fc = torch.nn.Linear(320, 10)def forward(self, x):# flatten data from (n,1,28,28) to (n, 784)batch_size = x.size(0)x = F.relu(self.pooling(self.conv1(x)))x = F.relu(self.pooling(self.conv2(x)))x = x.view(batch_size, -1) # -1 此处自动算出的是320x = self.fc(x)return xmodel = Net()# construct loss and optimizer
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)# training cycle forward, backward, updatedef train(epoch):running_loss = 0.0for batch_idx, data in enumerate(train_loader, 0):inputs, target = datainputs, target = inputs.to(device), target.to(device)optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % 300 == 299:print('[%d, %5d] loss: %.3f' % (epoch+1, batch_idx+1, running_loss/300))running_loss = 0.0def test():correct = 0total = 0with torch.no_grad():for data in test_loader:images, labels = dataoutputs = model(images)_, predicted = torch.max(outputs.data, dim=1)total += labels.size(0)correct += (predicted == labels).sum().item()print('accuracy on test set: %d %% ' % (100*correct/total))if __name__ == '__main__':for epoch in range(10):train(epoch)test()

显卡计算

1:model后面迁移至gpu

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

2:训练和测试的输入输出数据也迁移至gpu

inputs, target = inputs.to(device), target.to(device)

作业实现

卷积层用三个,relu三个,池化三个,线性层三个,对比性能

input(batch, 1, 28, 28) -> conv2d -> relu -> pooling -> conv2d -> relu -> pooling -> conv2d -> relu -> pooling -> linear layer -> linear -> output(batch, 10)

(batch, 1, 28, 28) ->卷积(1, 10, 5)->(10, 24, 24) ->下采样2->(10, 12, 12)->卷积(10, 20, 5)->(20, 8, 8)->下采样2->(20, 4, 4)->卷积(20, 10, 5, padding=2) ->(10, 4 ,4)->下采样(10,2,2)摊平view(batch_size, -1)->l1(40, 32)->l2(32, 16)->l3(16, 10)

(10,12,12)-》(20,6, 6)-》(10, 3, 3)

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import torch.nn.functional as F# 1.数据集准备
batch_size = 64
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
train_dataset = datasets.MNIST(root='../dataset/minist/', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size, num_workers=2)
test_dataset = datasets.MNIST(root='../dataset/minist/', train=False, download=True, transform=transform)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size, num_workers=2)# 2.模型构建
class CNNNet2(torch.nn.Module):def __init__(self):super(CNNNet2, self).__init__()self.cov1 = torch.nn.Conv2d(1, 10,5)self.cov2 = torch.nn.Conv2d(10, 20,5)self.cov3 = torch.nn.Conv2d(20, 10, 3, padding=1)self.pool = torch.nn.MaxPool2d(2)self.l1 = torch.nn.Linear(40, 32)self.l2 = torch.nn.Linear(32, 16)self.l3 = torch.nn.Linear(16, 10)def forward(self, x):batch_size = x.size(0) # B,C,W,H(之前的transform已经将图像转为tensor张量了,取第一个维度就是batch)x = self.pool(torch.relu(self.cov1(x)))x = self.pool(torch.relu(self.cov2(x)))x = self.pool(torch.relu(self.cov3(x)))x = x.view(batch_size, -1)  # batch是不变的,把CWH拉长x = torch.relu(self.l1(x))x = torch.relu(self.l2(x))return self.l3(x)
class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)self.pooling = torch.nn.MaxPool2d(2)self.fc = torch.nn.Linear(320, 10)def forward(self, x):# flatten data from (n,1,28,28) to (n, 784)batch_size = x.size(0)x = F.relu(self.pooling(self.conv1(x)))x = F.relu(self.pooling(self.conv2(x)))x = x.view(batch_size, -1)  # -1 此处自动算出的是320x = self.fc(x)return xmodel1 = Net()
device = torch.device('cuda'if torch.cuda.is_available() else 'cpu')
model1.to(device)model2 = CNNNet2()
model2.to(device)# 3.损失值和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer1 = torch.optim.SGD(model1.parameters(), lr=0.01, momentum=0.5)
optimizer2 = torch.optim.SGD(model2.parameters(), lr=0.01, momentum=0.5)# 4.训练循环
def train(epoch):l1 = 0.0l2 = 0.0for batch_index, (x, y) in enumerate(train_loader):x, y = x.to(device), y.to(device)y_pred1 = model1(x)optimizer1.zero_grad()loss1 = criterion(y_pred1, y)l1 += loss1.item()loss1.backward()optimizer1.step()y_pred2 = model2(x)optimizer2.zero_grad()loss2 = criterion(y_pred2, y)l2 += loss2.item()loss2.backward()optimizer2.step()if batch_index % 300 == 299:print(f'[epoch{epoch+1}---------batch={batch_index+1}---------loss1={round(100*l1/300, 3)}]')l1 = 0.0 # 输出完记得置为0print(f'[epoch{epoch + 1}---------batch={batch_index + 1}---------loss2={round(100 * l2 / 300, 3)}]')l2 = 0.0  # 输出完记得置为0def test():size = 0acc1 = 0acc2 = 0with torch.no_grad():for (x, y) in test_loader:x, y = x.to(device), y.to(device)y_pred1 = model1(x)_, predict1 = torch.max(y_pred1.data, dim=1)  # 0列1行,注意这里取的是data(用到张量的时候要格外小心)size += predict1.size(0)acc1 += (predict1 == y).sum().item()  # 与标签进行比较print('test accuracy1= %.3f %%' % (100 * acc1 / size))size = 0with torch.no_grad():for (x, y) in test_loader:x, y = x.to(device), y.to(device)y_pred2 = model2(x)_, predict2 = torch.max(y_pred2.data, dim=1)  # 0列1行,注意这里取的是data(用到张量的时候要格外小心)size += predict2.size(0)acc2 += (predict2 == y).sum().item()  # 与标签进行比较print('test accuracy2= %.3f %%' % (100 * acc2 / size))return (acc1 / size, acc2 / size)if __name__ == "__main__":epoch_list = []acc_list1 = []acc_list2 = []for epoch in range(10):train(epoch)acc1, acc2 = test()epoch_list.append(epoch)acc_list1.append(acc1)acc_list2.append(acc2)plt.plot(epoch_list, acc_list1)plt.plot(epoch_list, acc_list2)plt.ylabel('accuracy')plt.xlabel('epoch')plt.show()

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloudAlibaba-Seata2.0.0与Nacos2.2.1

一、下载 ## 下载seata wget https://github.com/apache/incubator-seata/releases/download/v2.0.0/seata-server-2.0.0.tar.gz## 解压 tar zxvf seata-server-2.0.0.tar.gz二、执行sql文件 ## 取出sql文件执行 cd /seata/script/server/db/mysql ## 找个mysql数据库执行三、…

【随想】代码优化论

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 目录 1.非必要,不修改、不优化 2.需修改、需优化、搞彻底 随着工作年限的增长,接触到的二手代码也越来越多,无论是同事离职留下的垃圾代码,还是接手烂摊子项目代码,…

Java并发04之线程同步机制

文章目录 1 线程安全1.1 线程安全的变量1.2 Spring Bean1.3 如果保证线程安全 2 synchronized关键字2.1 Java对象头2.1.1 对象组成部分2.1.2 锁类型2.1.3 锁对象 2.2 synchronized底层实现2.2.1 无锁状态2.2.2 偏向锁状态2.2.3 轻量级锁状态2.2.4 重量级锁2.2.5 锁类型总结2.2.…

云手机结合自主ADB命令接口 提升海外营销效率

现在,跨境电商直播已经成为在线零售的重要渠道,在大环境下,确保直播应用的稳定性和用户体验至关重要。 云手机支持自主ADB命令接口,为电商直播营销提供了技术支持,使得应用开发、测试、优化和运维更加高效。 什么是A…

postman双击打不开的解决方案

postman双击打不开的解决方案 深入再深入 于 2022-05-09 15:45:56 发布 阅读量3.1k 收藏 2 点赞数 4 文章标签: postman 版权 右键属性 安装路径 更新版本 回滚 问题排查 关键词由CSDN通过智能技术生成 解决方案: 右键-属性,复制安装路…

puzzle(0611)《组合+图论》追捕问题

目录 一,追及问题 1,警察和小偷 2,旋转的4个硬币 3,抓狐狸 二,围堵问题 三,追及围堵 一,追及问题 1,警察和小偷 如下图,警察先走,警察和小偷轮流一人…

开源模型应用落地-FastAPI-助力模型交互-进阶篇(三)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理,使应用程序能够处理各种不同的请求场景,提高应用程序的灵活性和可扩展性。 在数据验证和转换方面,高级用法提供了更精细和准确的控制&#…

【Git远程操作】理解分布式管理 | 创建远程仓库

目录 1.理解分布式管理 多人协作开发 2.创建远程仓库 2.1仓库名&路径 2.2初始化仓库&设置模板 1.理解分布式管理 目前我们学习的所有内容都是在本地来完成的。(add /commit /版本撤销回退/分支管理) Git是一个分布式 的版本控制系统。 分支…

c# listview控件调整标题显示顺序

右键点击listview,选择编辑列 修改DisplayIndex listview在成员位置点击上下箭头移动后,实际显示不会改变,因为DisplayIndex没有改变

IDEA的断点调试(Debug)

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试(Debug) 第七章 …

go-zero框架入门

go-zero框架环境的安装 goctl 若想用go-zero框架,还需要一些前置条件: 安装goctl go install github.com/zeromicro/go-zero/tools/goctllatest可以使用 goctl 命令查看是否安装成功 成功后安装protoc goctl env check --install --verbose --force…

云监控(华为) | 实训学习day2(10)

spring boot基于框架的实现 简单应用 - 用户数据显示 开发步骤 第一步:文件-----》新建---项目 第二步:弹出的对话框中,左侧选择maven,右侧不选任何内容. 第三步,选择maven后,下一步 第4步 :出现对话框中填写项目名称 第5步&…

【学术会议征稿】第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)

第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024) 2024 6th International Conference on Frontier Technologies of Information and Computer 第六届信息与计算机前沿技术国际学术会议(ICFTIC 2024)将在中国青岛举行,会期是2024年11月8-10日,为…

FOG Project 文件名命令注入漏洞复现(CVE-2024-39914)

0x01 产品简介 FOG是一个开源的计算机镜像解决方案,旨在帮助管理员轻松地部署、维护和克隆大量计算机。FOG Project 提供了一套功能强大的工具,使用户能够快速部署操作系统、软件和配置设置到多台计算机上,从而节省时间和精力。该项目支持基于网络的 PXE 启动、镜像创建和还…

Python:拆包

拆包 适用于元组和列表 coordinates (1, 2, 3) 如果想要获取这三个值 本来应该这样做 xcoordinates[0] ycoordinates[1] zcoordinates[2] python 特性:简化获取步骤 x, y, z coordinates 输出中全是变量名,可以直接用 , 连接 print(x, y, z)

Python | Leetcode Python题解之第257题二叉树的所有路径

题目: 题解: class Solution:def binaryTreePaths(self, root: TreeNode) -> List[str]:paths list()if not root:return pathsnode_queue collections.deque([root])path_queue collections.deque([str(root.val)])while node_queue:node node_…

鸿蒙语言基础类库:【@system.request (上传下载)】

上传下载 说明: 从API Version 6开始,该接口不再维护,推荐使用新接口[ohos.request]。本模块首批接口从API version 4开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import request from system.re…

HarmonyOS ArkUi @CustomDialog 和promptAction.openCustomDialog踩坑以及如何选择

CustomDialog 内使用Link,如何正常使用 错误使用方式: 定义一个函数,在函数内使用弹窗,如下面代码showDialog: 这种使用方式,无法在自定义的CustomDialog内使用 Link,进行父子双向绑定&#x…

3、宠物商店智能合约实战(truffle智能合约项目实战)

3、宠物商店智能合约实战(truffle智能合约项目实战) 1-宠物商店环境搭建、运行2-webjs与宠物逻辑实现3-领养智能合约初始化4-宠物领养实现5-更新宠物领养状态 1-宠物商店环境搭建、运行 https://www.trufflesuite.com/boxes/pet-shop 这个还是不行 或者…

vue3前端开发-小兔鲜项目-图片懒加载的自定义标签

vue3前端开发-小兔鲜项目-图片懒加载的自定义标签!很多大型网站,因为首页面渲染的内容太多了,然而有些用户,可能在顶部就发现了自己感兴趣的内容,直接就点击跳转去了其他页面,因此,完全没有必要…