深度学习每周学习总结P1(pytorch手写数字识别)

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊 | 接辅导、项目定制

目录

    • 0. 总结
    • 1. 数据导入部分
    • 2. 模型构建部分
    • 3. 训练前的准备
    • 4. 定义训练函数
    • 5. 定义测试函数
    • 6. 训练过程

0. 总结

总结:

  • 数据导入部分:数据导入使用了torchvision自带的数据集,获取到数据后需要使用torch.utils.data中的DataLoader()加载数据

  • 模型构建部分:有两个部分一个初始化部分(init())列出了网络结构的所有层,比如卷积层池化层等。第二个部分是前向传播部分,定义了数据在各层的处理过程。

  • 训练前的准备:在这之前需要定义损失函数,学习率,以及根据学习率定义优化器(例如SGD随机梯度下降),用来在训练中更新参数,最小化损失函数。

  • 定义训练函数:函数的传入的参数有四个,分别是设置好的DataLoader(),定义好的模型,损失函数,优化器。函数内部初始化损失准确率为0,接着开始循环,使用DataLoader()获取一个批次的数据,对这个批次的数据带入模型得到预测值,然后使用损失函数计算得到损失值。接下来就是进行反向传播以及使用优化器优化参数,梯度清零放在反向传播之前或者是使用优化器优化之后都是可以的。将 optimizer.zero_grad() 放在了每个批次处理的开始,这是最标准和常见的做法。这样可以确保每次迭代处理一个新批次时,梯度是从零开始累加的。准确率是通过累计预测正确的数量得到的,处理每个批次的数据后都要不断累加正确的个数,最终的准确率是由预测正确的数量除以所有样本得数量得到的。损失值也是类似每次循环都累计损失值,最终的损失值是总的损失值除以训练批次得到的

  • 定义测试函数:函数传入的参数相比训练函数少了优化器,只需传入设置好的DataLoader(),定义好的模型,损失函数。此外除了处理批次数据时无需再设置梯度清零、返向传播以及优化器优化参数,其余部分均和训练函数保持一致。

  • 训练过程:定义训练次数,有几次就使用整个数据集进行几次训练,初始化四个空list分别存储每次训练及测试的准确率及损失。使用model.train()开启训练模式,调用训练函数得到准确率及损失。使用model.eval()将模型设置为评估模式,调用测试函数得到准确率及损失。接着就是将得到的训练及测试的准确率及损失存储到相应list中并合并打印出来,得到每一次整体训练后的准确率及损失。

  • 模型的保存,调取及使用,暂时没有看到这部分,但是训练好的模型肯定是会用到这步的,需要自己添加进去。在PyTorch中,通常使用 torch.save(model.state_dict(), ‘model.pth’) 保存模型的参数,使用 model.load_state_dict(torch.load(‘model.pth’)) 加载参数。

1. 数据导入部分

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import torchvisiondevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")device
device(type='cpu')
print(torch.__version__) # 查看pytorch版本
1.9.0+cpu

# 导入数据
train_ds = torchvision.datasets.MNIST('data', train = True,transform = torchvision.transforms.ToTensor(),download = True
)
test_ds = torchvision.datasets.MNIST('data',train = False,transform = torchvision.transforms.ToTensor(),download = True
)
batch_size = 32# shuffle = True 意味着每次迭代数据集时,数据都会被随机打乱。
# 因此,当您从train_dl中获取一个批次的数据时,每次都可能得到不同的图像
train_dl = torch.utils.data.DataLoader(train_ds,batch_size=batch_size,shuffle = True
)
test_dl = torch.utils.data.DataLoader(test_ds,batch_size = batch_size
)
# 取一个批次查看数据格式
# 数据的shape为:[batch_size,channel,height,weight]
# 其中batch_size为自己设定,channel,height,weight分别对应图片的通道数,高度和宽度
imgs,labels = next(iter(train_dl)) # 由于数据加载器被设置为随机打乱数据(shuffle=True),因此每次调用next函数时,都会从数据集中随机选择一个批次的数据。
imgs.shape
torch.Size([32, 1, 28, 28])
import numpy as np#指定图片大小,图像大小为20宽,5高的绘图(单位为英寸inch)
plt.figure(figsize=(20,5))
for i,img in enumerate(imgs[:20]):# 维度缩减npimg = np.squeeze(img.numpy())plt.subplot(2,10,i+1) # 将整个figure分成2行10列,绘制第i+1个子图plt.imshow(npimg,cmap=plt.cm.binary)plt.axis('off') # 这行代码关闭了当前子图的坐标轴,使得图像没有任何坐标轴标签或刻度。

在这里插入图片描述

2. 模型构建部分

