深度学习快速入门----Pytorch 系列3

news2024/11/26 4:31:51

注:参考B站‘小土堆’视频教程

视频链接:【PyTorch深度学习快速入门教程(绝对通俗易懂!)【小土堆】

系列文章:
深度学习快速入门----Pytorch 系列1
深度学习快速入门----Pytorch 系列2
深度学习快速入门----Pytorch 系列3


文章目录

    • 一、完整的模型训练套路
        • 1、预备知识
        • 2、步骤
        • 3、代码
        • 4、运行结果
    • 二、利用GPU训练
        • 1、需要修改的地方
        • 2、比较CPU与GPU训练耗费时间
        • 3、用.to(device)的方式
    • 三、完整的模型验证套路

一、完整的模型训练套路

1、预备知识

通过argmax计算正确率:

import torch

outputs = torch.tensor([[0.1,0.2],
                        [0.3,0.4]])

print(outputs.argmax(1))
preds = outputs.argmax(1)
targets = torch.tensor([0,1])
print((preds == targets).sum())

在这里插入图片描述


思路

在这里插入图片描述

2、步骤

  • 准备数据集
  • 利用 DataLoader 来加载数据集
  • 创建网络模型
  • 损失函数
  • 优化器
  • 设置训练网络的一些参数
  • 设置训练轮数
    • 训练步骤

      • 计算损失函数
      • 优化
    • 测试步骤

      • 计算损失函数
      • 计算准确率
  • 展示
  • 保存模型

3、代码

# model.py
import torch
from torch import nn

# 搭建神经网络
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(3, 32, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(64*4*4, 64),
            nn.Linear(64, 10)
        )

    def forward(self, x):
        x = self.model(x)
        return x


if __name__ == '__main__':
    tudui = Tudui()
    input = torch.ones((64, 3, 32, 32))
    output = tudui(input)
    print(output.shape)
# train.py
import torchvision
from torch.utils.tensorboard import SummaryWriter

from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoader

train_data = torchvision.datasets.CIFAR10(root="dataset", train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)
test_data = torchvision.datasets.CIFAR10(root="dataset", train=False, transform=torchvision.transforms.ToTensor(),
                                         download=True)

# length 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 如果train_data_size=10, 训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))


# 利用 DataLoader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 创建网络模型
tudui = Tudui()

# 损失函数
loss_fn = nn.CrossEntropyLoss()

# 优化器
# learning_rate = 0.01
# 1e-2=1 x (10)^(-2) = 1 /100 = 0.01
learning_rate = 1e-2
# 随机梯度下降法
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("logs_train")

for i in range(epoch):
    print("-------第 {} 轮训练开始-------".format(i+1))

    # 训练步骤开始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        outputs = tudui(imgs)
        loss = loss_fn(outputs, targets)

        # 优化器优化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        total_train_step = total_train_step + 1
        if total_train_step % 100 == 0:
            print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))
            writer.add_scalar("train_loss", loss.item(), total_train_step)

    # 测试步骤开始
    tudui.eval()
    total_test_loss = 0
    # 整体正确率
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            outputs = tudui(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()

            accuracy = (outputs.argmax(1) == targets).sum()
            total_accuracy = total_accuracy + accuracy

    print("整体测试集上的Loss: {}".format(total_test_loss))
    print("整体测试集上的正确率: {}".format(total_accuracy/test_data_size))
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    writer.add_scalar("test_accuracy", total_accuracy/test_data_size, total_test_step)
    total_test_step = total_test_step + 1

    # 保存某一轮训练后的结果
    torch.save(tudui, "tudui_{}.pth".format(i))
    print("模型已保存")

writer.close()

4、运行结果

在这里插入图片描述
tensorboard:
在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

二、利用GPU训练

1、需要修改的地方

  • 网络模型
  • 数据(输入,标注)
  • 损失函数
  • .cuda()
import torch
import torchvision
from torch.utils.tensorboard import SummaryWriter
import time

# from model import *
# 准备数据集
from torch import nn
from torch.utils.data import DataLoader

train_data = torchvision.datasets.CIFAR10(root="dataset", train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)
test_data = torchvision.datasets.CIFAR10(root="dataset", train=False, transform=torchvision.transforms.ToTensor(),
                                         download=True)

# length 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 如果train_data_size=10, 训练数据集的长度为:10
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))


# 利用 DataLoader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 创建网络模型
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(3, 32, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(64*4*4, 64),
            nn.Linear(64, 10)
        )

    def forward(self, x):
        x = self.model(x)
        return x
tudui = Tudui()
if torch.cuda.is_available():
    tudui = tudui.cuda()

# 损失函数
loss_fn = nn.CrossEntropyLoss()
if torch.cuda.is_available():
    loss_fn = loss_fn.cuda()
