教你如何使用PyTorch解决多分类问题
本文分享自华为云社区《使用PyTorch解决多分类问题:构建、训练和评估深度学习模型》,作者: 小馒头学Python。
引言
当处理多分类问题时,PyTorch是一种非常有用的深度学习框架。在这篇博客中,我们将讨论如何使用PyTorch来解决多分类问题。我们将介绍多分类问题的基本概念,构建一个简单的多分类神经网络模型,并演示如何准备数据、训练模型和评估结果。
什么是多分类问题?
多分类问题是一种机器学习任务,其中目标是将输入数据分为多个不同的类别或标签。与二分类问题不同,多分类问题涉及到三个或更多类别的分类任务。例如,图像分类问题可以将图像分为不同的类别,如猫、狗、鸟等。
处理步骤
- 准备数据:
收集和准备数据集,确保每个样本都有相应的标签,以指明其所属类别。
划分数据集为训练集、验证集和测试集,以便进行模型训练、调优和性能评估。
- 数据预处理:
对数据进行预处理,例如归一化、标准化、缺失值处理或数据增强,以确保模型训练的稳定性和性能。
- 选择模型架构:
选择适当的深度学习模型架构,通常包括卷积神经网络(CNN)、循环神经网络(RNN)、Transformer等,具体取决于问题的性质。
- 定义损失函数:
为多分类问题选择适当的损失函数,通常是交叉熵损失(Cross-Entropy Loss)。
- 选择优化器:
选择合适的优化算法,如随机梯度下降(SGD)、Adam、RMSprop等,以训练模型并调整权重。
- 训练模型:
使用训练数据集来训练模型。在每个训练迭代中,通过前向传播和反向传播来更新模型参数,以减小损失函数的值。
- 评估模型:
使用验证集来评估模型性能。常见的性能指标包括准确性、精确度、召回率、F1分数等。
- 调优模型:
根据验证集的性能,对模型进行调优,可以尝试不同的超参数设置、模型架构变化或数据增强策略。
- 测试模型:
最终,在独立的测试数据集上评估模型的性能,以获得最终性能评估。
- 部署模型:
将训练好的模型部署到实际应用中,用于实时或批处理多分类任务。
多分类问题
之前我们讨论的问题都是二分类居多,对于二分类问题,我们若求得p(0),南无p(1)=1-p(0),还是比较容易的,但是本节我们将引入多分类,那么我们所求得就转化为p(i)(i=1,2,3,4…),同时我们需要满足以上概率中每一个都大于0;且总和为1。
处理多分类问题,这里我们新引入了一个称为Softmax Layer

接下来我们一起讨论一下Softmax Layer层

首先我们计算指数计算e的zi次幂,原因很简单e的指数函数恒大于0;分母就是e的z1次幂+e的z2次幂+e的z3次幂…求和,这样所有的概率和就为1了。
下图形象的展示了Softmax,Exponent这里指指数,和上面我们说的一样,先求指数,这样有了分子,再将所有指数求和,最后一一divide,得到了每一个概率。

接下来我们一起来看看损失函数

如果使用numpy进行实现,根据刘二大人的代码,可以进行如下的实现
import numpy as np y = np.array([1,0,0]) z = np.array([0.2,0.1,-0.1]) y_pred = np.exp(z)/np.exp(z).sum() loss = (-y * np.log(y_pred)).sum() print(loss)
运行结果如下

注意:神经网络的最后一层不需要激活
在pytorch中
import torch y = torch.LongTensor([0]) # 长整型 z = torch.Tensor([[0.2, 0.1, -0.1]]) criterion = torch.nn.CrossEntropyLoss() loss = criterion(z, y) print(loss)
运行结果如下

下面根据一个例子进行演示
criterion = torch.nn.CrossEntropyLoss()
Y = torch.LongTensor([2,0,1])
Y_pred1 = torch.Tensor([[0.1, 0.2, 0.9],
[1.1, 0.1, 0.2],
[0.2, 2.1, 0.1]])
Y_pred2 = torch.Tensor([[0.8, 0.2, 0.3],
[0.2, 0.3, 0.5],
[0.2, 0.2, 0.5]])
l1 = criterion(Y_pred1, Y)
l2 = criterion(Y_pred2, Y)
print("Batch Loss1 = ", l1.data, "\nBatch Loss2=", l2.data)
运行结果如下

