Pytorchz学习---基于卷积神经网络的MINIST数据集训练

news/2024/9/25 18:19:45/
# 一般情况下,如果模型有可学习的参数,最好用nn.Module,其他情况用nn.function相对简单一些
import torch.nn.functional as F
import torch
loss_func = F.cross_entropy
def model(xb):return xb.mm(weights)+bias
# bs = 64
# xb = x_trains[0:bs]
# yb = y_trains[0:bs]
# weights = torch.randn([784,10],dtype=torch.float,requires_grad=True)
# bias = torch.zeros(10,requires_grad=True)
# print(loss_func(model(xb),yb))
# 创建一个model来更简化代码
from torch import nn
class Mnist_NN(nn.Module):def __init__(self):super().__init__()self.hidden1 = nn.Linear(784,128)self.hidden2 = nn.Linear(128,256)self.out = nn.Linear(256,10)def forward(self,x):x = F.relu(self.hidden1(x))x = F.relu(self.hidden2(x))x = self.out(x)return x
net = Mnist_NN()
print(net)
for name, parameter in net.named_parameters():print(name,parameter,parameter.size())
# # 使用TensorDataset和DataLoader批量取数据
# from torch.utils.data import TensorDataset
# from torch.utils.data import  DataLoader
# train_ds = TensorDataset(x_train,y_train)
# train_dl = DataLoader(train_ds,batch_size=bs,shuffle=True)
# valid_ds = TensorDataset(x_valid, y_valid)
# valid_dl = DataLoader(valid_ds,batch_size=bs*2)
# def get_data(train_ds, valid_ds, bs):
#     return (
#         DataLoader(train_ds,batch_size=bs,shuffle=True),
#         DataLoader(valid_ds,batch_size=bs*2)
#     )

卷积神经网络参数 :

滑动窗口步长

卷积核尺寸

边缘填充

因为边缘点利用少,加入填充,可以使原本图像边缘点被利用增加

池化层

最大池化,神经网络传递过程中最大值一般比较重要,参数在更新过程中算出的最大值说明权重大

池化层不涉及任何计算,只是筛选

全连接层

最后还要在池化层的基础上将特征图拉成一个向量

残差神经网络主要来解决随着网络层数的增加效果下降的问题

手写数字识别

导包

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets,transforms
from torch.utils.data import DataLoader

构造模型

class numberCNN(nn.Module):def __init__(self):super(numberCNN,self).__init__()# 第一个卷积模块 标准形参self.conv1 = nn.Sequential(# 卷积层nn.Conv2d(in_channels=1,  # 输入通道数out_channels=16, # 输出通道数,卷积数量kernel_size=5,  # 卷积尺寸stride=1,  # 步长padding=2  # 填充),# 加入非线性变换激活nn.ReLU(),# 最大池化nn.MaxPool2d(kernel_size=2))# 第二个卷积模块,简化参数# 输入14*14*16self.conv2 = nn.Sequential(nn.Conv2d(16,32,5,1,2),  # 输出14*14*32nn.ReLU(),nn.MaxPool2d(2)  # 输出7*7*32)# 全连接层self.out = nn.Linear(7*7*32,10)def forward(self,x:torch.Tensor):x = self.conv1(x)x = self.conv2(x)x = x.view(x.size(0),-1) # 在输入全连接层以前要将特征图的特征展开成一维output = self.out(x)return output

计算模型预测的准确率

def accuracy(predictions,labels):# torch.max()函数用于找到张量最大值及其索引,这里索引代表了数字本身,直接返回索引即可,括号内的1表示取的是每行的最大值,每列的最大值取0pred = torch.max(predictions.data,1)[1]# 查看标签与预测值的对比个数,返回的是正确个数rights = pred.eq(labels.data.view_as(pred)).sum()# 返回预测正确个数和总个数return rights, len(labels)

开始训练