# 优化器
# learning_rate = 0.01
# 1e-2=1 x (10)^(-2) = 1 /100 = 0.01
learning_rate = 1e-2
optimizer = torch.optim.SGD(tudui.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("logs_train")
start_time = time.time()
for i in range(epoch):
    print("-------第 {} 轮训练开始-------".format(i+1))

    # 训练步骤开始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        if torch.cuda.is_available():
            imgs = imgs.cuda()
            targets = targets.cuda()
        outputs = tudui(imgs)
        loss = loss_fn(outputs, targets)

        # 优化器优化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        total_train_step = total_train_step + 1
        if total_train_step % 100 == 0:
            end_time = time.time()
            print(end_time - start_time)
            print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))
            writer.add_scalar("train_loss", loss.item(), total_train_step)

    # 测试步骤开始
    tudui.eval()
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            if torch.cuda.is_available():
                imgs = imgs.cuda()
                targets = targets.cuda()
            outputs = tudui(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()
            accuracy = (outputs.argmax(1) == targets).sum()
            total_accuracy = total_accuracy + accuracy

    print("整体测试集上的Loss: {}".format(total_test_loss))
    print("整体测试集上的正确率: {}".format(total_accuracy/test_data_size))
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    writer.add_scalar("test_accuracy", total_accuracy/test_data_size, total_test_step)
    total_test_step = total_test_step + 1

    torch.save(tudui, "tudui_{}.pth".format(i))
    print("模型已保存")

writer.close()

2、比较CPU与GPU训练耗费时间

  • CPU
    在这里插入图片描述
  • GPU
    在这里插入图片描述

3、用.to(device)的方式

# ···

# 定义训练的设备
device = torch.device("cuda")

# ···

tudui = Tudui()
tudui = tudui.to(device)

# 损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.to(device)

# ···

# 训练步骤开始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        imgs = imgs.to(device)
        targets = targets.to(device)
        outputs = tudui(imgs)
        loss = loss_fn(outputs, targets)

# ···

# 测试步骤开始
    tudui.eval()
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            imgs = imgs.to(device)
            targets = targets.to(device)
            outputs = tudui(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()
            accuracy = (outputs.argmax(1) == targets).sum()
            total_accuracy = total_accuracy + accuracy

三、完整的模型验证套路

在这里插入图片描述
用GPU训练30轮后的网络模型:

在这里插入图片描述

import torch
import torchvision
from PIL import Image
from torch import nn

image_path = "imgs/dog.png"
image = Image.open(image_path)
print(image)
image = image.convert('RGB')
transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32, 32)),
                                            torchvision.transforms.ToTensor()])

image = transform(image)
print(image.shape)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(3, 32, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(64*4*4, 64),
            nn.Linear(64, 10)
        )

    def forward(self, x):
        x = self.model(x)
        return x

model = torch.load("tudui_29_gpu.pth", map_location=torch.device('cpu'))
print(model)
image = torch.reshape(image, (1, 3, 32, 32))
model.eval()
with torch.no_grad():
    output = model(image)
print(output)

print(output.argmax(1))

运行结果:

在这里插入图片描述
与CIFAR10数据集比较,预测正确:

在这里插入图片描述

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

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

相关文章

[附源码]计算机毕业设计JAVA小区供暖收费管理系统

[附源码]计算机毕业设计JAVA小区供暖收费管理系统 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM my…

世界杯小组赛频繁爆冷?这或许是强队的谋略 一分钟带你了解2022卡塔尔世界杯赛制

今年的世界杯你赚到钱了吗? 我们这里所说的世界杯是指世界杯决赛圈,也被叫做世界杯正赛。参赛队伍是已经通过世界杯预选赛选拔出的的32支队伍(除了东道主卡塔尔自动晋级)。 世界杯中没有皇马、巴萨、曼联,这些都是俱乐…

基于 SpringBoot + MyBatis 的网页版五子棋对战

目录 一、项目所要实现的功能模块 1、用户模块 2、匹配模块 3、对战模块 二、使用技术 三、项目截图 1、登录页面 2、注册页面 3、游戏大厅页面 4、游戏房间页面 四、创建 SpringBoot 项目 1、在 IDEA 中创建一个 SpringBoot 项目 2、设置项目名称 3、选择项目依…

第2-4-9章 规则引擎Drools实战(2)-信用卡申请

文章目录9.2 信用卡申请9.2.1 计算规则9.2.2 实现步骤9.2 信用卡申请 全套代码及资料全部完整提供,点此处下载 本小节我们需要通过Drools规则引擎来根据规则进行申请人的合法性检查,检查通过后再根据规则确定信用卡额度,最终页面效果如下&a…

浅谈架构备考.补缺.V1

2022.11.28 可靠性分析 to repair to failure between failure 平均故障间隔时间。平均故障间隔时间(Mean Time Between Failure,MTBF)常常与 MTTF 发生混淆。 因为两次故障(失败)之间必然有修复行为,因…

SpringBoot主启动类使用@ComponentScans、@ComponentScan扫描组件类,注意避坑

