游侠的博客 游侠的博客
首页
  • 论文笔记
  • 一些小知识点

    • pytorch、numpy、pandas函数简易解释
  • 《深度学习500问》
开发
技术
更多
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Ranger

一名在校研究生
首页
  • 论文笔记
  • 一些小知识点

    • pytorch、numpy、pandas函数简易解释
  • 《深度学习500问》
开发
技术
更多
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 论文笔记

  • 一些小知识点

    • pytorch、numpy、pandas函数简易解释【持续更新ing】
    • BatchNorm和LayerNorm的区别
    • 监督学习步骤
    • 分类算法的评价指标
    • 生成模型判别模型区别
    • 常见损失函数及说明
    • LDA与PCA降维方法
    • nn.Sequential作用
    • one-hot编码
    • python中的zip函数
    • 关于nn.CrossEntropyLoss的一些小说明
      • 遇见的问题
      • 原因
      • 结论
      • 2023.5.29日更新补充
    • 关于使用全局平均池化需要注意的地方
    • L2正则化、归一化、范数
  • 《深度学习500问》

  • pytorch知识点

  • 人工智能
  • 一些小知识点
yangzhixuan
2023-03-06
目录

关于nn.CrossEntropyLoss的一些小说明

# 遇见的问题

有一天在做一个分类任务实验的时候,发现损失一直降不下去,一直在零点几到一之间徘徊,好嘛,不调试不知道,一调试吓一跳 在验证集上的预测输出完全是正确的,但损失居然不为0,最后一查才发现是nn.CrossEntropyLoss()的问题

# 原因

nn.CrossEntropyLoss()不是单纯的一个交叉熵损失函数,而是多个函数的叠加,它的计算公式自然也发生了改变

它的计算流程如下:

先创建数据:

import torch.nn as nn
import torch

x = torch.rand((3,3))
y = torch.tensor([0,1,1])

#x的值
#tensor([[0.7459, 0.5881, 0.4795],
#        [0.2894, 0.0568, 0.3439],
#        [0.6124, 0.7558, 0.4308]])

#y的值
#tensor([0, 1, 1])
1
2
3
4
5
6
7
8
9
10
11
12
13
  1. 先经过softmax函数,求出每个类别的概率值,取值在0-1之间
 softmax = nn.Softmax()
x_softmax = softmax(x)

#x_softmax
>>>tensor([[0.3817, 0.3259, 0.2924],
        [0.3511, 0.2782, 0.3707],
        [0.3346, 0.3863, 0.2791]])
1
2
3
4
5
6
7
  1. 再经过log函数,取对数,原来的变化趋势保持不变,但所有值都会变成负的,原来概率大的,成为负值也大,但是它取绝对值后就是最小的,我们想要的是最小损失,正好贴合
 x_log = torch.log(x_softmax)

>>>tensor([[-0.9632, -1.1211, -1.2297],
        [-1.0468, -1.2794, -0.9923],
        [-1.0947, -0.9512, -1.2762]])
1
2
3
4
5

上边两步其实可以用函数nn.LogSoftmax代替,可以看出两个结果相同

ls = nn.LogSoftmax(dim=1)
ls(x)

>>>tensor([[-0.9632, -1.1211, -1.2297],
        [-1.0468, -1.2794, -0.9923],
        [-1.0947, -0.9512, -1.2762]])
1
2
3
4
5
6
  1. 最后使用nn.NLLLoss函数(负对数似然损失函数)求损失

公式:

image

自己实现:

loss = x_log[range(len(x)),y]  #取出每一个样本标签值处的概率
loss = abs(sum(loss)/len(x))

#loss
>>>tensor(1.0646)
1
2
3
4
5

使用torch中的函数:

loss_func = nn.NLLLoss()
loss_func(x_log,y)

>>>tensor(1.0646)
1
2
3
4

可以看到结果是一样的

直接使用nn.CrossEntropyLoss进行验证:

loss_func = nn.CrossEntropyLoss()
loss_func(x,y)

>>>tensor(1.0646)
1
2
3
4

# 结论

CrossEntropyLoss的计算公式如下:

image

所以说,使用CrossEntropyLoss的话,就不要在网络后面加softmax层了,这样会导致计算的损失不正确

# 2023.5.29日更新补充

使用CrossEntropyLoss时,数据集里的标签要从0开始,从1开始的话会出现越界问题

编辑 (opens new window)
上次更新: 2024/05/30, 07:49:34
python中的zip函数
关于使用全局平均池化需要注意的地方

← python中的zip函数 关于使用全局平均池化需要注意的地方→

最近更新
01
tensor比较大小函数
05-30
02
Large Language Models can Deliver Accurate and Interpretable Time Series Anomaly Detection
05-27
03
半监督学习经典方法 Π-model、Mean Teacher
04-10
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Ranger | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式