《PyTorch深度学习实践》第九讲 多分类问题

news2024/9/22 9:46:24

b站刘二大人《PyTorch深度学习实践》课程第九讲多分类问题笔记与代码:https://www.bilibili.com/video/BV1Y7411d7Ys?p=9&vd_source=b17f113d28933824d753a0915d5e3a90


  • 二分类问题中计算出 P ( y = 1 ) P(y=1) P(y=1)即可直接得到 P ( y = 0 ) P(y=0) P(y=0),即 P ( y = 0 ) = 1 − P ( y = 1 ) P(y=0) = 1 - P(y=1) P(y=0)=1P(y=1)
  • 在多分类问题中则无法这样得到,样本属于各个类别的概率是互斥的,例如某个样本属于1的概率为0.8,那么该样本属于其他数字的概率就会被抑制,变得更小,因为这个样本属于各个类别的概率的总和必须等于1
    • 概率大于0
    • 所有概率和等于1
  • 分类问题的输出是一个分布
    • 输出之间存在竞争
image-20230701175106087

多分类问题中,中间用Sigmoid,输出层加Softmax,使其输出一个分布,满足概率大于0且概率和为1这两个条件

image-20230701175332482

Softmax Layer

  • 指数运算(exponent)一定大于0
  • 所有的和作为分母 -> 保证和为1
image-20230701175955826

例子:

image-20230701180137579

通过softmax得到一个分布后如何计算损失函数Loss ???

image-20230701180708907
import numpy as np

y = np.array([1, 0, 0])				   # 真实标签
z = np.array([0.2, 0.1, -0.1])           # softmax输入
y_pred = np.exp(z) / np.exp(z).sum()	# softmax输出
loss = (-y * np.log(y_pred)).sum()		# 计算loss
print(loss)

PyTorch中实现:

image-20230701181238944

MNIST Dataset分类

  • http://yann.lecun.com/exdb/mnist/
image-20230701181822388 image-20230701181900876
  • Import Package

    • 激活函数使用更流行的Relu
    import torch
    
    # 构造Dataloader
    from torchvision import transforms  # 用于对图像进行一些处理
    from torchvision import datasets
    from torch.utils.data import DataLoader
    
    import torch.nn.functional as F     # 使用更流行的激活函数Relu
    import torch.optim as optim         # 构造优化器
    
  • Prepare Dataset

    batch_size = 64
    
    # 将PIL图像转成Tensor
    transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307, ), (0.3081, ))
    ])
    
    # 训练集
    train_dataset = datasets.MNIST(root='D:/pycharm_workspace/Liuer_lecturer/dataset/mnist',
                                   train=True,
                                   download=True,
                                   transform=transform)  # 读取到某个数据后就直接进行transform处理
    train_loader = DataLoader(train_dataset,
                              shuffle=True,
                              batch_size=batch_size)
    # 测试集
    test_dataset = datasets.MNIST(root='D:/pycharm_workspace/Liuer_lecturer/dataset/mnist',
                                  train=False,
                                  download=True,
                                  transform=transform)
    test_loader = DataLoader(train_dataset,
                             shuffle=False,
                             batch_size=batch_size)
    
    • 原始图像像素值是0 ~ 255的整数,将其转成0 ~ 1的张量

      • Normalize是归一化处理。0.1307是均值,0.3081是标准差
      image-20230701184943431
    • 通道(H:高,W:宽,C:通道channel)

      • 表示图像时一般是W * H * C,PyTorch中是C * W * H
      image-20230701184404200
  • Design Model

    image-20230701185513148
    class Net(torch.nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            self.l1 = torch.nn.Linear(784, 512)
            self.l2 = torch.nn.Linear(512, 256)
            self.l3 = torch.nn.Linear(256, 128)
            self.l4 = torch.nn.Linear(128, 64)
            self.l5 = torch.nn.Linear(64, 10)
    
        def forward(self, x):
            x = x.view(-1, 784)
            x = F.relu(self.l1(x))
            x = F.relu(self.l2(x))
            x = F.relu(self.l3(x))
            x = F.relu(self.l4(x))
            return self.l5(x)	# 最后一层不做激活,要直接输到softmax中
    
    
    model = Net()
    
  • Construct Loss and Optimizer

    image-20230701190130003
    criterion = torch.nn.CrossEntropyLoss()
    optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)  # 带冲量(momentum)的梯度下降
    
  • Train and Test

    • 将一轮循环封装成函数,简化代码复杂度
    # 一轮训练
    def train(epoch):
        running_loss = 0.0
        for batch_idx, data in enumerate(train_loader, 0):
            inputs, target = data  # inputs输入x,target输出y
            optimizer.zero_grad()
    
            # forward + backward + update
            outputs = model(inputs)
            loss = criterion(outputs, target)
            loss.backward()
            optimizer.step()
    
            running_loss += loss.item()  # loss累加
    
            # 每300轮输出一次,减少计算成本
            if batch_idx % 300 == 299:
                print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss/300))
                running_loss = 0.0
    
    
    # 测试函数
    def test():
        correct = 0
        total = 0
        with torch.no_grad():   # 让后续的代码不计算梯度
            for data in test_loader:
                images, labels = data
                outputs = model(images)
                _, predicted = torch.max(outputs.data, dim=1)
                total += labels.size(0)
                correct += (predicted == labels).sum().item()
        print('Accuracy on test set: %d %%' % (100 * correct / total))
    

