【深度学习】(5)--搭建卷积神经网络

devtools/2024/9/24 13:31:44/

文章目录

  • 搭建卷积神经网络
    • 一、数据预处理
      • 1. 下载数据集
      • 2. 创建DataLoader(数据加载器)
    • 二、搭建神经网络
    • 三、训练数据
    • 四、优化模型
  • 总结

搭建卷积神经网络

一、数据预处理

1. 下载数据集

在PyTorch中,有许多封装了很多与图像相关的模型、数据集,那么如何获取数据集呢?

导入datasets模块:

python">from torchvision import datasets #封装了很多与图像相关的模型,数据集

以datasets模块中的MNIST数据集为例,包含70000张手写数字图像:60000张用于训练,10000张用于测试。图像是灰度的,28*28像素,并且居中的,以减少预处理和加快运行。

在这里插入图片描述

python">from torch.utils.data import DataLoader #数据包管理工具,打包数据
from torchvision import datasets #封装了很多与图像相关的模型,数据集
from torchvision.transforms import ToTensor # 数据转换,张量,将其他类型数据转换为tensor张量
"""-----下载训练集数据集-----"""
training_data = datasets.MNIST(root="data",train=True,# 取训练集download=True,transform=ToTensor(),# 张量,图片是不能直接传入神经网络模型的
) # 对于pytorch库能够识别的数据,一般是tensor张量"""-----下载测试集数据集-----"""
test_data = datasets.MNIST(root="data",train=False,download=True,transform=ToTensor(),
)# numpy数组只能在CPU上运行,Tensor可以在GPU上运行,这在深度学习中可以显著提高计算速度

在这里插入图片描述

下载完成之后可在project栏查看。

2. 创建DataLoader(数据加载器)

在PyTorch中,创建DataLoader的主要作用是将数据集(Dataset)加载到模型中,以便进行训练或推理。DataLoader通过封装数据集,提供了一个高效、灵活的方式来处理数据。

DataLoader通过batch_size参数将数据集自动划分为多个小批次(batch),每一批次的放入模型训练,减少内存的使用,提高训练速度。

python">import torch
from torch.utils.data import DataLoader
"""
创建数据DataLoader(数据加载器)
batch_size:将数据集分成多份,每一份为batch_size(指定数值)个数据。
优点:减少内存的使用,提高训练速度
"""
train_dataloder = DataLoader(training_data,batch_size=64)# 64张图片为一个包
test_datalodar = DataLoader(test_data,batch_size=64)
# 查看打包好的数据
for x,y in test_datalodar: #x是表示打包好的每一个数据包print(f"Shape of x [N, C, H, W]:{x.shape}")print(f"Shape of y:{y.shape} {y.dtype}")break
-----------------------
Shape of x [N, C, H, W]:torch.Size([64, 1, 28, 28])
Shape of y:torch.Size([64]) torch.int64

二、搭建神经网络

在这里插入图片描述

注意:同普通的神经网络不同,卷积神经网络在传入图片时不需要将其展开,因为对图片进行卷积就是在原图上进行内积,不能展开。

卷积神经网络是由输入层、卷积层、激活层、池化层、全连接层、输出层组成。所以在结构上我们也同这样式的来,但是可以搭建多层卷积哦!

python">"""---判断当前设备是否支持GPU,其中mps是苹果m系列芯片的GPU"""
device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu""""-----定义神经网络-----"""
class CNN(nn.Module):def __init__(self): # 输入大小(1,28,28)super(CNN,self).__init__()self.conv1 = nn.Sequential( # 将多个层组合在一起nn.Conv2d(         # 2d一般用于图像,3d用于视频数据(多一个时间维度),1d一般用于结构化的序列数据in_channels=1, # 图像通道个数,1表示灰度图(确定卷积核 组中的个数)out_channels=16, # 要得到多少特征图,卷积核的个数kernel_size=5,  # 卷积核大小stride=1,   # 步长padding=2   # 边界填充大小), # 输出的特征图为(16,28,28)-->16个大小28*28的图像nn.ReLU(), # relu层,不会改变特征图的大小nn.MaxPool2d(kernel_size=2) # 进行池化操作(2*2区域),输出结果为(16,14,14))self.conv2 = nn.Sequential( # 输入(16,14,14)nn.Conv2d(16,32,5,1,2), # 输出(32*14*14)nn.ReLU(),nn.Conv2d(32,32,5,1,2), # 输出(32*14*14)nn.ReLU(),nn.MaxPool2d(2) # 输出(32,7,7))self.conv3 = nn.Sequential( # 输入(32,7,7)nn.Conv2d(32,64,5,1,2), # 输出(64,7,7)nn.ReLU())self.out = nn.Linear(64*7*7,10)def forward(self,x):x = self.conv1(x)x = self.conv2(x)x = self.conv3(x) # 输出(64,7,7)x = x.view(x.size(0),-1) # flatten 操作,结果为:(batch_size,64*7*7)output = self.out(x)return outputmodel = CNN().to(device)

三、训练数据

  • optimizer优化器
python">optimizer = torch.optim.Adam(model.parameters(),lr=0.001)
  • loss_fn损失函数

在PyTorch中,**nn.CrossEntropyLoss()**是一个常用的损失函数,它结合了 nn.LogSoftmax()nn.NLLLoss()(负对数似然损失)在一个单独的类中。

python">loss_fn = nn.CrossEntropyLoss()
  • 训练集
