python中pytorch框架loss函数配置

import torch.nn.modules

pre = net(data)
target = label

def loss_seg(pre, target, hnm_ratio=0, **kwargs):
    target = target.cuda(cfg.device_list[0])
    loss = torch.nn.modules.MSELoss()
    ls = loss(pre, target.float())
    return ls

这是一个计算分割损失的函数 loss_seg。它使用了 torch.nn.modules.MSELoss() 来计算均方误差损失。

首先,pre = net(data) 执行了神经网络模型 net 对输入数据 data 进行前向计算,并将结果赋值给变量 pre

然后,目标值 target 被赋值为变量 label

接下来,target = target.cuda(cfg.device_list[0]) 将目标值 target 移动到指定的 CUDA 设备上进行计算,其中 cfg.device_list[0] 是一个设备列表的索引,表示要使用的 CUDA 设备的索引。

接着,使用 torch.nn.modules.MSELoss() 创建了一个均方误差损失函数的实例,赋值给变量 loss

最后,ls = loss(pre, target.float()) 计算了预测值 pre 和目标值 target 之间的均方误差损失,并将结果赋值给变量 ls

最终,函数返回了计算得到的损失值 ls

请注意,这段代码假设 net 是一个已经定义并初始化的神经网络模型,data 是输入到模型的数据,label 是目标分割结果。确保正确配置和设置 CUDA 设备,并确保设备索引 cfg.device_list[0] 是有效的 CUDA 设备索引,否则代码将引发错误。

import torch.nn.modules

在日常使用中

在实际使用中,这两个模块都包含基本模块来构建自定义的神经网络模型。

Conv2dLinearBatchNorm2d等,可以直接使用这些层构建模型。

如损失函数、优化器、初始化方法等。当需要使用这些功能时,可以导入相应的类或函数,并进行调用。

比如torch.nn.modules.MSELoss()和torch.nn.MSELoss()点进去都是

target = label

target = target.cuda(cfg.device_list[0])

执行顺序:

1、先计算label的值(可能原先各种数据类型,但在pytorch中,我们都将会将其转换为张量tensor)

2、计算cfg.device_list[0],求出当前显卡设备编号

3、target.cuda(cfg.device_list[0])

label 是一个张量对象,通过调用 .cuda(...) 方法将其移动到指定的设备上进行计算。

  • 原理:.cuda(...) 方法是 PyTorch 提供的用于将张量移动到指定设备的方法。它接受一个设备标识符作为参数,将张量复制到指定的设备上。

  • 内容:该方法会将 label 张量的数据和梯度(如果存在)复制到指定设备上的显存中。

  • 目的:将 label 张量移动到特定的设备上,以便在该设备上进行后续的计算和操作。

loss = torch.nn.modules.MSELoss()

ls = loss(pre, target.float())

其实可以一步写为

loss = torch.nn.modules.MSELoss(pre, target.float())

torch.nn.modules.MSELoss()与torch.nn.MSELoss()基本相同

torch.nn.modules.MSELoss()是一个类,用于创建均方误差(Mean Squared Error,MSE)损失函数的实例。

  • 均方误差损失函数衡量了模型输出与目标值之间的差异的平方和的平均值。
  • 在回归问题中,通常使用均方误差作为损失函数,用于衡量模型输出与真实目标值之间的差异。
  • 这个损失函数计算的结果越小,表示模型的输出越接近目标值。
  • 均方误差损失函数的计算公式为:MSE = (1/n) * Σ(y - y_hat)^2,其中 y 是真实目标值,y_hat 是模型的预测值,n 是样本数量。

使用 torch.nn.modules.MSELoss() 可以创建一个均方误差损失函数的实例,用于计算模型输出和目标值之间的均方误差损失。

import torch
import torch.nn as nn

# 创建均方误差损失函数实例
criterion = nn.MSELoss()

# 模型输出
output = torch.tensor([0.5, 0.8, 1.2])
# 目标值
target = torch.tensor([1.0, 0.7, 1.5])

# 计算损失
loss = criterion(output, target)

print(loss)  # 打印损失值

关于函数或方法的返回类型注解介绍

def add_numbers(a: int, b: int) -> int:
    return a + b

-> 符号在代码中通常表示函数或方法的返回类型注解。它用于指示函数或方法返回的数据类型。

在Python中,类型注解是一种静态类型检查的工具,用于提供变量、参数和函数的类型信息,以便在开发过程中进行类型检查和预测。

在函数或方法定义的参数列表后面使用 -> 符号,可以指定函数或方法的返回类型。这样做可以提供更多的代码可读性,并帮助开发者理解函数的预期行为和返回结果的类型。