完整的代码:

import torch

# 构造Dataloader
from torchvision import transforms  # 用于对图像进行一些处理
from torchvision import datasets
from torch.utils.data import DataLoader

import torch.nn.functional as F     # 使用更流行的激活函数Relu
import torch.optim as optim         # 构造优化器


batch_size = 64

# Compose的实例化
transform = transforms.Compose([
    transforms.ToTensor(),  # 将PIL图像转成Tensor
    transforms.Normalize((0.1307, ), (0.3081, ))  # 归一化。0.1307是均值,0.3081是标准差
])

# 训练集
train_dataset = datasets.MNIST(root='D:/pycharm_workspace/Liuer_lecturer/dataset/mnist',
                               train=True,
                               download=True,
                               transform=transform)  # 读取到某个数据后就直接进行transform处理
train_loader = DataLoader(train_dataset,
                          shuffle=True,
                          batch_size=batch_size)
# 测试集
test_dataset = datasets.MNIST(root='D:/pycharm_workspace/Liuer_lecturer/dataset/mnist',
                              train=False,
                              download=True,
                              transform=transform)
test_loader = DataLoader(train_dataset,
                         shuffle=False,
                         batch_size=batch_size)


class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.l1 = torch.nn.Linear(784, 512)
        self.l2 = torch.nn.Linear(512, 256)
        self.l3 = torch.nn.Linear(256, 128)
        self.l4 = torch.nn.Linear(128, 64)
        self.l5 = torch.nn.Linear(64, 10)

    def forward(self, x):
        x = x.view(-1, 784)
        x = F.relu(self.l1(x))
        x = F.relu(self.l2(x))
        x = F.relu(self.l3(x))
        x = F.relu(self.l4(x))
        return self.l5(x)


model = Net()

criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)  # 带冲量的梯度下降


# 一轮训练
def train(epoch):
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader, 0):
        inputs, target = data  # inputs输入x,target输出y
        optimizer.zero_grad()

        # forward + backward + update
        outputs = model(inputs)
        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()  # loss累加

        # 每300轮输出一次,减少计算成本
        if batch_idx % 300 == 299:
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss/300))
            running_loss = 0.0