def start():input_size = 28  # 图像尺寸28*28num_classes = 10  # 标签类别num_epochs = 3  # 训练的总循环周期batch_size = 64  # 一个batch的大小,一个批量训练64张图片# 训练集train_dataset = datasets.MNIST(root='./data',train=True,transform=transforms.ToTensor(),download=True)# 测试集test_dataset = datasets.MNIST(root='./data',train=False,transform=transforms.ToTensor(),download=True)# 构建一个批量数据"""在 PyTorch 中,DataLoader 是一个迭代器,它能够从数据集中加载数据,并且对数据进行批处理(batching)、乱序(shuffling)等操作。当你使用 enumerate(train_loader) 遍历时,data 实际上是数据加载器返回的一个批次的数据。data 的形式在每次迭代中,data 是一个元组(tuple),包含两个元素:inputs:一个包含输入数据(通常是图像)的张量。labels:一个包含相应标签(通常是类别标签)的张量。"""train_loader = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=True)myModel = numberCNN()# 损失函数criterion = nn.CrossEntropyLoss()# 优化器optimizer = optim.Adam(myModel.parameters(),lr=0.001)# 开始训练for epoch in range(num_epochs):train_right = []for idx, data in enumerate(train_loader):# `inputs` 的形状:[64, 1, 28, 28]# `labels` 的形状:[64]inputs, labels = datamyModel.train()  # 开启训练模式outputs = myModel(inputs)loss = criterion(outputs,labels)"""用于清空(或重置)优化器中积累的梯度。这是在每次反向传播之前需要执行的一个步骤,目的是为了防止梯度累积,从而确保每次计算梯度时都是基于当前批次的数据。在每次迭代中,当我们计算完损失函数并通过反向传播计算梯度之后,梯度会被累积在模型参数的 .grad 属性中。如果不清空这些梯度,那么在下一次迭代中,旧的梯度会与新的梯度相加,这可能会导致错误的结果。"""optimizer.zero_grad()  # 每个批次开始反向传播以前都要归零loss.backward()# 根据计算出的梯度更新模型的参数"""在反向传播(backpropagation)过程中,PyTorch 计算了损失函数相对于模型参数的梯度。optimizer.step() 使用这些梯度来更新模型参数,使损失函数的值朝着最小化的方向变化。"""optimizer.step()# 计算精准率right = accuracy(outputs,labels)# 将每个批次的正确预测个数加入train_right.append(right)# 验证 每隔一定数量的批次(这里设定为每 100 个批次),程序会将模型切换到评估模式,并在验证集上评估模型的性能。"""训练过程中定期评估模型的性能,并打印出训练和验证的准确率。以便于监控训练进度,防止过拟合,调整训练参数"""if idx%100==0:myModel.eval()  # 切换评估模式val_right = []  # 用于保存模型在验证集上每个批次的准确率信息。用于存储每个验证批次的准确率结果。for valData in test_loader:valInputs, valLabels = valDataoutput = myModel(valInputs)right = accuracy(output,valLabels)val_right.append(right)# 计算准确率train_r = (sum([tup[0] for tup in train_right]), sum([tup[1] for tup in train_right]))val_r = (sum([tup[0] for tup in val_right]), sum([tup[1] for tup in val_right]))print("当前epochL", epoch, "当前训练量:", (idx+1)*batch_size)print("训练正确个数:", train_r[0].numpy(), "训练总个数:", train_r[1],"训练准确率:", train_r[0].numpy() / train_r[1])print("测试正确个数:", val_r[0].numpy(), "测试总个数:", val_r[1],"测试准确率:", val_r[0].numpy() / val_r[1])
start()
当前epochL 0 当前训练量: 64
训练正确个数: 7 训练总个数: 64 训练准确率: 0.109375
测试正确个数: 1191 测试总个数: 10000 测试准确率: 0.1191
当前epochL 0 当前训练量: 6464
训练正确个数: 5010 训练总个数: 6464 训练准确率: 0.7750618811881188
测试正确个数: 9260 测试总个数: 10000 测试准确率: 0.926
当前epochL 0 当前训练量: 12864
训练正确个数: 10963 训练总个数: 12864 训练准确率: 0.8522232587064676
测试正确个数: 9556 测试总个数: 10000 测试准确率: 0.9556
当前epochL 0 当前训练量: 19264
训练正确个数: 17087 训练总个数: 19264 训练准确率: 0.8869912790697675
测试正确个数: 9634 测试总个数: 10000 测试准确率: 0.9634
当前epochL 0 当前训练量: 25664
训练正确个数: 23263 训练总个数: 25664 训练准确率: 0.906444825436409
测试正确个数: 9707 测试总个数: 10000 测试准确率: 0.9707
当前epochL 0 当前训练量: 32064
训练正确个数: 29456 训练总个数: 32064 训练准确率: 0.9186626746506986
测试正确个数: 9732 测试总个数: 10000 测试准确率: 0.9732
当前epochL 0 当前训练量: 38464
训练正确个数: 35638 训练总个数: 38464 训练准确率: 0.9265287021630616
测试正确个数: 9745 测试总个数: 10000 测试准确率: 0.9745
当前epochL 0 当前训练量: 44864
训练正确个数: 41866 训练总个数: 44864 训练准确率: 0.933175820256776
测试正确个数: 9762 测试总个数: 10000 测试准确率: 0.9762
当前epochL 0 当前训练量: 51264
训练正确个数: 48115 训练总个数: 51264 训练准确率: 0.9385728776529338
测试正确个数: 9801 测试总个数: 10000 测试准确率: 0.9801
当前epochL 0 当前训练量: 57664
训练正确个数: 54338 训练总个数: 57664 训练准确率: 0.9423210321864595
测试正确个数: 9782 测试总个数: 10000 测试准确率: 0.9782
当前epochL 1 当前训练量: 64
训练正确个数: 61 训练总个数: 64 训练准确率: 0.953125
测试正确个数: 9823 测试总个数: 10000 测试准确率: 0.9823
当前epochL 1 当前训练量: 6464
训练正确个数: 6335 训练总个数: 6464 训练准确率: 0.9800433168316832
测试正确个数: 9812 测试总个数: 10000 测试准确率: 0.9812
当前epochL 1 当前训练量: 12864
训练正确个数: 12602 训练总个数: 12864 训练准确率: 0.9796330845771144
测试正确个数: 9807 测试总个数: 10000 测试准确率: 0.9807
当前epochL 1 当前训练量: 19264
训练正确个数: 18857 训练总个数: 19264 训练准确率: 0.9788725083056479
测试正确个数: 9848 测试总个数: 10000 测试准确率: 0.9848
当前epochL 1 当前训练量: 25664
训练正确个数: 25131 训练总个数: 25664 训练准确率: 0.979231608478803
测试正确个数: 9835 测试总个数: 10000 测试准确率: 0.9835
当前epochL 1 当前训练量: 32064
训练正确个数: 31421 训练总个数: 32064 训练准确率: 0.9799463572854291
测试正确个数: 9843 测试总个数: 10000 测试准确率: 0.9843
当前epochL 1 当前训练量: 38464
训练正确个数: 37705 训练总个数: 38464 训练准确率: 0.9802672628951747
测试正确个数: 9839 测试总个数: 10000 测试准确率: 0.9839
当前epochL 1 当前训练量: 44864
训练正确个数: 43993 训练总个数: 44864 训练准确率: 0.9805857703281027
测试正确个数: 9854 测试总个数: 10000 测试准确率: 0.9854
当前epochL 1 当前训练量: 51264
训练正确个数: 50303 训练总个数: 51264 训练准确率: 0.9812539013732834
测试正确个数: 9840 测试总个数: 10000 测试准确率: 0.984
当前epochL 1 当前训练量: 57664
训练正确个数: 56593 训练总个数: 57664 训练准确率: 0.9814268867924528
测试正确个数: 9883 测试总个数: 10000 测试准确率: 0.9883
当前epochL 2 当前训练量: 64
训练正确个数: 64 训练总个数: 64 训练准确率: 1.0
测试正确个数: 9859 测试总个数: 10000 测试准确率: 0.9859
当前epochL 2 当前训练量: 6464
训练正确个数: 6397 训练总个数: 6464 训练准确率: 0.989634900990099
测试正确个数: 9879 测试总个数: 10000 测试准确率: 0.9879
当前epochL 2 当前训练量: 12864
训练正确个数: 12708 训练总个数: 12864 训练准确率: 0.9878731343283582
测试正确个数: 9860 测试总个数: 10000 测试准确率: 0.986
当前epochL 2 当前训练量: 19264
训练正确个数: 19024 训练总个数: 19264 训练准确率: 0.9875415282392026
测试正确个数: 9885 测试总个数: 10000 测试准确率: 0.9885
当前epochL 2 当前训练量: 25664
训练正确个数: 25328 训练总个数: 25664 训练准确率: 0.9869077306733167
测试正确个数: 9883 测试总个数: 10000 测试准确率: 0.9883
当前epochL 2 当前训练量: 32064
训练正确个数: 31656 训练总个数: 32064 训练准确率: 0.9872754491017964
测试正确个数: 9791 测试总个数: 10000 测试准确率: 0.9791
当前epochL 2 当前训练量: 38464
训练正确个数: 37968 训练总个数: 38464 训练准确率: 0.9871048252911814
测试正确个数: 9886 测试总个数: 10000 测试准确率: 0.9886
当前epochL 2 当前训练量: 44864
训练正确个数: 44272 训练总个数: 44864 训练准确率: 0.9868045649072753
测试正确个数: 9882 测试总个数: 10000 测试准确率: 0.9882
当前epochL 2 当前训练量: 51264
训练正确个数: 50580 训练总个数: 51264 训练准确率: 0.9866573033707865
测试正确个数: 9876 测试总个数: 10000 测试准确率: 0.9876
当前epochL 2 当前训练量: 57664
训练正确个数: 56889 训练总个数: 57664 训练准确率: 0.9865600721420644
测试正确个数: 9877 测试总个数: 10000 测试准确率: 0.9877
import torch #如果pytorch安装成功即可导入
print(torch.cuda.device_count())  #查看可用的CUDA数量
torch.cuda.is_available()

