深度学习pytorch——多分类问题(持续更新)

news2024/11/15 13:48:13

回归问题 vs 分类问题(regression vs classification)

回归问题(regression)

1、回归问题的目标是使预测值等于真实值,即pred=y。

2、求解回归问题的方法是使预测值和真实值的误差最小,即minimize dist(pred,y),一般我们通过求其2-范数,再平方得到它的最小值,也可以直接使用1-范数。

分类问题(classification)

1、分类问题的目标是找到最大的概率,即maximize benchmark(accurcy)。

2、求解分类问题,第一种方法是找到真实值与预测值之间的最小距离,即minimize dist( p\theta(y | x), pr(y | x) )。第二种方法是找到真实值与预测值的最小差异,即minimize divergence( p\theta(y | x), pr(y | x) )

但是,为什么不直接就概率呢?

1、如果概率不发生改变,权重发生改变,就会导致梯度等于0,出现梯度离散的现象。

2、由于正确的数量是不连续的,因此造成梯度也是不连续的,会导致梯度爆炸、训练不稳定等问题。

二分类问题(Binary Classification)

给定一个函数 f :x ---> p(y = 1 | x),如果二分类的角度去研究这个问题。预测的方法是:如果p(y = 1 | x) > 0.5 ,则预测值为1,否则预测值为0。

以交叉熵的角度分析二分类问题:

首先将二分类问题实例化,是对于猫和狗的分类问题,根据概率之和等于1,我们可以得到狗的概率等于1减去猫的概率,即P(dog) = (1 - P(cat)),接着将其带入到交叉熵公式中,得到以下公式:

将具体问题扩展到 一般问题,得到如下公式:

分析以上公式,当y = 1 时,H (P, Q) = log(p);当y = 0 时,H (P, Q) = log(1 - p);这两种情况随着p的变化,单调性是相反的,进一步证明了交叉熵解决二分类问题的可行性。

多分类问题(Multi-class classification)

给定一个函数 f :x ---> p(y  | x) ,其中 [𝑝 𝑦 = 0 𝑥 , 𝑝 𝑦 = 1 𝑥 , … , 𝑝 𝑦 = 9 𝑥 。必须满足:所有的𝑝 (𝑦 |𝑥) ∈ [0, 1];所有的概率和\Sigma 𝑝 (𝑦 = 𝑖 |𝑥 )= 1。

如何让所有的概率和为1呢?

使用softmax函数,详情请看深度学习pytorch——激活函数&损失函数(持续更新)-CSDN博客

交叉熵(cross entropy)

1、交叉熵的特点:

(1)具有很高的不确定性

(2)度量很惊喜

2、交叉熵的公式:

3、交叉熵的值越高就代表不稳定性越大

(1)以代码的方式解释

可以清楚的观察到数据的分布越平衡,最后得到的熵值就越高,反之,熵值就越低。

import torch
a = torch.full([4],1/4)
print('1.a:',a)
print("entropy:",-(a*torch.log2(a)).sum())

a = torch.tensor([0.1,0.1,0.1,0.7])
print('2.a:',a)
print("entropy:",-(a*torch.log2(a)).sum())

a = torch.tensor([0.001,0.001,0.001,0.999])
print('3.a:',a)
print("entropy:",-(a*torch.log2(a)).sum())

(2)以理论的角度解释

给出Cross Entropy 的公式:

当Cross Entropy 和Entropy 这两个分布相等时,即H(p,q)=H(p),此时两个分布重合,此时Dkl就等于0。

当使用one-hot加密,我们可以得到Entropy = 1log1 = 0,即H(p)= 0,则此时满足H(p, q) = Dkl(p|q)的情况,此时如果对H(p,q)进行优化,相当于将Dkl(p|q)直接优化了,这是我们直接可以不断减小Dkl(p|q)的值,使预测值逐渐接近真实值,这就很好的解释了我们为什么要使用Cross Entropy。

为什么不使用MSE?

1、sigmoid + MSE 的模式会导致梯度离散的现象

2、收敛速度比较慢

通过下图可以很合理的证明以上两个原因的合理性:

3、但是有时我们再做一些前沿的技术时,会发现MSE效果要好于cross entropy,因为它的求解梯度较为简单。

 MSE VS Cross Entropy

Cross Entropy = sofymax + log + nll_loss,最后的结果都是一样的。

import torch
from torch.nn import functional as F
# MSE vs Cross Entropy
x = torch.randn(1,784)
w = torch.randn(10,784)
logists = x@w.t()
# 使用Cross Entropy
print(F.cross_entropy(logists,torch.tensor([3])))
# tensor(0.0194)
# 自己处理
pred = F.softmax(logists, dim = 1)
pred_log = torch.log(pred)
print(F.nll_loss(pred_log,torch.tensor([3])))
# tensor(0.0194)

多分类问题实战 

############# Logistic Regression 多分类实战(MNIST)###########
# (1)加载数据
# (2)定义网络
# (3)凯明初始化
# (4)training:实例化一个网络对象,构建优化器,迭代,定义loss,输出
# (5)testing


import  torch
import  torch.nn as nn
import  torch.nn.functional as F
import  torch.optim as optim
from    torchvision import datasets, transforms


batch_size=200 #Batch Size:一次训练所选取的样本数
learning_rate=0.01
epochs=10 #1个epoch表示过了1遍训练集中的所有样本,这里可以设置为 5

# 加载数据
train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('../data', train=True, download=True,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('../data', train=False, transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
    ])),
    batch_size=batch_size, shuffle=True)