在这个例子中,-> int 表示 add_numbers 函数返回的结果应该是一个整数。

请注意,类型注解只是一种静态检查的辅助工具,Python 解释器在运行时并不会对类型注解进行强制检查。它们主要用于提供给静态类型检查器(如 Mypy)使用,或者作为代码文档的一部分,以帮助开发者理解代码的含义和预期行为。

import torch.nn.modules

pre = net(data)

target = label

loss = torch.nn.modules.MSELoss(pre, target.float())

点进函数内部

class MSELoss(_Loss):
    __constants__ = ['reduction']
    def __init__(self, size_average=None, reduce=None, reduction: str = 'mean') -> None:
        super(MSELoss, self).__init__(size_average, reduce, reduction)
    def forward(self, input: Tensor, target: Tensor) -> Tensor:
        return F.mse_loss(input, target, reduction=self.reduction)

其中看到其是继承于_Loss,再深层点入

from torch.nn.modules import Module
class _Loss(Module):
    reduction: str
    def __init__(self, size_average=None, reduce=None, reduction: str = 'mean') -> None:
        super(_Loss, self).__init__()
        if size_average is not None or reduce is not None:
            self.reduction: str = _Reduction.legacy_get_string(size_average, reduce)
        else:
            self.reduction = reduction

reduction: str

在代码中使用 : 的主要目的是进行类型注解或变量声明

在类型注解中,: 用于指示变量、参数或函数返回的数据类型。这样做可以提供更多的代码可读性,并帮助开发者理解变量的类型以及函数的预期行为。

代表声明一个变量,变量名为reduction,数据类型为str

使用 : 进行类型注解或变量声明可以提高代码的可读性和可维护性,尤其是在大型项目中或与他人共享代码时。它可以帮助开发者更清晰地理解代码的含义和预期行为,并在编译器或静态类型检查器中进行类型验证。

在给变量 reduction 进行类型注解时,将其单独占一行是为了提高代码的可读性和清晰度。将类型注解单独放在一行上可以使代码更加清晰,易于理解变量的类型。

将其放在单独的行上有助于提高代码的可读性和维护性,特别是在复杂的代码中或与其他人合作开发时。

这里的 reduction 是一个自定义的变量名,用于表示损失函数的缩减方式。str 表示该变量的数据类型为字符串。

在 PyTorch 中,损失函数通常会计算出一系列的损失值,而缩减方式用于将这些损失值聚合成一个标量值(单个数值)。

常见的缩减方式包括:

  • 'mean':计算损失值的平均值。
  • 'sum':计算损失值的总和。
  • 'none':不进行缩减,保留每个样本的损失值。

通过设置 reduction 的值,可以指定损失函数的缩减方式,以满足具体应用的需求。

def __init__(self, size_average=None, reduce=None, reduction: str = 'mean') -> None:

构造函数的返回类型注解指定为 None,表示该构造函数没有返回值。

  • size_average 和 reduce 参数的默认值都是 None,这意味着它们是可选参数。通过指定这两个参数的值,可以控制损失函数的缩减方式。

  • reduction 参数是一个字符串类型的参数,并且它的默认值是 'mean'。这意味着,如果没有显式地提供 reduction 参数的值,它将默认为 'mean'

_Reduction.legacy_get_string也是模型定义的方法

def legacy_get_string(size_average: Optional[bool], reduce: Optional[bool], emit_warning: bool = True) -> str:
    warning = "size_average and reduce args will be deprecated, please use reduction='{}' instead."

    if size_average is None:
        size_average = True
    if reduce is None:
        reduce = True

    if size_average and reduce:
        ret = 'mean'
    elif reduce:
        ret = 'sum'
    else:
        ret = 'none'
    if emit_warning:
        warnings.warn(warning.format(ret))
    return ret

在 Python 中,Optional[T] 表示参数或变量的类型可以是类型 T,或者是 None。其中,T 是一个占位符,可以是任何有效的类型。

返回类型注解 -> str 表示该函数的返回值是一个字符串类型。

import warnings
emit_warning: bool = True
warning = "size_average and reduce args will be deprecated, please use reduction='{}' instead."
if emit_warning: 
warnings.warn(warning.format(ret)) 
return ret

warning.format(ret)中,warning是一个字符串

warning.format(ret) 是一个字符串格式化操作,用于将字符串 warning 中的占位符 {} 替换为变量 ret 的值。

加下来看计算损失的函数

import torch.nn.functional as F
def forward(self, input: Tensor, target: Tensor) -> Tensor:
    return F.mse_loss(input, target, reduction=self.reduction)

也就是;利用

torch.nn.functional.mse_loss(input, target, reduction=self.reduction)