YOLOv11-ultralytics-8.3.67部分代码阅读笔记-activation.py

activation.py

ultralytics\nn\modules\activation.py

目录

activation.py

1.所需的库和模块

2.class AGLU(nn.Module): 


1.所需的库和模块

# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
"""Activation modules."""

import torch
import torch.nn as nn

2.class AGLU(nn.Module): 

# 这段代码定义了一个名为 AGLU 的 PyTorch 神经网络模块,它实现了一种统一的激活函数。
# 定义了一个名为 AGLU 的类,继承自 PyTorch 的 nn.Module ,这是所有 PyTorch 神经网络模块的基类。通过继承 nn.Module , AGLU 可以像其他 PyTorch 模块一样被集成到更大的网络中,并且可以利用 PyTorch 提供的模块化功能,例如参数管理、梯度计算等。
class AGLU(nn.Module):
    # 统一激活函数模块来自https://github.com/kostas1515/AGLU。
    """Unified activation function module from https://github.com/kostas1515/AGLU."""

    # 定义了类的初始化方法 __init__ ,它接受两个可选参数。
    # 1.device :指定设备(如 CPU 或 GPU)。
    # 2.dtype :指定数据类型(如 torch.float32 或 torch.float64 )。
    # 这些参数允许用户在创建模块实例时指定模块的运行设备和数据类型。
    def __init__(self, device=None, dtype=None) -> None:
        # 初始化统一激活函数。
        """Initialize the Unified activation function."""
        # 调用了父类 nn.Module 的初始化方法。这是必要的步骤,确保继承自 nn.Module 的类能够正确初始化其内部结构,例如参数管理、梯度跟踪等功能。
        super().__init__()

        # torch.nn.Softplus(beta=1, threshold=20)
        # 在PyTorch中, nn.Softplus() 是 torch.nn 模块中定义的一个激活函数类,它实现了Softplus激活函数。Softplus函数是一个平滑的激活函数,通常用于神经网络中,以增加模型的非线性能力。
        # 参数 :
        # beta ( float , 可选) : 控制函数平滑程度的参数,默认为1。
        # threshold ( float , 可选): 函数的阈值,默认为20。当输入值大于这个阈值时,函数将直接返回输入值加上一个小常数,以避免数值溢出。
        # 功能 :
        # nn.Softplus() 函数的主要功能是为神经网络提供平滑的非线性激活,它在数学上定义为: Softplus(x) = log(1+e^x) 、 Softplus(x) = (1/β)·log(1+e^β·x) 。
        # 这个函数在整个实数域上都是平滑的,并且当输入值非常大时,它的输出接近于输入值本身,这使得它在某些情况下比ReLU函数更稳定。

        # 定义了一个名为 act 的属性,它是一个 nn.Softplus 激活函数实例。 Softplus 是一种平滑的 ReLU 替代品,其公式为 : Softplus(x) = log(1+e^x) 、 Softplus(x) = (1/β)·log(1+e^β·x) 。
        # 这里通过设置 beta=-1.0 ,对 Softplus 的行为进行了调整,但需要注意的是, Softplus 的 beta 参数通常为正数,因此这里的设置可能需要进一步验证其合理性。
        self.act = nn.Softplus(beta=-1.0)

        # torch.nn.init.uniform_(tensor, a=0.0, b=1.0)
        # torch.nn.init.uniform_() 是 PyTorch 中的一个函数,用于将输入张量的值初始化为均匀分布的随机数。这个函数通常用于神经网络的权重初始化,以帮助模型在训练开始时避免过大或过小的梯度。
        # 参数说明 :
        # tensor : 要初始化的张量,通常是神经网络中的权重。
        # a : 均匀分布的下界,默认为 0.0。
        # b : 均匀分布的上界,默认为 1.0。
        # 功能描述 :
        # uniform_() 函数会将输入张量的每个元素随机初始化为在 [a, b) 区间内的均匀分布的值。这个函数是一个就地操作(in-place operation),意味着它会直接修改输入张量,而不会返回一个新的张量。
        # 返回值 :
        # 返回输入张量本身,已被修改为均匀分布的随机值。
        # 注意事项 :
        # 使用均匀分布初始化时,确保选择合适的上下界 a 和 b ,以避免在训练过程中出现梯度消失或梯度爆炸的问题。
        # 在某些情况下,使用其他初始化方法(如 Xavier 初始化或 He 初始化)可能会更有效,具体取决于网络的架构和激活函数的选择。

        # torch.nn.Parameter(data, requires_grad=True)
        # 在PyTorch中, nn.Parameter 是一个特殊类型的张量,它会自动地被识别为模型的参数,这意味着它会被包含在模型参数的列表中,并且在模型训练时会被优化器自动更新。
        # 参数说明 :
        # data : 一个张量( torch.Tensor ),它将被包装成参数。
        # requires_grad : 一个布尔值,指示这个参数是否需要梯度。默认为 True ,即需要梯度。
        # 返回值 :
        # 返回一个 nn.Parameter 实例。
        # 基本用法 :
        # nn.Parameter 通常在定义模型的可学习参数时使用,比如权重和偏置。但是,它也可以用于定义需要梯度的中间变量。
        # 注意事项 :
        # nn.Parameter 通常与 nn.Module 一起使用,因为只有当 nn.Parameter 是 nn.Module 的属性时,它才会被自动识别为模型的参数。
        # 如果你将一个张量直接赋值给 nn.Module 的属性,而不是使用 nn.Parameter ,那么这个张量不会被识别为模型的参数,也不会在训练过程中被更新。
        # requires_grad 参数可以设置为 False 来防止计算某个参数的梯度,这在某些情况下可以减少内存消耗和计算量。

        # 定义了一个名为 lambd 的可训练参数。
        # torch.empty(1, device=device, dtype=dtype) 创建了一个形状为 (1,) 的张量,其设备和数据类型由 device 和 dtype 参数指定。
        # nn.init.uniform_ 用于将该张量初始化为均匀分布的随机值。
        # 最后,通过 nn.Parameter 将其包装为一个可训练参数,这意味着在训练过程中,该参数的值可以通过梯度下降进行更新。
        self.lambd = nn.Parameter(nn.init.uniform_(torch.empty(1, device=device, dtype=dtype)))  # lambda parameter
        # 定义了另一个可训练参数 kappa ,其初始化方式与 lambd 相同。这两个参数在激活函数的计算中起到关键作用,通过训练可以调整激活函数的 形状 和 行为 。
        self.kappa = nn.Parameter(nn.init.uniform_(torch.empty(1, device=device, dtype=dtype)))  # kappa parameter

    # 定义了模块的前向传播方法 forward 。 forward 方法是 PyTorch 模块的核心,它定义了输入张量 x 如何被转换为输出张量。输入参数 :
    # 1.x :是一个 PyTorch 张量。
    # 返回值也是一个 PyTorch 张量。
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # 计算统一激活函数的前向传递。
        """Compute the forward pass of the Unified activation function."""
        # 通过 torch.clamp 函数对参数 self.lambd 进行裁剪,确保其值不会小于 0.0001 。这是为了避免在后续计算中出现数值不稳定的状况,例如除以零的情况。
        lam = torch.clamp(self.lambd, min=0.0001)
        # 这是激活函数的核心计算公式。具体步骤如下 :
        # 计算 self.kappa * x ,即输入张量 x 与参数 kappa 的逐元素乘积。
        # 减去 torch.log(lam) ,即对上述结果减去 lam 的自然对数。
        # 将结果传递给 self.act ,即 Softplus 激活函数。
        # 最后,将结果乘以 (1 / lam) ,并取指数,得到最终的输出张量。
        # 不同的激活函数具有不同的数学形式和计算公式。 torch.exp((1 / lam) * self.act((self.kappa * x) - torch.log(lam))) 是一种特定的激活函数形式,它通过引入可训练参数 lambd 和 kappa ,以及使用 Softplus 函数,实现了一种灵活的激活函数。这种设计允许激活函数在训练过程中动态调整其形状和特性,但并不是所有激活函数都采用类似的复杂形式。常见的激活函数(如 ReLU、Sigmoid、Tanh 等)通常具有更简单的形式,适用于不同的应用场景。
        return torch.exp((1 / lam) * self.act((self.kappa * x) - torch.log(lam)))
# 这段代码实现了一个自定义的激活函数模块 AGLU ,它通过引入两个可训练参数 lambd 和 kappa ,以及使用 Softplus 激活函数,定义了一种灵活的激活函数形式。通过训练,这两个参数可以自动调整,使得激活函数能够适应不同的网络结构和任务需求。这种设计允许激活函数在训练过程中动态调整其形状和特性,从而提高模型的表达能力和适应性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红色的山茶花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值