python">from torch import nn #导入神经网络模块
def train(dataloader,model,loss_fn,optimizer):model.train()# 设置模型为训练模式batch_size_num =1# 迭代次数 for x,y in dataloader:x,y = x.to(device),y.to(device)  # 将数据和标签发送到指定设备  pred = model.forward(x)  # 前向传播  loss = loss_fn(pred,y)  # 计算损失  optimizer.zero_grad()  # 清除之前的梯度  loss.backward()  # 反向传播  optimizer.step()  # 更新模型参数  loss_value = loss.item()  # 获取损失值if batch_size_num %200 == 0:  # 每200次迭代打印一次损失  print(f"loss:{loss_value:>7f} [number:{batch_size_num}]")batch_size_num += 1
train(train_dataloder,model,loss_fn,optimizer)
------------------------
loss:0.158841 [number:200]
loss:0.242431 [number:400]
loss:0.173504 [number:600]
loss:0.020542 [number:800]
  • 测试集
python">"""-----测试集-----"""
def test(dataloader,model,loss_fn):size = len(dataloader.dataset)num_batches = len(dataloader)model.eval()test_loss,correct = 0,0with torch.no_grad():for x,y in dataloader:x,y = x.to(device),y.to(device)pred = model.forward(x)test_loss += loss_fn(pred,y).item()correct += (pred.argmax(1) == y).type(torch.float).sum().item()a = (pred.argmax(1) == y)b = (pred.argmax(1) == y).type(torch.float)test_loss /= num_batchescorrect /= sizecorrect = round(correct, 4)print(f"Test result: \n Accuracy:{(100*correct)}%,Avg loss:{test_loss}")test(test_datalodar,model,loss_fn)
--------------------
Test result: Accuracy:98.11999999999999%,Avg loss:0.05511626677004996

四、优化模型

通过多次迭代,神经网络不断调整其内部参数(如权重和偏置),以最小化预测值与实际值之间的误差。这种优化过程使得神经网络能够更准确地处理输入数据,提高分类、回归等任务的性能。

python">epochs = 5
for t in range(epochs):print(f"Epoch {t+1} \n-------------------------")train(train_dataloder,model,loss_fn,optimizer)
print("Done!")
test(test_datalodar,model,loss_fn)

输出结果:

python">Epoch 1 
-------------------------
loss:0.182339 [number:200]
loss:0.229839 [number:400]
loss:0.210450 [number:600]
loss:0.028532 [number:800]
Epoch 2 
-------------------------
loss:0.066216 [number:200]
loss:0.149762 [number:400]
loss:0.084482 [number:600]
loss:0.003749 [number:800]
…………
Done!
Test result: Accuracy:98.99%,Avg loss:0.03138259953491878

总结

本篇介绍了如何搭建卷积神经网络,其主要的构造部分为卷积层、激活层以及池化层,可以搭建多层该部分对数据进行多次卷积、池化。
注意:同普通的神经网络不同,卷积神经网络在传入图片时不需要将其展开,因为对图片进行卷积就是在原图上进行内积,不能展开。


http://www.ppmy.cn/devtools/116523.html

相关文章

前端项目发版后页面加载最新代码

版本发布上线后,如果用户还停留在老页面,此时用户并不知道网页已经重新部署了,跳转页面的时候可能会出 js 链接 的hash变了导致报错跳不过去的情况。需要手动刷新拿到最新的代码后才能恢复,那有哪些办法可以实现优化这个问题。 方…

牛客小白月赛101

题目链接 A k 次操作,每次删除数组的第一个元素或者最后一个元素,求最后数组和的最大值 错误做法:每次操作比较第一个元素和最后一个元素,删除较小的一个。 这样不能只能保证一次操作是最优的;对于多次删除操作&…

uni-icons自定义图标详细步骤及踩坑经历

一、详细步骤 获取图标 1.访问iconfont-阿里巴巴矢量图标库,搜索图标并加入购物车: 2.点击页面右上角购物车图标 ,点击添加至项目,如没有项目,需要点击下图第二步的图标新建一个项目目录,如已经有项目则…

Kotlin 操作符 in 的基本使用(十)

导读大纲 1.0.1 迭代集合1.0.2 使用 in 检查集合和范围 1.0.1 迭代集合 使用 for (x in y) 循环最常见的情况是对一个集合进行迭代 您很可能已经熟悉它的行为–对输入集合中的每个元素都执行循环 在这种情况下,您只需打印颜色集合中的每个元素 在循环内部,单个颜色可以用 colo…

第十章 【后端】商品分类管理微服务(10.7)——公共模块

10.7 公共模块 用于存放公共服务类。 10.7.1. 创建模块 10.7.2 创建实体类的超类 在父工程的 pom.xml 中添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns

用Flutter几年了,Flutter每个版本有什么区别?

用Flutter几年了&#xff0c;你知道Flutter每个版本有什么区别吗&#xff1f;不管是学习还是面试我们可能都需要了解这个信息。 Flutter 每个版本的用法基本都是一样的&#xff0c;每隔几天或者几周就会更新一个版本&#xff0c; 2018 年 12 月 5 日发布了1.x 版本&#…

python自学笔记

python部分总结 主要记录的是python与之前学的语言的不同之处 函数总结 首字母大写: name.title() 删除右边空格&#xff08;暂时&#xff09;:name.rstrip() 删除左边空格&#xff08;暂时&#xff09;:name.lstrip() 删除前缀&#xff08;暂时&#xff09;:name.removeprefi…

PMP考完之后考什么,NPDP值得考吗?

PMP考完之后先去申请一个CSPM-2级证书吧&#xff0c;现在这个证书还在推广期&#xff0c;不用参加考试就能申请增持 CSPM 证书&#xff0c;流程也很简单&#xff0c;600米申请表照片就可以了&#xff0c;有PMP的建议不要错过这个免考期~ 一、cspm是什么呢&#xff1f; CSPM是由…