# 模型构建
import torch.nn.functional as Fnum_classes = 10 # 图片的类别数class Model(nn.Module):def __init__(self):super().__init__() # super(Model,self).__init__() 的简化写法# 特征提取网络self.conv1 = nn.Conv2d(1,32,kernel_size = 3) # 第一层卷积,卷积核大小为3*3self.pool1 = nn.MaxPool2d(2) # 设置池化层,池化核大小为2*2self.conv2 = nn.Conv2d(32,64,kernel_size = 3) # 第二层卷积,卷积核大小为3*3self.pool2 = nn.MaxPool2d(2)# 分类网络self.fc1 = nn.Linear(1600,64)self.fc2 = nn.Linear(64,num_classes)# 前向传播def forward(self,x):x = self.pool1(F.relu(self.conv1(x)))x = self.pool2(F.relu(self.conv2(x)))x = torch.flatten(x,start_dim=1) # x.view(x.size(0), -1) 展平张量x = F.relu(self.fc1(x))x = self.fc2(x)return x
# !pip install torchinfo -i https://pypi.mirrors.ustc.edu.cn/simple/
# 查看模型结构
model = Model()
model
Model((conv1): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1))(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))(pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(fc1): Linear(in_features=1600, out_features=64, bias=True)(fc2): Linear(in_features=64, out_features=10, bias=True)
)
# 打印模型
from torchinfo import summarymodel = Model().to(device) # 在指定的设备(device,可能是CPU或CUDA/GPU)上实例化原始Model。summary(model) # 使用torchinfo库中的summary函数来打印模型的摘要。
=================================================================
Layer (type:depth-idx)                   Param #
=================================================================
Model                                    --
├─Conv2d: 1-1                            320
├─MaxPool2d: 1-2                         --
├─Conv2d: 1-3                            18,496
├─MaxPool2d: 1-4                         --
├─Linear: 1-5                            102,464
├─Linear: 1-6                            650
=================================================================
Total params: 121,930
Trainable params: 121,930
Non-trainable params: 0
=================================================================

3. 训练前的准备

# 训练模型# 设置超参数
loss_fn = nn.CrossEntropyLoss() # 创建损失函数
learn_rate = 1e-2 # 学习率
opt = torch.optim.SGD(model.parameters(),lr=learn_rate)

4. 定义训练函数

# 训练循环
def train(dataloader,model,loss_fn,optimizer):size = len(dataloader.dataset) # 训练集的大小,一共60000张图片num_batches = len(dataloader) # 批次数目,1875(60000/32)train_loss,train_acc = 0,0 # 初始化训练损失和正确率for X,y in dataloader: # 获取图片及其标签X,y = X.to(device),y.to(device)# 计算预测误差pred = model(X) # 网络输出loss = loss_fn(pred,y) # 计算网络输出值和真实值之间的差距,targets为真实值,计算二者差值即为损失# 反向传播optimizer.zero_grad() # grad属性归零loss.backward() # 反向传播optimizer.step() # 每一步自动更新# 记录acc与losstrain_acc += (pred.argmax(1) == y).type(torch.float).sum().item()train_loss += loss.item()train_acc /= sizetrain_loss /= num_batchesreturn train_acc,train_loss

5. 定义测试函数

# 编写测试函数
def test(dataloader,model,loss_fn):size = len(dataloader.dataset) # 测试集的大小,一共10000张图片num_batches = len(dataloader) # 批次数目,313(10000/32=312.5)test_loss,test_acc = 0,0# 当不进行训练时,停止梯度更新,节省计算内存消耗with torch.no_grad():for imgs,target in dataloader:imgs,target = imgs.to(device),target.to(device)# 计算losstarget_pred = model(imgs)loss = loss_fn(target_pred,target)test_loss += loss.item()test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()test_acc /= sizetest_loss /= num_batchesreturn test_acc,test_loss

6. 训练过程

# 训练
epochs = 5
train_loss = []
train_acc = []
test_loss = []
test_acc = []for epoch in range(epochs):model.train()epoch_train_acc,epoch_train_loss = train(train_dl,model,loss_fn,opt)model.eval()epoch_test_acc,epoch_test_loss = test(test_dl,model,loss_fn)train_acc.append(epoch_train_acc)train_loss.append(epoch_train_loss)test_acc.append(epoch_test_acc)test_loss.append(epoch_test_loss)template = ('Epoch:{:2d},Train_acc:{:.1f}%,Train_loss:{:.3f},Test_acc:{:.1f}%,Test_loss:{:.3f}')print(template.format(epoch+1,epoch_train_acc*100,epoch_train_loss,epoch_test_acc*100,epoch_test_loss))print('Done')
C:\Users\chengyuanting\.conda\envs\pytorch_cpu\lib\site-packages\torch\nn\functional.py:718: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally at  ..\c10/core/TensorImpl.h:1156.)return torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode)Epoch: 1,Train_acc:77.5%,Train_loss:0.753,Test_acc:0.2%,Test_loss:0.000
Epoch: 2,Train_acc:94.3%,Train_loss:0.190,Test_acc:0.1%,Test_loss:0.000
Epoch: 3,Train_acc:96.2%,Train_loss:0.125,Test_acc:0.2%,Test_loss:0.000
Epoch: 4,Train_acc:96.9%,Train_loss:0.098,Test_acc:0.2%,Test_loss:0.000
Epoch: 5,Train_acc:97.5%,Train_loss:0.081,Test_acc:0.2%,Test_loss:0.000
Done
# 结果可视化
import matplotlib.pyplot as plt
# 隐藏警告
import warnings
warnings.filterwarnings("ignore") # 忽略警告信息
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['figure.dpi'] = 100epochs_range = range(epochs)plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