# 在pytorch中的定义(a,b)a是ch-out输出,b是ch-in输入,也就是(输出,输入)
# 比如第一个可以理解为从784降维成200的层
w1, b1 = torch.randn(200, 784, requires_grad=True),\
         torch.zeros(200, requires_grad=True)
w2, b2 = torch.randn(200, 200, requires_grad=True),\
         torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10, 200, requires_grad=True),\
         torch.zeros(10, requires_grad=True)

# 凯明初始化,如果不进行初始化会出现梯度离散的现象
# torch.nn.init.kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
torch.nn.init.kaiming_normal_(w1)
torch.nn.init.kaiming_normal_(w2)
torch.nn.init.kaiming_normal_(w3)

# 前向传播过程
def forward(x):
    x = x@w1.t() + b1
    x = F.relu(x)
    x = x@w2.t() + b2
    x = F.relu(x)
    x = x@w3.t() + b3
    x = F.relu(x)  #这里千万不要用softmax,因为之后的crossEntropyLoss中自带了。这里可以用relu,也可以不用。
    return x  #返回的是一个logits(即没有经过sigmoid或者softmax的层)


# 优化器
optimizer = optim.SGD([w1, b1, w2, b2, w3, b3], lr=learning_rate)
criteon = nn.CrossEntropyLoss()

for epoch in range(epochs):

    for batch_idx, (data, target) in enumerate(train_loader):
        data = data.view(-1, 28*28) # 将二维的图片数据打平 [200,784],第5课用的 x = x.view(x.size(0), 28*28)

        logits = forward(data) #这里是网络的输出
        loss = criteon(logits, target)  # 调用cross—entorpy计算输出值和真实值之间的loss

        optimizer.zero_grad()
        loss.backward()
        # print(w1.grad.norm(), w2.grad.norm())
        optimizer.step()
        # 每 batch_idx * 100=20000输出结果 每100个bachsize打印输出的结果,看看loss的情况
        if batch_idx % 100 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                       100. * batch_idx / len(train_loader), loss.item()))

