深度学习-多分类
文章目录
- 多分类
- one_hot编码
- 编码原理
- 交叉熵损失函数
- 示例
- 实战案例基于mnnist的手写识别
- TensorBoard的使用
- 部分代码解释
多分类
- 输出是每个类别的概率,要求有多少个分类最终的输出层就有多少个神经元
- 各分类输出概率的总和是1(使用softmax归一化)
one_hot编码
One-Hot 编码是机器学习中处理分类数据的核心技术,它将离散类别转换为向量表示,使其能被神经网络处理。
一句话:在一个样本中:n个分类,结果是第k个,则yone-hot=[0,⋯,1⏟第k位,⋯,0]y_{\text{one-hot}} = [0, \cdots, \underbrace{1}_{\text{第k位}}, \cdots, 0]yone-hot=[0,⋯,第k位1,⋯,0]
编码原理
对于一个包含 C 个类别的特征:
- 创建长度为 C 的零向量
- 对第 k 类数据,将其向量中第 k 个位置设为 1
- 其余位置保持为 0
yone-hot=[0,⋯,1⏟第k位,⋯,0]y_{\text{one-hot}} = [0, \cdots, \underbrace{1}_{\text{第k位}}, \cdots, 0]yone-hot=[0,⋯,第k位1,⋯,0]
假设动物分类的类别为:[“狗”, “猫”, “鸟”]
类别 One-Hot 编码
狗 [1, 0, 0]
猫 [0, 1, 0]
鸟 [0, 0, 1]
交叉熵损失函数
一句话:在H(y,pi)=−∑xylogpiH(y,p_i)=-\sum_{x}y\log p_iH(y,pi)=−∑xylogpi中,只有一条1*log(pi)为最终交叉熵损失函数值,其它都是0*log(pi)=0
交叉熵损失函数与逻辑回归中的损失函数效果相同,都是为如何调整参数指明方向,即通过求取梯度,调整参数使损失函数的值逼近0,只是交叉熵损失函数用在多分类中
L(y^,y)=−ylog(y^)−(1−y)log(1−y^)L(\hat{y}, y) = - y \log(\hat{y}) - (1 - y) \log(1 - \hat{y}) L(y^,y)=−ylog(y^)−(1−y)log(1−y^)
交叉熵损失函数
H(y,pi)=−∑xylogpiH(y,p_i)=-\sum_{x}y\log p_iH(y,pi)=−x∑ylogpi
yi:是真实标签(真实分布),通常采用one−hot编码(真实类别为1,其余为0)y_i:是真实标签(真实分布),通常采用one-hot编码(真实类别为1,其余为0)yi:是真实标签(真实分布),通常采用one−hot编码(真实类别为1,其余为0)
(乘的时候按类,分开乘了,0*log or 1*log ,单个样本,最终结果取决于那个唯一的1*log的值)
pi:是预测概率(模型输出的概率分布)p_i:是预测概率(模型输出的概率分布)pi:是预测概率(模型输出的概率分布)
log(pi):是预测概率的对数值\log(p_i):是预测概率的对数值log(pi):是预测概率的对数值
整体计算:是真实标签yi与预测概率对数log(pi)的乘积再求和取负整体计算:是真实标签y_i与预测概率对数\log(p_i)的乘积再求和取负整体计算:是真实标签yi与预测概率对数log(pi)的乘积再求和取负
示例
- L=0.357 表示当前预测不够准确(理想值应接近0)
- Log的底数无所谓,经过训练,任何底数的结果都是相同的
log(x)
实战案例基于mnnist的手写识别
TensorBoard的使用
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter(comment='test_tensorboard') # 用于记录要可视化的数据
#writer = SummaryWriter(存放的地址)
如果不指定绝对路径,PyTorch 默认创建runs在当前文件夹下
在你安装TensorBoard的虚拟py环境中运行以下代码即可
tensorboard --logdir="这个event文件所在目录的绝对地址"
部分代码解释
import torch
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from torchvision.datasets import MNIST
import matplotlib.pyplot as plt
import os
import numpy as np
from datetime import datetime
import os
log_dir = "runs"
os.makedirs(log_dir, exist_ok=True)
创建一个名为runs的文件夹
import matplotlib.pyplot as plt
writer = SummaryWriter(log_dir=log_subdir)
记录数据便于后续画图
3.定义网络基本框架
class SoftmaxRegression(torch.nn.Module):#括号中的 torch.nn.Module 表示你的 SoftmaxRegression 类 继承自 PyTorch 的 Module 基类def __init__(self): #self 指代 当前类的实例对象(即正在创建的具体模型)super().__init__()# 单层网络结构:784输入 -> 10输出self.linear = torch.nn.Linear(28 * 28, 10)#定义了这个网络的基本结构,有784个输入特征,10个输出def forward(self, x):# 应用log_softmax到线性层输出return torch.nn.functional.log_softmax(self.linear(x), dim=1)
log_softmax(self.linear(x), dim=1)相当于两步
softmax_output = exp(z_i) / sum(exp(z_j)) # 转换为概率分布
log_softmax = log(softmax_output) # 取自然对数
torch.nn.functional.log_softmax(self.linear(x), dim=1),dim=1
im=0:跨样本操作(通常不需要)(每个样本的第n类概率加起来为1)
dim=1:跨类别操作(分类任务的标准做法)(每个样本的n个类的各个概率加起来为1)
在这个模型中没有隐藏层,这是一个单层神经网络(也称为 Softmax 回归或多元逻辑回归),是直接从784个输出特征到,输出层的十个输出神经元
4.加载训练数据
def get_data_loader(is_train, batch_size=128):transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,)) # MNIST的均值和标准差])dataset = MNIST(root='./data', train=is_train, download=True, transform=transform)return DataLoader(dataset, batch_size=batch_size, shuffle=is_train, pin_memory=True)