对于训练时loss出现负值的情况

这篇具有很好参考价值的文章主要介绍了对于训练时loss出现负值的情况。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

loss为负数,pytorch踩坑,计算机视觉,python,深度学习
在训练时候loss出现负值,就立马停下来分析一下原因在哪。最有可能是损失函数出现问题,开始只使用交叉熵损失时没有出现过,在加上了dice loss时就出现了问题。于是就去dice loss中寻找原因。
1:首先需要明白语义分割的GT,每一个像素点的值就是像素的类别。

# -*- coding: utf-8 -*-
import numpy as np
from torchvision import transforms
import torch
from PIL import Image
img = Image.open('C:/Users/翰墨大人/Desktop/0003_lable.png') #图像所在位置
img1 = np.array(img)
img1 = torch.from_numpy(img1).type(torch.FloatTensor)
# trans = transforms.ToTensor()
# img1 = trans(img1)

a = torch.unique(img1) # 查看图片内的像素值
print(a)
print(img.mode) # 查看图片模式

打印结果:

tensor([ 0.,  1.,  5.,  7.,  8., 26., 29., 38., 40.])
P

原图一共有四十个类别,在003_lable这张GT上只出现了上述的类别。剩下的像素点和上述像素点是重复的。
注意:
这里将np格式转换为tensor格式时候,不能使用transforms.ToTensor(),他会将像素值发生改变。这样新的像素值点和类别就不是一一对应的。

tensor([0.0000, 0.0039, 0.0196, 0.0275, 0.0314, 0.1020, 0.1137, 0.1490, 0.1569])
P

2:语义分割的GT一共有四十类,没有通道,而在模型中pred的输出为一个通道。
在计算二分类dice loss时候,首先要将pred进行sigmoid。GT是四十个类别,如果是二分类的话那么标签就必须是[0,1]。而loss为负值的原因就是没有将标签转换为[0,1]。
X是pred,Y是GT,分子就是X和Y进行矩阵的相乘再相加,当Y中含有大于1的类别,比如30,40的话,而X又是进过sigmoid之后再(0,1)之内,那么分子除以分母的值就会大于1,造成dice loss就变成了负值。
loss为负数,pytorch踩坑,计算机视觉,python,深度学习
如何将GT变为[0,1]呢?因为我需要的是对GT进行提边,使用一个拉普拉斯对GT进行卷积,然后再使用一个阈值,大于阈值为1,小于为0。为是边缘和不是边缘。GT就又灰度图像转换为了二值图像。

l = F.conv2d(x,sobel,padding=1,stride=1)
print(l.shape)
ll = torch.unique(l) # 查看图片内的像素值
print(ll)

l[l>0.1]=1
l[l<0.1]=0
l_ = torch.unique(l) # 查看图片内的像素值
print(l_)

结果:
loss为负数,pytorch踩坑,计算机视觉,python,深度学习
对于多分类的dice loss:
GT需要进行one-hot编码,这样一个通道,像素点为(0-40)的GT就会变为四十个通道,每个通道像素点为(0,1),每个通道都可以看做一个二分类问题,属于该类别和不属于该类别。而pred的输出通道也为40,通过计算pred的每个通道和GT的每个通道的loss,最后求均值得到总loss。
3:代码代码参考
单分类代码:

import torch
import torch.nn as nn

class BinaryDiceLoss(nn.Model):
	def __init__(self):
		super(BinaryDiceLoss, self).__init__()
	
	def forward(self, input, targets):
		# 获取每个批次的大小 N
		N = targets.size()[0]
		# 平滑变量
		smooth = 1
		# 将宽高 reshape 到同一纬度
		input_flat = input.view(N, -1)
		targets_flat = targets.view(N, -1)
	
		# 计算交集
		intersection = input_flat * targets_flat 
		N_dice_eff = (2 * intersection.sum(1) + smooth) / (input_flat.sum(1) + targets_flat.sum(1) + smooth)
		# 计算一个批次中平均每张图的损失
		loss = 1 - dice_eff.sum() / N
		return loss

多分类代码:文章来源地址https://www.toymoban.com/news/detail-802974.html

import torch
import torch.nn as nn

class MultiClassDiceLoss(nn.Module):
	def __init__(self, weight=None, ignore_index=None, **kwargs):
		super(MultiClassDiceLoss, self).__init__()
		self.weight = weight
		self.ignore_index = ignore_index
		self.kwargs = kwargs
	
	def forward(self, input, target):
		"""
			input tesor of shape = (N, C, H, W)
			target tensor of shape = (N, H, W)
		"""
		# 先将 target 进行 one-hot 处理,转换为 (N, C, H, W)
		nclass = input.shape[1]
		target = one_hot(target.long(), nclass)

		assert input.shape == target.shape, "predict & target shape do not match"
		
		binaryDiceLoss = BinaryDiceLoss()
		total_loss = 0
		
		# 归一化输出
		logits = F.softmax(input, dim=1)
		C = target.shape[1]
		
		# 遍历 channel,得到每个类别的二分类 DiceLoss
		for i in range(C):
			dice_loss = binaryDiceLoss(logits[:, i], target[:, i])
			total_loss += dice_loss
		
		# 每个类别的平均 dice_loss
		return total_loss / C