# len(data)---指的是一个batch_size;
# len(train_loader.dataset)----指的是train_loader这个数据集中总共有多少张图片(数据)
# len(train_loader)---- len(train_loader.dataset)/len(data)---就是这个train_loader要加载多少次batch

    # 测试网络---test----每训练完一个epoch检测一下测试结果
    # 因为每一个epoch已经优化了batch次参数,得到的参数信息还是OK的
    test_loss = 0
    correct = 0
    for data, target in test_loader:
        data = data.view(-1, 28 * 28)
        logits = forward(data) #logits的shape=[200,10],--200是batchsize,10是最后输出结果的10分类
        test_loss += criteon(logits, target).item()  #每次将test_loss进行累加   #target=[200,1]---每个类只有一个正确结果

        pred = logits.data.max(1)[1]
        # 这里losgits.data是一个二维数组;其dim=1;max()---返回的是每行的最大值和最大值对应的索引
        # max(1)----是指每行取最大值;max(1)[1]---取每行最大值对应的索引号
        # 也可以写成 pred=logits.argmax(dim=1)
        correct += pred.eq(target.data).sum()
        #预测值和目标值相等个数进行求和--在for中,将这个test_loader中相等的个数都求出来
    test_loss /= len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))


"""
影响training的因素有:
1、learning rate过大
2、gradient vanish---梯度弥散(参数梯度为0,导致loss保持为常数,loss长时间得不到更新)
3、初始化问题----参数初始化问题
"""

课时50 多分类问题实战_哔哩哔哩_bilibili

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

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

相关文章

opencv各个模块介绍(2)

Features2D 模块:特征检测和描述子计算模块,包括SIFT、SURF等算法。 Features2D 模块提供了许多用于特征检测和描述子匹配的函数和类,这些函数和类可用于图像特征的提取、匹配和跟踪。 FeatureDetector:特征检测器的基类&#xf…