前言: 1、大家都知道,Springboot主启动加载会默认扫描同级包目录下所有的组件类、配置类,然后进行解析注入到Spring容器中。SpringBootApplication 是个联合注解,里面包含了 ComponentScan 组件扫描注解,所以我们不需要…

沉睡者IT - 什么是NFT?

欢迎关注沉睡者IT,点上面关注我 ↑ ↑ NFT,全称为Non-Fungible Token,指非同质化通证,实质是区块链网络里具有唯一性特点的可信数字权益凭证,是一种可在区块链上记录和处理多维、复杂属性的数据对象。 以上是百度百科…

MongoBd 离线安装与管理

背景: 鉴于内部网络原因,可能一个简单的操作变得复杂化,现在就Mongodb的离线安装分享本人的操作经验: 材料: 操作系统:centos7.6 MongoDB(主程序) : mongodb-linux-x86_64-rhel70-6.0.1.tgz 下载地址:下载…

传输层协议 —— UDP

目录 一、端口号的划分范围 二、认识知名端口号 三、两个问题 四、nestat和pidof命令 五、UDP协议 1. UDP首部格式 2. UDP的特点 3. 面向数据报 4. UDP的缓冲区 5. UDP使用注意事项 6. 基于UDP的应用层协议 一、端口号的划分范围 端口号的长度是16位,因此…

博途PLC和MATLAB矩阵运算存储方法对比

MATLBA不用多说,号称矩阵实验室可想而知在MATLAB里对矩阵的存储、运算非常简单、高效。如下图简单定义一个5*3的矩阵 1、rand(5*3) 上面利用rand()函数简单的实现了内存矩阵存储空间分配+附随机初值,下面我们看下博途里的矩阵定义存储方法。 BP神经网络PID算法的PLC实现过程…

量表如何分析?

一、什么是量表 量表是一种测量工具,通常用来测量人们的主观态度、意见或价值观念。我们经常会在问卷中使用量表对调查对象进行测量,最常见到的就是李克特量表。 ‍1、定义:李克特量表 李克特量表是最常用的量表,是由美国社会心…

基于AD Event日志检测LSASS凭证窃取攻击

01、简介 简单介绍一下,LSASS(本地安全机构子系统服务)在本地或域中登录Windows时,用户生成的各种凭证将会存储在LSASS进程的内存中,以便用户不必每次访问系统时重新登录。 攻击者在获得起始攻击点后,需要获取目标主机上的相关凭证…

AutoCAD Electrical 2022—项目特性

当绘图的过程中如果弹出上面的对话框,就是库和图标菜单途径不对造成的; 点击浏览找到正确的位置或点击默认设置恢复默认的路径; 元件对应原理图的设置; 标记格式:放置元件的代号的格式; 线号:编…

iphone怎么传数据到另一个手机,苹果如何转移数据到新手机,两台iphone怎么同步所有数据

换新手机后,需要迁移旧苹果手机的数据到新苹果手机里面,那么,iphone怎么传数据到另一个手机?本篇文章带您深度了解苹果手机的数据传输技巧。 方法一、通过“快速开始”传输数据 苹果手机如何数据传输?我记得之前换 iP…

【JUC】信号量Semaphore详解

前言 大家应该都用过synchronized 关键字加锁,用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行,有什么好的办法呢? 答案就是JUC提供的信号量Semaphore。 介绍和使用 Semaphore(信号量)可以用…

Servlet API 表白墙

Servlet API 详解 主要三个: 1.HttpServlet 2.HttpServletRequest 3.HttpServletResponse 1.HttpServlet 方法名称 调用时机 init 在 HttpServlet 实例化之后被调用一次 destroy 在 HttpServlet 实例不再使用的时候调用一次 service 收到 HTTP 请求的时候调用 …

vue开发测评系统思路及踩坑

最近公司做了一个测评系统,因为时间很短,本以为会很简单,没有想到踩了很多坑。 先看下部分效果图吧 然后在说下需求 1:所有的答案都是动态的(例如选择是出来的是第二题,选择否出来的是第五题&#xff09…

【Linux】文件权限的理解

不用心做一件事情,你永远不知道自己有多么的强大! 文章目录一、shell命令以及运行原理(centos7下,shell为命令行解释器bash)1. 什么是shell(Kernel外层的软件层)?2. shell的交互方式存在意义3. windows GUI对比Linux shell(都是Ke…

算法: C# 中将 Dictionary 集合用作 Hashmap 等价类型

一.只出现一次的数字 1.1 题目描述 给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 示例 1: 输入:nums [2,2,3,2] 输出:3 示例 2&#…

Faster RCNN全文翻译

Abstract—State-of-the-art【最先进的】 object detection networks depend on region proposal algorithms to hypothesize【假设、推测】 object locations.Advances like SPPnet [1] and Fast R-CNN [2] have reduced the running time of these detection networks, expos…