在这里插入图片描述

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

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

相关文章

PMP证书含金量如何,打算以后从事项目管理这一行业的有没有必要考这个证书?

建议考一个,虽然说这一纸证书只是一个资格证书,本身不能带来多少利益,项目管理行业入门证书,但是现在很多企业招聘要求中写了“有 PMP 证书”优先录取,还是考一个有备无患。 含金量问题一直备受关注,总结了…

抽样算法——【数据科学与工程算法基础】

一、前言 这是课程的第二章节——抽样算法,主要分为三类。 详情可参考: 数据科学的算法基础——学习记录跳转中心 二、正篇 1.系统抽样 课本只介绍了最简单的——等距抽样。 直线等距抽样(Nn*k):即总体个数可以被抽…

【刷题训练】LeetCode125. 验证回文串

验证回文串 题目要求 示例 1: 输入: s “A man, a plan, a canal: Panama” 输出:true 解释:“amanaplanacanalpanama” 是回文串。 示例 2: 输入:s “race a car” 输出:false 解释:“rac…

Docker-数据卷、网络、dockerfile、挂载

目录 一、数据卷 二、MySQL数据 三、具名和匿名挂载 1、匿名挂载 2、具名挂载 3、指定挂载 四、Dockerfile 1、数据卷容器 2、dockerfile构建步骤 五、数据卷容器 1、实现多个容器之间数据共享 2、多个mysql之间共享数据库 六、Docker网络 1、Docker0 1、查看容器…

bpmn-js系列之Palette

前边写了四篇文章介绍了bpmn.js的基本使用,最近陆续有小伙伴加我催更,感谢对我这个半吊子前端的信任,接着更新bpmn.js的一些高级用法,本篇介绍对左侧工具栏Palette的隐藏和自定义修改 隐藏shape 左侧工具栏Palette有些图标我用不…

MATLAB:一些杂例

a 2; b 5; x 0:pi/40:pi/2; %增量为pi/40 y b*exp(-a*x).*sin(b*x).*(0.012*x.^4-0.15*x.^30.075*x.^22.5*x); %点乘的意义 z y.^2; %点乘的意义 w(:,1) x; %组成w,第一列为x w(:,2) y; %组成w,第二列为y w(:,3) z; %组成w,第三列为z…

MySQL一些命令记录

查看数据引擎 show engines;创建数据库,并选择库 CREATE DATABASE IF NOT EXISTS test_database; USE test_database;创建表 CREATE TABLE IF NOT EXISTS test_table (id INT AUTO_INCREMENT PRIMARY KEY,field1 VARCHAR(50),field2 VARCHAR(50),field3 VARCHAR(50),field4 …

2024最新注册谷歌账号(Gmail邮箱),解决此号码无法用于验证的方法,亲测有用!

我们知道,拥有一个谷歌账号/Gmail邮箱注册在全球互联网冲浪时会比较方便。但不少人在注册过程中,遇到了“此号码无法用于验证”的问题,如图: 有些人可能会认为是因为国内的手机号才没办法用于验证的,这简直是在胡说&am…

续上篇 qiankun 微前端配置

上篇文章地址:微前端框架 qiankun 配置使用【基于 vue/react脚手架创建项目 】-CSDN博客 主应用: src/main.js 配置: import Vue from vue import App from ./App.vue import router from ./router import { registerMicroApps, start } …

云计算与APP开发,如何利用云端服务提升应用性能?

随着移动应用程序(APP)的普及,如何提升应用性能成为了开发者们关注的重点之一。而云计算技术的发展为APP开发者提供了全新的解决方案。本文将探讨云计算与APP开发的结合,以及我们公司提出的解决方案,帮助开发者利用云端…

使用阿里云服务器查看网站备案的方法和注意事项

随着互联网的发展,网站注册已成为在中国建设网站的必要步骤。 在使用阿里云服务器时,我们可以通过以下步骤查看网站注册状态。 备案概述: 在中国,互联网信息服务提供者必须进行登记,以监管互联网内容、规范市场运营和…

3.14号arm

1. 计算机基础理论 1.1 计算机的组成 输入设备:将数据转换成计算机可以识别,存储,处理的形式,发送到计算机中 输出设备:将计算机对程序和数据的运算结果输送到外部的设备 存储器:用于将数据保存的模块。 …