根据上面的代码可以看出第一个损失比第二个损失要小。原因很简单,想对于Y_pred1每一个预测的分类与Y是一致的,而Y_pred2则相差了一下,所以损失自然就大了些
MNIST dataset的实现
首先第一步还是导包
import torch from torchvision import transforms from torchvision import datasets from torch.utils.data import DataLoader import torch.nn.functional as F import torch.optim as optim
之后是数据的准备
batch_size = 64 # transform可以将其转化为0-1,形状的转换从28×28转换为,1×28×28 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307, ), (0.3081, )) # 均值mean和标准差std ]) train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform) train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size) test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform) test_loader = DataLoader(test_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
optimizer.zero_grad()
# forward + backward + update
outputs = model(inputs)
loss = criterion(outputs, target)
loss.backward()
optimizer.step()
running_loss += loss.item()
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()
NLLLoss 和 CrossEntropyLoss
NLLLoss 和 CrossEntropyLoss(也称为交叉熵损失)是深度学习中常用的两种损失函数,用于测量模型的输出与真实标签之间的差距,通常用于分类任务。它们有一些相似之处,但也有一些不同之处。
相同点:
用途:两者都用于分类任务,评估模型的输出和真实标签之间的差异,以便进行模型的训练和优化。
数学基础:NLLLoss 和 CrossEntropyLoss 本质上都是交叉熵损失的不同变种,它们都以信息论的概念为基础,衡量两个概率分布之间的相似度。
输入格式:它们通常期望模型的输出是一个概率分布,表示各个类别的预测概率,以及真实的标签。
不同点:
输入格式:NLLLoss 通常期望输入是对数概率(log probabilities),而 CrossEntropyLoss 通常期望输入是未经对数化的概率。在实际应用中,CrossEntropyLoss 通常与softmax操作结合使用,将原始模型输出转化为概率分布,而NLLLoss可以直接使用对数概率。
对数化:NLLLoss 要求将模型输出的概率经过对数化(取对数)以获得对数概率,然后与真实标签的离散概率分布进行比较。CrossEntropyLoss 通常在 softmax 操作之后直接使用未对数化的概率值与真实标签比较。
输出维度:NLLLoss 更通用,可以用于多种情况,包括多类别分类和序列生成等任务,因此需要更多的灵活性。CrossEntropyLoss 通常用于多类别分类任务。
总之,NLLLoss 和 CrossEntropyLoss 都用于分类任务,但它们在输入格式和使用上存在一些差异。通常,选择哪个损失函数取决于你的模型输出的格式以及任务的性质。如果你的模型输出已经是对数概率形式,通常使用NLLLoss,否则通常使用CrossEntropyLoss。
教你如何使用PyTorch解决多分类问题的更多相关文章
- pytorch解决鸢尾花分类
半年前用numpy写了个鸢尾花分类200行..每一步计算都是手写的 python构建bp神经网络_鸢尾花分类 现在用pytorch简单写一遍,pytorch语法解释请看上一篇pytorch搭建简单网 ...
- Keras入门(一)搭建深度神经网络(DNN)解决多分类问题
Keras介绍 Keras是一个开源的高层神经网络API,由纯Python编写而成,其后端可以基于Tensorflow.Theano.MXNet以及CNTK.Keras 为支持快速实验而生,能够把 ...
- 采用boosting思想开发一个解决二分类样本不平衡的多估计器模型
# -*- coding: utf-8 -*- """ Created on Wed Oct 31 20:59:39 2018 脚本描述:采用boosting思想开发一个 ...
- 03_利用pytorch解决线性回归问题
03_利用pytorch解决线性回归问题 目录 一.引言 二.利用torch解决线性回归问题 2.1 定义x和y 2.2 自定制线性回归模型类 2.3 指定gpu或者cpu 2.4 设置参数 2.5 ...
- 【笔记】二分类算法解决多分类问题之OvO与OvR
OvO与OvR 前文书道,逻辑回归只能解决二分类问题,不过,可以对其进行改进,使其同样可以用于多分类问题,其改造方式可以对多种算法(几乎全部二分类算法)进行改造,其有两种,简写为OvO与OvR OvR ...
- 官网安装Python包太慢?教你三种下载安装方式-PiP、conda、轮子,教你三种Pytorch的下载安装方式,保证你再也不用出现Error
上一期我们介绍了CUDA下载安装以及其总结,这一期教大家如何在Anaconda中使用CUDA来进行加速.神经网络依赖cuDNN的下载安装,以及下载和安装Pytorch-GPU安装包的三种方式(cond ...
- 动手造轮子自己实现人工智能神经网络(ANN),解决鸢尾花分类问题Golang1.18实现
人工智能神经网络( Artificial Neural Network,又称为ANN)是一种由人工神经元组成的网络结构,神经网络结构是所有机器学习的基本结构,换句话说,无论是深度学习还是强化学习都是基 ...
- SVM怎样解决多分类问题
从 SVM的那几张图能够看出来,SVM是一种典型的两类分类器.即它仅仅回答属于正类还是负类的问题.而现实中要解决的问题,往往是多类的问题(少部分例外,比如垃圾邮件过滤,就仅仅须要确定"是&q ...
- 使用条件随机场模型解决文本分类问题(附Python代码)
对深度学习感兴趣,热爱Tensorflow的小伙伴,欢迎关注我们的网站!http://www.tensorflownews.com.我们的公众号:磐创AI. 一. 介绍 世界上每天都在生成数量惊人的文 ...
- pytorch实现LeNet5分类CIFAR10
关于LeNet-5 LeNet5的Pytorch实现在网络上已经有很多了,这里记录一下自己的实现方法. LeNet-5出自于Gradient-Based Learning Applied to Doc ...
随机推荐
- Go中 net/http 使用
转载请注明出处: net/http是Go语言标准库中的一个包,提供了实现HTTP客户端和服务器的功能.它使得编写基于HTTP协议的Web应用程序变得简单和方便. net/http包的主要用途包括: 实 ...
- pandas对某列数据进行求和
求和的方式很简单,如下所示: number_of_declarations = data[4].sum()//中括号中为要求和的列
- Redis从入门到放弃(9):集群模式
前面文章我们介绍了Redis的主从模式是一种在Redis中实现高可用性的方式,但也存在一些缺点. 1.主从模式缺点 写入单点故障:在主从模式中,写入操作只能在主节点进行,如果主节点宕机,写入将无法执行 ...
- BUGKU逆向reverse 1-8题
练习IDA两年半 打开尘封已久的bugku,从题目中练习使用,现在都已经是新版本了 orz 入门逆向 运行baby.exe将解压后的baby.exe拖到IDA里面主函数中找到mov指令 可以看到这里就 ...
- python如何提取浏览器中保存的网站登录用户名密码
python如何提取Chrome中的保存的网站登录用户名密码? 很多浏览器都贴心地提供了保存用户密码功能,用户一旦开启,就不需要每次都输入用户名.密码,非常方便.作为python脚本,能否拿到用户提前 ...
- CodeForces 1174D Ehab and the Expected XOR Problem
题意: 给定两个数\(n\)和\(x\),构造一个序列,设为\(a[l]\)(\(l\)不确定) \(1\).\(1\leq a[i]<2^{n}\) \(2\).序列中没有子序列异或和为\(0 ...
- Binary String Copying
Smiling & Weeping ----第一次见你的时候, 在我的心里已经炸成了烟花, 需要用一生来打扫灰炉. 题目链接:Problem - C - Codeforces 题目大意不难,就 ...
- 618京东到家APP-门详页反爬实战
一.背景与系统安全需求分析 1. 系统的重要性 上图所示是接口所属位置.对电商平台或在线商店而言,分类查商品都是很重要的,通过为用户提供清晰的商品分类,帮助他们快速找到所需产品,节省浏览时间,提升购物 ...
- python基础:元组(tuple)列表(list)介绍
一,元组 1.元组的创建(可以把元组看作一个容器,任何数据类型都可以放在里面)通过赋值方法创建元组In [5]: t = ("hello",2.3,2,True,{1:" ...
- SK 简化流行编程语言对 生成式AI 应用开发的支持
Semantic Kernel[1] 是一个将大型语言模型(LLM)与流行的编程语言相结合的SDK. Microsoft将Semantic Kernel(简称SK)称为轻量级SDK,支持AI LLM的 ...