java数据结构与算法刷题-----LeetCode452. 用最少数量的箭引爆气球

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 解题思路:贪心算法,时间复杂度O( n ∗ l …

【计算机】——51单片机——持续更新

单片机是一种内部包含CPU、存储器和输入/输出接口等电路的集成电路(IC芯片) 单片机是单片微型计算机(Single Chip Microcomputer)的简称,用于控制领域,所以又称为微型控制器(Microcontroller U…

AI+软件工程:10倍提效!用ChatGPT编写系统功能文档

系统功能文档是一种描述软件系统功能和操作方式的文档。它让开发团队、测试人员、项目管理者、客户和最终用户对系统行为有清晰、全面的了解。 通过ChatGPT,我们能让编写系统功能文档的效率提升10倍以上。 ​《Leetcode算法刷题宝典》一位阿里P8大佬总结的刷题笔记…

一文看懂,高端及大流量停车场如何选择合适的道闸管理系统?

在当今快速发展的城市环境中,停车场的管理和运营已成为城市基础设施建设的重要组成部分。不同类型的停车场,如大流量停车场和高端停车场,面临着各自独特的挑战和需求。为了确保停车场的高效运营和良好的用户体验,选择合适的道闸管…

在ubuntu22.04系统上用pycharm编写第一个ros2程序

1.打开终端(快捷键altctrlt),创建工作空间,工作空间就是文件夹 2.创建一个功能包 打开pycharm的终端(altf12) 3.创建节点文件 在village_li文件夹右键新建li4.py 4.在li4.py编写代码 5.在setup.py里面添加…

Ubuntu Desktop 安装谷歌拼音输入法

Ubuntu Desktop 安装谷歌拼音输入法 1. Installation1.1. 汉语语言包​1.2. 谷歌拼音输入法1.3. 安装语言包1.4. 键盘输入方式系统1.5. 重启电脑1.6. 输入法配置 2. configuration2.1. Text Entry Settings… 3. ExecutionReferences 1. Installation 1.1. 汉语语言包 strong…

淘宝海外获取tglobal跨境商品原数据 API 返回值说明

一、应用场景 宝海外获取TGlobal跨境商品原数据API的应用场景相当广泛,涵盖了多个领域和行业。以下是一些主要的应用场景: 跨境电商平台:跨境电商平台可以通过此API获取全球范围内的商品信息,从而丰富平台上的商品种类&#xff…

边缘计算基础介绍及AKamai-linode产品分析

1、背景 随着互联网的发展,我们进入了大数据时代,这个时代也是移动互联网的时代,而且这个时代,大量的线下服务走到线上,随之而来的,比如外卖、叫车……于是,有各种各样的 App 和设备在收集你的…

如何打破SAST代码审计工具的局限性?

关键词:白盒测试;代码分析工具;代码扫描工具;静态代码检测工具; 在代码的世界里,安全问题如同潜伏的暗礁,随时可能让航行中的软件项目触礁沉没。SAST代码审计工具如同雷达一样,以其独…

Python - 深度学习系列30 - 使用LLaMA-Factory微调模型

说明 最实用的一种利用大语言模型的方式是进行微调。预训练模型与我们的使用场景一定会存在一些差异,而我们又不可能重头训练。 微调的原理并不复杂,载入模型,灌新的数据,然后运行再训练,保留checkpoints。但是不同项…

Cobalt Strike -- 各种beacon

今天来讲一下cs里面的beacon 其实cs真的功能很强大,自带代理创建,自带beacon通信!!! 一张图,就能说明beacon的工作原理 1.Beacon 每当有一台机器上线之后,我们都会选择sleep时间,…

PCI产业概述和产业发展动态分享

atsec白海蔚 2024年3月底 关键词:支付卡产业、PCI DSS、数据安全、支付交易 本文为atsec和作者技术共享类文章,旨在共同探讨信息安全的相关话题。转载请注明:atsec和作者名称。 *如有兴趣了解早期产业信息请参见作者于2021年4月发布信息&a…

数据在内存里面的存储

学习流程 ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————…

SOC子模块---RTC and watchdog

RTC RTC大致执行过程: 对SOC 中的锁相环或者外部晶振的时钟进行计数;产生时,分,秒的中断;送给中断控制器;中断控制器进行优先权选择后送给cpu;Cpu执行中断服务程序;在中断服务程序…

吴恩达深度学习笔记:神经网络的编程基础2.15-2.17

目录 第一门课:神经网络和深度学习 (Neural Networks and Deep Learning)第二周:神经网络的编程基础 (Basics of Neural Network programming)2.15 Python 中的广播(Broadcasting in Python)2.16 关于 python _ numpy 向量的说明&…

Java中的代理模式(动态代理和静态代理)

代理模式 我们先了解一下代理模式: 在开发中,当我们要访问目标类时,不是直接访问目标类,而是访问器代理类。通过代理类调用目标类完成操作。简单来说就是:把直接访问变为间接访问。 这样做的最大好处就是&#xff1a…

UE5 LiveLink 自动连接数据源,以及打包后不能收到udp消息的解决办法

为什么要自动连接数据源,因为方便打包后接收数据,这里我是写在了Game Instance,也可以写在其他地方,自行替换成Beginplay和Endplay 关于编辑器模式下能收到udp消息,打包后不能收到消息的问题有两点需要排查,启动打包后…

数据结构·排序

1. 排序的概念及运用 1.1 排序的概念 排序:排序是将一组“无序”的记录序列,按照某个或某些关键字的大小,递增或递减归零调整为“有序”的记录序列的操作 稳定性:假定在待排序的记录序列中,存在多个具有相同关键字的记…

大数据技术原理与应用 01.大数据概述

不可以垂头丧气,会显矮 —— 24.3.24 参考学习:厦门大学 林子雨老师 大数据技术原理与应用 一、大数据时代 大数据概念、影响、应用、关键技术 大数据与云计算、物联网的关系 ①三次信息化浪潮时代 ②第三次信息化浪潮的技术支撑 1>存储设备容量不断…