http://www.ppmy.cn/news/1530401.html

相关文章

微服务注册中⼼1

1. 微服务的注册中⼼ 注册中⼼可以说是微服务架构中的”通讯录“ ,它记录了服务和服务地址的映射关系。在分布式架构中, 服务会注册到这⾥,当服务需要调⽤其它服务时,就这⾥找到服务的地址,进⾏调⽤。 1.1 注册中⼼的…

大健康裂变分销小程序开发

大健康裂变分销小程序的开发是一个涉及技术、市场策略、用户体验和合规性等多个方面的综合项目。这类小程序旨在通过分销机制促进大健康产品的销售和品牌推广,同时利用社交网络的裂变效应扩大市场影响力。以下是大健康裂变分销小程序开发的主要步骤和考虑因素&#…

设计模式-PIMPL 模式

PIMPL(Pointer to IMPLementation),又称Opaque Pointer模式或编译防火墙,是一种在C中广泛应用的编程技术。其核心思想是将类的实现细节从公共接口中分离出来,通过指向实现类的指针来访问类的具体功能。这种模式在提高代…

C#|.net core 基础 - 深拷贝的五大类N种实现方式

在实际应用中经常会有这样的需求:获取一个与原对象数据相同但是独立于原对象的精准副本,简单来说就是克隆一份,拷贝一份,复制一份和原对象一样的对象,但是两者各种修改不能互相影响。这一行为也叫深克隆,深…

把命令的语气改成聊天的方式

​在与人沟通时,没人会喜欢别人用下命令的口气对自己说话。 即使是非常明显的错误,一旦用粗鲁的口气命令指责别人,也会引起对方的反感,改正起来也会非常困难。 即使作为领导,也不要用命令的语气面对下级要做到合情合…

Python提供内置正则表达式库

正则表达式是一种强大的文本处理工具,可以匹配文本片段的模式 最简单的正则表达式就是普通的字符串,可以匹配自身 要注意的是,正则表达式并不是一个程序,它使用一种特定的语法模式来描述在搜索文本时要匹配的一个或多个字符串。正…

2024最新!!!iOS高级面试题,全!(一)

TCP,HTTP,HTTPS,,WebSokect 区别: IP协议(网络层协议) TCP:传输控制协议,主要解决数据如何在网络中传输,面向连接,可靠。(传输层协议) UDP:用户数…

需求导向的正则表达式

目录 re.sub 需求:把 1. 2.这些序号转成(1) (2) 需求:反过来,把(1)->1. ,(2)》2. 。 需求:把出现的 1 2 3都转成下标 进阶1!只想让化学符…