到了这里,关于对于训练时loss出现负值的情况的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • yolo系列算法训练时loss出现nan值,解决办法(GTX16xx系列显卡的问题)

    1.首先 这个问题时由于GTX16xx系列显卡导致的,只要是使用GTX16xx系列显卡跑yolo系列算法的时候基本上都会遇到这个问题,真是搞得我头大,当我第一次遇到这个问题的时候,我只是简单地认为是 学习率过大导致梯度爆炸 ,但是后来我上网查资料才发现问题出现在我的显卡上

    2023年04月26日
    浏览(47)
  • 为什么从没有负值的数据中绘制的小提琴图(Violin Plot)会出现负值部分?

    🍉 CSDN 叶庭云 : https://yetingyun.blog.csdn.net/ 小提琴图(Violin Plot) 是一种用于展示和比较数据分布的可视化工具。它结合了 箱形图 (Box Plot)和 密度图 (Kernel Density Plot)的特点:中间有箱形图表示四分位数和中位数,外围是密度估计曲线,显示数据分布的密度。这种设计旨

    2024年02月20日
    浏览(35)
  • YOLO系列训练时出现loss出现nan值或者测试时P\R\map全部为0值的解决办法(GTX16xx系列显卡大坑)

    目录 0 前言(用处不大,可以直接看解决办法) 1 产生问题的原因 2 解决办法 YOLO V5 YOLO V7 2 小结 ☆ 这个问题是GTX16xx用户的大坑,基本上每个GTX16xx用户使用YOLO系列算法,都会遇到这些问题。 这个方法 是不彻底的解决办法 ,牺牲了训练的时间来换取问题的解决,经过本人在

    2024年02月02日
    浏览(50)
  • RISC-V基础指令之addi与lui(生成一个更大的立即数,包含负数符号拓展的特殊情况)

    这两条指令都是RISC-V体系结构中的整数指令,它们的功能和格式如下: lui指令的全称是Load Upper Immediate,它的功能是把一个20位的立即数加载到寄存器的高20位,低12位为0。它的格式是: lui rd, imm 其中,rd是目标寄存器,imm是20位的立即数。例如,lui x1, 0x12345会把0x12345000加载到

    2024年02月11日
    浏览(40)
  • Pytorch训练过程中出现RuntimeError: falseINTERNAL ASSERT FAILED... Couldn‘t open shared file mapping...

    一句话:换成pytorch1.8。 今天跑一个开源的模型跑到第9个epoch时报错,如下: 遂搜索,同类问题比较少,有一个博客讲到是显卡性能问题。于是我尝试大幅降低batch_size和works,又跑了一遍,这次第3个epoch就报了同样的错误(我跑一个epoch要一小时)。 这时我就奇怪了,降低了

    2023年04月21日
    浏览(28)
  • 一行代码解决PyTorch训练模型时突然出现的For debugging consider passing CUDA_LAUNCH_BLOCKING=1报错

    一、问题描述         今天在调试模型的代码,然后代码一直运行得好好地,就突然出现了一下的错误: RuntimeError: CUDA error: invalid device ordinal CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect. For debugging consider passing CUDA_LAUNCH_BLOCK

    2024年02月02日
    浏览(45)
  • 【机器学习】验证集loss震荡(loss的其他问题) 训练深度学习模型loss为nan的原因

    训练过程中发现,train loss一直下降,train acc一直上升;但是val loss、val acc却一直震荡。loss一会上一会下,但是总体趋势是向下的。 “loss震荡但验证集准确率总体下降” 如何解决? 测试集准确率这样震荡是正常的吗? - 李峰的回答 - 知乎 很多经验:loss问题汇总(不收敛、

    2024年02月12日
    浏览(43)
  • 【损失函数:2】Charbonnier Loss、SSIM Loss(附Pytorch实现)

    下面介绍各个函数时,涉及到一下2变量,其含义如下:假设网络输入为x,输出为 y ‾ overline{text{y}}

    2024年02月02日
    浏览(60)
  • pytorch如何使用Focal Loss

    Focal loss 是 文章 Focal Loss for Dense Object Detection 中提出对简单样本的进行 decay 的一种损失函数。是对标准的 Cross Entropy Loss 的一种改进。 FL 对于简单样本(p比较大)回应较小的loss。 如论文中的图1, 在p=0.6时, 标准的 CE 然后又较大的 loss , 但是对于FL就有相对较小的loss回应

    2024年02月10日
    浏览(37)
  • 深度学习:Pytorch常见损失函数Loss简介

    此篇博客主要对深度学习中常用的损失函数进行介绍,并结合Pytorch的函数进行分析,讲解其用法。 L1 Loss计算预测值和真值的平均绝对误差。 L o s s ( y , y ^ ) = ∣ y − y ^ ∣ Loss(y,hat{y}) = |y-hat{y}| L oss ( y , y ^ ​ ) = ∣ y − y ^ ​ ∣ Pytorch函数: 参数: size_average (bool, optional) –

    2024年02月13日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包