PyTorch实现卷积神经网络CNN

embedded/2024/10/10 18:36:14/

一、卷积神经网络CNN

二、代码实现(PyTorch)

1. 导入依赖库

import torch
from torch import nn, optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
  • nn:包含了torch已经准备好的层,激活函数、全连接层等

  • optim:提供了神经网络的一系列优化算法,如 SGD、Adam 等

  • datasets:提供常用的数据集,如 MNIST(本次使用)、CIFAR10/100、ImageNet、COCO 等

  • DataLoder:装载上面提到的数据集

2. 准备数据集

        这里使用MNIST数据集,它是一个大型手写数字数据库(包含0~9十个数字),原始的这两个数据集由128×128像素的黑白图像组成。LeCun等人将其进行归一化和尺寸调整后得到的是28×28的灰度图像。

        MNIST数据集总共包含两个子数据集:一个训练数据集(train_dataset)和一个测试数据集(test_dataset)。它们分别包含了60K和10K的28×28的灰度图像。代码如下:

# 训练集
train_dataset = datasets.MNIST(root='./',train=True,transform=transforms.ToTensor(),  # 数据转换为张量格式download=True)
# 测试集
test_dataset = datasets.MNIST(root='./',train=False,transform=transforms.ToTensor(),download=True)batch_size = 100  # 批次大小
# 装载训练集
train_loader = DataLoader(dataset=train_dataset,batch_size=batch_size,  # 每次加载多少条数据shuffle=True)  # 生成数据前打乱数据 
# 装载测试集
test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=True)

         这里值得注意的是,datasets.s=MNIST() 的参数 download 表示是否下载到参数 root 下的目录。但是实际使用过程中,从 https://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz 下载会出现 403 forbidden 的报错信息。这个不必担心,torch 还会选择其他可用下载链接继续下载。 下载好的数据集应该有如下几个:

或者

3. 构建网络模型

        首先应该清楚,MNIST给到的原始训练集的图像可以表示为(batch_size, 1, 28, 28),其中 batch_size 代表一共加载了多少条数据,这里我之前设置了100;1代表这个训练集的图片是灰度图;两个28则为灰度图的长和宽。

        接下来就可以设计卷积层和池化层。

        设计卷积层时,应该注意第一层的卷积核数量(特征图数量)一般从较小的数值开始,我这里设置了32。因为灰度图的特征还算明显,因此卷积核可以适当减小,缓慢增加感受野,以此提高效率,因此设置为5×5。步长一般设置为1。至于填充几圈0,则可通过图像大小、卷积核大小、步长等推算得知。

        设计池化层时,首先确定池化法,这里选择最大池化法。选择最常用的2×2大小的池化核,它能够将特征图的宽和高减小一半。

        以下是每一层的详细设计思路:

  1. 卷积层1(conv1):先创建一个二维卷积层(Conv2d),然后确定激活函数(ReLU)对卷积层输出的每个值进行非线性变换,最后利用最大池化法(MaxPool)减小特征图尺寸防止过拟合。
  2. 卷积层2(conv2):由卷积层1的输出通道数确定卷积层2的输入通道数,其他不变。
  3. 全连接层1(fc1):使用 Dropout 来控制全连接层的过拟合问题,每次有50%的神经元不使用(只有训练状态下 Dropout 才起作用,测试状态下还是全部神经元工作)。在前向传播时需要注意,应该把卷积层的特征图维数修改为2维。
  4. 全连接层2(fc2):最后将1000个特征图输出为10个数字(0~9)的概率值。这里Softmax不加也行,因为后续在使用交叉熵代价函数(CrossEntropyLoss)时,因为它内部已经包括 Softmax 操作。
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Sequential(nn.Conv2d(1, 32, 5, 1, 2),  # Conv2d(输入通道数(灰度图),输出通道数(生成多少特征图),卷积核大小(5×5),步长,0填充(填充2圈))nn.ReLU(),nn.MaxPool2d(2, 2)  # MaxPool2d(池化核大小2×2,步长为2))self.conv2 = nn.Sequential(nn.Conv2d(32, 64, 5, 1, 2),nn.ReLU(),nn.MaxPool2d(2, 2)  )self.fc1 = nn.Sequential(nn.Linear(64 * 7 * 7, 1000),  # 将特征压缩为1000维的特征向量nn.Dropout(p=0.5),nn.ReLU())self.fc2 = nn.Sequential(nn.Linear(1000, 10),nn.Softmax(dim=1))def forward(self, x):x = self.conv1(x)  # 特征图(batch_size, 1, 28, 28) -> (batch_size, 32, 14, 14)x = self.conv2(x)  # 特征图(batch_size, 32, 14, 14) -> (batch_size, 64, 7, 7)x = x.view(x.size()[0], -1)  # ([batch_size, 64, 7, 7]) -> (batch_size, 64*7*7)x = self.fc1(x)  # (batch_size, 64*7*7) -> (batch_size, 1000)x = self.fc2(x)  # (batch_size, 1000) -> (1000, 10)return x

4. 训练+测试

        使用交叉熵代价函数(CrossEntropyLoss)和自适应矩阵优化算法(Adam)训练数据。代码如下:

LR = 0.001  # 学习率
model = Net()  # 模型
crossEntropy_loss = nn.CrossEntropyLoss()  # 交叉熵代价函数
optimizer = optim.Adam(model.parameters(), LR)def train():model.train()for i, data in enumerate(train_loader):inputs, labels = data  # 获得一个批次的数据和标签out = model(inputs)  # 获得模型预测输出(64张图像,10个数字的概率)loss = crossEntropy_loss(out, labels)  # 使用交叉熵损失函数时,可以直接使用整型标签,无须独热编码optimizer.zero_grad()  # 梯度清0loss.backward()  # 计算梯度optimizer.step()  # 修改权值def test():model.eval()correct = 0for i, data in enumerate(test_loader):inputs, labels = data  # 获得一个批次的数据和标签out = model(inputs)  # 获得模型预测结构(64,10)_, predicted = torch.max(out, 1)  # 获得最大值,以及最大值所在位置correct += (predicted == labels).sum()  # 判断64个值有多少是正确的print("测试集正确率:{}\n".format(correct.item() / len(test_loader)))# 训练20个周期
for epoch in range(20):print("Epoch:{}".format(epoch))train()test()

         运行,等待片刻后,输出测试集的正确率为:

 

 


http://www.ppmy.cn/embedded/125487.html

相关文章

jmeter实现SSL双向验证

前提: 预先了解:SSL单向/双向认证详解握手请求以及tomcat配置https请求的请到以下网址了解Java nginx https 双向认证 der,cer文件一般是二进制格式的,只放证书,不含私钥 crt 文件可能是二进制的,也可能是文本格式的,应该以文本格式居多,功能同der/cer pem文件一般是…

压力测试指南-分布式系统下的压力测试策略

分布式系统下的压力测试策略 在当今的数字化时代,分布式系统因其高可用性、可扩展性和灵活性成为众多企业的首选架构。然而,这复杂的体系结构也为压力测试带来了新的挑战。本文将深入探讨分布式系统压力测试的关键方面,并展示如何利用自动化…

State of ChatGPT ---- ChatGPT的技术综述

声明:该文总结自AI菩萨Andrej Karpathy在youtube发布的演讲视频。 原视频连接:State of GPT | BRK216HFS 基础知识: Transformer原文带读与代码实现https://blog.csdn.net/m0_62716099/article/details/141289541?spm1001.2014.3001.5501 H…

本田汽车投资SiLC Technologies:携手共促自动驾驶技术新飞跃

SiLC Technologies获本田汽车投资:加速自动驾驶技术革新 近日,硅谷光子学初创公司SiLC Technologies宣布获得本田汽车的投资,这一合作标志着双方将共同推进自动驾驶技术领域的革新与发展。本田此次投资不仅体现了对SiLC Technologies技术实力的认可,也彰显了本田在自动驾驶…

【一起学NLP】Chapter3-使用神经网络解决问题

目录 使用神经网络解决问题Tip:数据集划分学习使用的代码Tip:epochTip:数据打乱Trainer类Tip-高速化计算 使用神经网络解决问题 import sys sys.path.append(..) # 为了引入父目录的文件而进行的设定 from dataset import spiral import matplotlib.pyplot as pltx,t spiral.…

Linux系统和数据库常用的命令2

Linux系统和数据库常用的命令2 1、两台Linux机器ssh免密登录 client端登录server端需要免密,只需把公钥发送到server就可,会在server端生成一个authorized_keys文件 # 108机器上[rootclient ~]# ssh-keygen -t rsa // 非对称算法 Generating public/…

服务器虚拟化的详细学习顺序

服务器虚拟化的详细学习顺序可以遵循以下步骤,这些步骤旨在帮助学习者系统地掌握虚拟化技术: 1. 理解基本概念与原理 定义与原理:首先,需要明确服务器虚拟化的定义和基本原理,即如何将物理服务器资源转化为虚拟服务器…

深度学习中的结构化概率模型 - 使用图来描述模型结构篇

序言 在深度学习的探索之路上,结构化概率模型以其独特的视角和强大的表达能力,成为了研究复杂数据关系的重要工具。这一模型的核心在于其巧妙地利用图来描述模型结构,将随机变量间的复杂交互关系可视化、结构化。图的引入,不仅为…