# 测试函数
def test():
    correct = 0
    total = 0
    with torch.no_grad():   # 让后续的代码不计算梯度
        for data in test_loader:
            images, labels = data
            outputs = model(images)
            _, predicted = torch.max(outputs.data, dim=1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print('Accuracy on test set: %d %%' % (100 * correct / total))


if __name__ == '__main__':
    for epoch in range(10):
        train(epoch)
        test()

image-20230701193134398

image-20230701193156037image-20230701193214824

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

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

相关文章

LeetCode 打卡day46-- 单词拆分和多重背包问题

一个人的朝圣 — LeetCode打卡第46天 知识总结 Leetcode 139. 单词拆分题目说明代码说明 知识总结 今天写了一道题目, 但是还挺难的, 而且是面试高频题目 还过了一遍多重背包问题. 多重背包与01背包的区别在于多重背包限制了物品的个数, 某些物品的个数可能不为1, 可以使用两…

Opencascade源码学习之模型算法_建模算法介绍

Opencascade源码学习之模型算法_建模算法介绍 介绍几何工具相交两曲线相交曲线曲面相交两曲面相交 插值Geom2dAPI_InterpolateGeomAPI_Interpolate 约束的直线和圆约束类型可用的线和圆的类型外部/内部直线的方向两个圆相切给定半径的圆与两个圆相切算法的类型 约束的曲线和曲面…

初识React/JSX

JSX ​​​​​​​推荐使用小括号包裹jsx

【Linux】硬链接 和 软链接

为了方便用户访问文件,Linux提供了一种称为连接(link)的机制,可以将一个文件或目录与另一个文件或目录建立关联,从而实现多个路径指向同一个文件或目录的效果。 一、概述二、硬链接和软链接详解2.1 硬链接2.11 硬链接的…

ASIC 数字设计:概述和开发流程

概述 集成电路是由硅晶圆(wafer)切割出来的芯片(die)组成的。每个晶圆可以切割出数百个芯片。 ASIC是指针对特定应用而设计的集成电路(Application Specific Integrated Circuit),与通用的存储器…

ctfhub靶场练习——SSRF攻击

文章目录 前言关卡、内网访问关卡、伪协议读取文件关卡、端口扫描关卡、POST1、使用http协议查看本地的flag.php文件2、使用burp抓包,并发送到Repeater模块进行操作3、构造一个简单的POST请求:4、对构造的post请求进行url编码第一次编码:对第…

【裸机开发】GPT 定时器(一) —— GPT的功能、寄存器解析

后续需要使用 GPT 计数器实现中断以及延时,这里我们需要先了解一下GPT的功能以及相关寄存器。 目录 一、GPT 定时器的功能 1、计数器 2、输入捕获 3、输出比较(GPT的两种工作模式) 二、寄存器解析 1、GPTx_CR 2、GPTx_PR 3、GPTx_SR …

Jetson Nano烧写系统镜像

Jetson Nano是一款形状和接口类似于树莓派的嵌入式主板,搭载了四核Cortex-A57处理器,GPU则是拥有128个NVIDIA CUDA核心的NVIDIA Maxwell架构显卡,内存为4GB的LPDDR4,60Hz视频解码。 1.烧录前准备 电源线(必备&#xf…

游戏陪玩语音聊天系统3.0商业升级独立版本源码

首发价值29800元的最新商业版游戏陪玩语音聊天系统3.0商业升级独立版本源码 1、增加人气店员轮播 2、优化ui界面丨优化游戏图标展示丨优化分类展示 3、增加动态礼物打赏功能 4、增加礼物墙功能 增加店员满足业绩,才能升级功能 5、增加店员等级不同,可接…

操作系统第4章习题

B 一个目录文件包含多个目录项 B. 在打开文件的时候还不用 只有在读文件的时候 才需要把数据读到内存中 C 不完整 D 在外存中 FCB不是文件控制块吗 为什么是文件目录项 文件属性:有的文件是只读的 访问控制的灵活性较高

【前端2】jquary,bootstrap,vue

文章目录 1.jquary:选择器1.1 jquery框架引入:$("mydiv") 当成id选择器1.2 jquery版本/对象:$(js对象) -> jquery对象1.3 jquery的页面加载事件:$ 想象成 window.onload 1.4 jquery的基本选择器:$()里内容…

7 拓展中断_事件控制器(EXTI)(STM32HAL库 )

目录 EXTI-扩展中断和事件控制器 事件的概念 EXTI-扩展中断和事件控制器 EXTI外设框图 F1/F4/F7(看懂与或门) H7 STM32CubeMX中的EXTI配置 EXTI-扩展中断和事件控制器 事件的概念 STM32上许许多多的外设,是通过内部信号来协同工作的。…

Android Compose Button defaultButtonColors

Android Compose Button defaultButtonColors 本文最新更新地址 https://gitee.com/chenjim/chenjimblog 发现问题 最近看 Android Compose 相关资料发现如下代码 colors defaultButtonColors( backgroundColor if (count > 5) Color.Green else Color.White )原文地…

从C语言到C++_23(多态)抽象类+虚函数表VTBL+多态的面试题

目录 1. 多态(polymorphism) 1.1 构成多态的两个条件 1.2 虚函数重写(覆盖) 1.3 协变构成多态 1.4 父虚子非虚构成多态 1.5 析构函数的重写 1.6 final 和 override 关键字(C11) 1.7 重载、覆盖、隐藏的对比 2. 抽象类&am…

通信接口和通信方式总结

通信接口和通信方式总结 一、通信接口主要的5种类型二、通信方式2.1 并行和串行2.2 单工、半双工及全双工通信2.3 串行通信分类 - 同步\异步2.4 波特率 Baud Rate 三、串联设备的接口类型 - 网口和串口3.1 串口 - COM口3.1.1 基本介绍及应用3.1.2 接线方式 - 232、422、485接线…

时序预测 | MATLAB实现PSO-GRU(粒子群优化门控循环单元)时间序列预测

时序预测 | MATLAB实现PSO-GRU(粒子群优化门控循环单元)时间序列预测 目录 时序预测 | MATLAB实现PSO-GRU(粒子群优化门控循环单元)时间序列预测预测效果基本介绍模型介绍PSO模型GRU模型PSO-GRU模型 程序设计参考资料致谢 预测效果 基本介绍 Matlab基于PSO-GRU粒子群算法优化门…

【vue3-element-admin 】基于 Vue3 + Vite4 + TypeScript5+ Element-Plus 从0到1搭建企业级后台管理系统(前后端开源)

vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 Element Plus 版本的后台管理前端解决方案,技术栈为 Vue3 Vite4 TypeScript Element Plus Pinia Vue Router 等当前主流框架。 相较于其他管理前端框架,vue3-element-admin 的优势在于一…

Docker中安装Nginx

查看可以安装的Nginx版本: docker search nginx 下载最新版本: docker pull nginx :latest 可以省略 运行容器: docker run -itd --name my_nginx -p 80:80 nginx 在主机通过 https://localhost:80或者 http://192.168.40.100:80可以访问 如果之前创…

Java阶段四Day10

Java阶段四Day10 文章目录 Java阶段四Day10关于RedisRedis的数据类型Redis中的list类型Redis的常用命令关于Key的格式Redis编程使用Redis时的数据一致性问题 关于ApplicationRunnerLoadCacheRunnerContentCategoryServiceImpl 计划任务ScheduleConfigurationCategoryCacheSched…

已烧写过的镜像重新烧镜像教程

本教程是已经烧录过镜像的SD卡,无法被电脑识别盘符导致无法重新烧录镜像的教程。一般是win7系统无法识别烧录过的Ubuntu系统盘符。win10可以使用SDformat软件格式化。 1.确定读卡器是否识别到SD卡。 点击计算机右键选择“管理”,选择磁盘管理&#xff0…