当前位置: 首页 > article >正文

YOLOv9-0.1部分代码阅读笔记-activations.py

activations.py

utils\activations.py

目录

activations.py

1.所需的库和模块

2.class SiLU(nn.Module): 

3.class Hardswish(nn.Module): 

4.class Mish(nn.Module): 

5.class MemoryEfficientMish(nn.Module): 

6.class FReLU(nn.Module): 

7.class AconC(nn.Module): 

8.class MetaAconC(nn.Module): 


1.所需的库和模块

import torch
import torch.nn as nn
import torch.nn.functional as F

2.class SiLU(nn.Module): 

# 这段代码定义了一个名为 SiLU 的类,它是一个 PyTorch 神经网络模块,实现了 SiLU(Sigmoid Linear Unit)激活函数。SiLU 激活函数是一种自门控激活函数,它将输入 x 与其通过 sigmoid 函数的输出相乘。
# 定义一个名为 SiLU 的类,它继承自 nn.Module ,这是 PyTorch 中所有神经网络模块的基类。
class SiLU(nn.Module):
    # SiLU activation https://arxiv.org/pdf/1606.08415.pdf    Swish‌
    # 在 SiLU 类中定义了一个静态方法 forward ,它接受一个参数。
    # @staticmethod 装饰器表示 forward 方法是一个静态方法,这意味着它不需要访问类的实例或类变量。
    @staticmethod
    # 1.x :代表输入的张量。这个方法实现了 SiLU 激活函数的前向传播逻辑。
    def forward(x):
        # torch.sigmoid(x) 计算输入张量 x 的 sigmoid 值,sigmoid 函数将输入值映射到 (0, 1) 区间。
        # x * torch.sigmoid(x) 将输入张量 x 与其 sigmoid 值相乘,得到 SiLU 激活函数的输出。
        return x * torch.sigmoid(x)
# SiLU 激活函数在某些深度学习模型中被用作 ReLU 的替代品,因为它在正负输入值上都具有非线性激活的特性。
# 自门控激活函数(Self-Gated Activation Function)是一种特殊的激活函数,它能够根据输入数据自身的情况来动态调整信息的流动。这种激活函数通常包含一个门控机制,可以控制信号的通过与否,类似于神经生物学中的神经元门控。
# 自门控激活函数的优点包括 :
# 平滑性和非线性 :自门控激活函数通常具有平滑的曲线,能够为神经网络提供非线性激活。
# 动态调整 :门控机制可以根据输入数据动态调整激活值,这有助于网络更好地学习和表示数据。
# 减少梯度消失问题 :由于自门控激活函数在正输入时输出接近输入值,这有助于缓解梯度消失问题,尤其是在深层网络中。
# 提高模型性能 :在某些情况下,自门控激活函数能够提高模型的性能,尤其是在处理复杂或非线性数据时。
# 自门控激活函数在深度学习模型中得到了广泛的应用,尤其是在那些需要精细控制信息流的场景中。

3.class Hardswish(nn.Module): 

# 这段代码定义了一个名为 Hardswish 的类,它是一个 PyTorch 神经网络模块,实现了 Hardswish 激活函数。Hardswish 是 SiLU(Sigmoid Linear Unit)激活函数的一种近似形式,它使用更简单的函数来近似 sigmoid 函数,以便于在某些硬件上更高效地执行。
# 定义一个名为 Hardswish 的类,它继承自 nn.Module ,这是 PyTorch 中所有神经网络模块的基类。
class Hardswish(nn.Module):
    # Hard-SiLU activation
    # 在 Hardswish 类中定义了一个静态方法 forward ,它接受一个参数 。这个方法实现了 Hardswish 激活函数的前向传播逻辑。
    @staticmethod
    # 1.x :代表输入的张量。
    def forward(x):
        # 这是 Hardswish 的标准形式,其中 F.hardsigmoid 是 PyTorch 中的硬 sigmoid 函数,它是一个近似 sigmoid 函数。
        # return x * F.hardsigmoid(x)  # for TorchScript and CoreML
        # 这是另一种 Hardswish 的实现方式,其中 F.hardtanh 是 PyTorch 中的硬 tanh 函数,它是一个近似 tanh 函数。
        # 在这个实现中, hardtanh 函数的输入是 x + 3 ,范围是 [0.0, 6.0] ,输出后再除以 6.0,以匹配 Hardswish 的行为。
        # 这种形式适用于 TorchScript、CoreML 和 ONNX。
        return x * F.hardtanh(x + 3, 0.0, 6.0) / 6.0  # for TorchScript, CoreML and ONNX
# Hardswish 激活函数因其计算效率和在某些模型中的性能优势而被使用。它在硬件上实现时可以避免昂贵的 sigmoid 计算,从而提高模型的运行速度。

4.class Mish(nn.Module): 

# 这段代码定义了一个名为 Mish 的类,它是一个 PyTorch 神经网络模块,实现了 Mish 激活函数。Mish 是一种自门控的非单调激活函数,它结合了软softplus和双曲正切(tanh)函数的特性。
# 定义一个名为 Mish 的类,它继承自 nn.Module ,这是 PyTorch 中所有神经网络模块的基类。
class Mish(nn.Module):
    # Mish activation https://github.com/digantamisra98/Mish
    # 在 Mish 类中定义了一个静态方法 forward ,它接受一个参数。这个方法实现了 Mish 激活函数的前向传播逻辑。
    @staticmethod
    # 1.x :代表输入的张量。
    def forward(x):
        # 在 forward 方法中,实现了 Mish 激活函数的计算。
        # F.softplus(x) :计算输入张量 x 的软plus值。软plus函数定义为 log(1 + exp(x)) ,它是一个平滑的、非负的、并且对于所有输入值都是非饱和的(即不会完全死亡或完全激活)激活函数。
        # .tanh() :计算软plus函数输出的双曲正切值。双曲正切函数将输入值映射到 (-1, 1) 区间内。
        # x * ... :将输入张量 x 与软plus和tanh的组合结果相乘,得到 Mish 激活函数的输出。
        return x * F.softplus(x).tanh()
# Mish 激活函数因其在某些深度学习模型中提供的性能优势而被使用,尤其是在图像分类和自然语言处理任务中。它被认为是一种通用的激活函数,可以在多种不同的网络架构和任务中提供良好的性能。

5.class MemoryEfficientMish(nn.Module): 

# 这段代码定义了一个名为 MemoryEfficientMish 的类,它是 PyTorch 的 nn.Module 的子类,实现了一个内存高效的 Mish 激活函数。这个实现通过自定义的 torch.autograd.Function 来减少中间结果的存储,从而降低内存消耗。
# 定义一个名为 MemoryEfficientMish 的类,继承自 nn.Module 。
class MemoryEfficientMish(nn.Module):
    # Mish activation memory-efficient    Mish 激活内存高效。
    # 嵌套类 F 。
    # 在 MemoryEfficientMish 类中定义了一个嵌套类 F ,它继承自 torch.autograd.Function 。这个类用于定义 Mish 激活函数的前向和后向传播。
    class F(torch.autograd.Function):
        # ctx 在 torch.autograd.Function 中的使用是为了保持无状态的设计,提供上下文传递的机制,以及确保与 PyTorch 自动微分系统的兼容性。这是 PyTorch 设计自定义操作的标准方式,允许高效的梯度计算和内存管理。

        # 这段代码是 MemoryEfficientMish 类中嵌套的 F 类的一个静态方法,它实现了 Mish 激活函数的前向传播逻辑。
        # 前向传播方法定义。
        # 定义了一个静态方法 forward ,它接受两个参数。
        @staticmethod
        # 1.ctx :是一个上下文对象,用于在前向和后向传播之间保存信息。
        # 2.x :是输入的张量。
        def forward(ctx, x):
            # 保存输入。
            # 在前向传播中,使用 ctx.save_for_backward(x) 保存输入张量 x 。这个保存的操作是为了在后向传播时能够访问到输入张量,而不需要在计算图中显式地保存它,从而减少内存的使用。
            ctx.save_for_backward(x)
            # 计算 Mish 激活函数。计算 Mish 激活函数的前向传播结果。Mish 激活函数定义为输入 x 与其 Softplus 函数的双曲正切的乘积,即 :Misn(x) = x · tanh(Softplus(x))
            # F.softplus(x) 计算 Softplus 函数, torch.tanh(...) 计算双曲正切函数。 x.mul(...) 是 PyTorch 中的元素级乘法操作,它将输入 x 与 Softplus 和 tanh 的组合结果相乘,得到最终的 Mish 激活函数的输出。
            return x.mul(torch.tanh(F.softplus(x)))  # x * tanh(ln(1 + exp(x)))
        # 这个方法实现了 Mish 激活函数的前向传播,并且通过 ctx.save_for_backward(x) 保存了输入张量,以便在后向传播时使用,而不需要额外的内存来存储这些中间结果。这样的实现对于内存效率是有益的,特别是在处理大规模数据或深度网络时。

        # 这段代码是 MemoryEfficientMish 类中嵌套的 F 类的另一个静态方法,它实现了 Mish 激活函数的反向传播逻辑。
        # 反向传播方法定义
        # 定义了一个静态方法 backward ,它接受两个参数。
        @staticmethod
        # 1.ctx :是一个上下文对象,用于在前向和后向传播之间保存信息。
        # 2.grad_output :是输出梯度,即对输出的损失函数关于 Mish 激活函数输出的导数。
        def backward(ctx, grad_output):
            # 恢复保存的输入。从 ctx 中恢复在前向传播时保存的输入张量 x 。
            x = ctx.saved_tensors[0]
            # 计算 Sigmoid 和 Softplus 及其双曲正切。计算输入 x 的 Sigmoid 值 sx ,以及 x 的 Softplus 值的双曲正切 fx 。这些值将用于后向传播的梯度计算。
            sx = torch.sigmoid(x)
            fx = F.softplus(x).tanh()
            # 计算后向传播的梯度。计算后向传播的梯度。Mish 激活函数的导数可以通过链式法则计算得到,这里使用了以下公式 :d(Misn(x))/dx = tanh(Softplus(x)) + x·σ(x)·(1-tanh^2(Softplus(x)))
            # fx 是 tanh(Softplus(x)) ,即 Mish 激活函数的第一部分。 sx 是 sigmoid(x)  ,即 Sigmoid 函数的输出。
            # x * sx * (1 - fx * fx) 是 Mish 激活函数的第二部分,它考虑了 x 与 Sigmoid 输出的乘积,以及 tanh(Softplus(x)) 的平方项的调整。
            # 将这两部分相加,然后乘以 grad_output ,得到最终的梯度。
            return grad_output * (fx + x * sx * (1 - fx * fx))
        # 这个方法实现了 Mish 激活函数的后向传播,计算了对输入 x 的损失函数的导数。这种实现允许 Mish 激活函数在 PyTorch 的自动微分系统中工作,同时保持了计算的准确性和内存效率。通过这种方式,Mish 激活函数可以被集成到更复杂的神经网络模型中,而不必担心内存消耗问题。

    # 这段代码是 MemoryEfficientMish 类中的 forward 方法的定义,它用于执行 Mish 激活函数的前向传播。
    # 定义了一个名为 forward 的实例方法,它接受一个参数。
    # 1.x :代表输入的张量。
    # 这个方法是 nn.Module 的子类中的标准方法,用于定义模块的前向传播逻辑。
    def forward(self, x):
        # 调用自定义函。在 forward 方法中,调用了嵌套类 F 的 apply 方法,并传入输入张量 x 。 self.F 是 MemoryEfficientMish 类中定义的 F 类的一个实例, apply 方法是 torch.autograd.Function 的一个特殊方法,用于执行自定义函数的前向和后向传播。
        # 工作原理 :
        # 当 apply 方法被调用时,它首先执行 F 类中定义的 forward 静态方法,这是自定义函数的前向传播逻辑。
        # 在前向传播过程中,如果需要计算梯度(即在训练模式下),PyTorch 会自动调用 F 类中定义的 backward 静态方法,这是自定义函数的后向传播逻辑。
        return self.F.apply(x)

6.class FReLU(nn.Module): 

# 这段代码定义了一个名为 FReLU 的类,它是一个 PyTorch 神经网络模块,实现了 Funnel Activation(FReLU),这是一种用于图像识别任务的激活函数。FReLU 是 ReLU 和 PReLU 的扩展,通过添加一个微不足道的空间条件来实现 2D 激活。
# 定义一个名为 FReLU 的类,它继承自 nn.Module ,这是 PyTorch 中所有神经网络模块的基类。
class FReLU(nn.Module):
    # FReLU activation https://arxiv.org/abs/2007.11824
    # 构造函数。 FReLU 类的构造函数接受两个参数。
    # 1.c1 :输入通道数。
    # 2.k :卷积核大小,默认为 3。
    def __init__(self, c1, k=3):  # ch_in, kernel
        # 调用父类 nn.Module 的构造函数以初始化模块。
        super().__init__()
        # 定义一个 nn.Conv2d 卷积层,用于实现空间条件。这个卷积层有 c1 个输入和输出通道,卷积核大小为 k  x  k ,步长为 1,填充为 1,分组卷积(groups=c1)以保持通道独立,且没有偏置项(bias=False)。
        self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False)
        # 定义一个 nn.BatchNorm2d 批量归一化层,用于归一化卷积层的输出。
        self.bn = nn.BatchNorm2d(c1)

    # 前向传播方法。定义 FReLU 类的 forward 方法,它接受一个参数。 forward 方法实现了 FReLU 激活函数的前向传播逻辑。
    # 1.x :代表输入的张量。
    def forward(self, x):
        # 计算空间条件 self.bn(self.conv(x)) ,其中 self.conv(x) 通过卷积层计算空间条件, self.bn 对卷积输出进行归一化。
        # 使用 torch.max(x, self.bn(self.conv(x))) 计算 FReLU 激活函数的输出,这相当于对每个像素位置,取输入 x 和空间条件 self.bn(self.conv(x)) 的最大值。
        return torch.max(x, self.bn(self.conv(x)))
# FReLU 是一个元素级的激活函数。
# 元素级(Element-wise)激活函数是指那些对输入张量中每个元素(或称为像素、单元等)单独应用的激活函数。这类激活函数不涉及跨元素的操作,如卷积或池化等,而是独立地对每个元素进行计算。
# 以下是一些常见的元素级激活函数:
# ReLU (Rectified Linear Unit) : ReLU 函数将所有负值置为 0,而保持正值不变。
#  Leaky ReLU : Leaky ReLU 允许负值通过一个较小的斜率,避免完全死亡的问题。
# PReLU (Parametric ReLU) : PReLU 是 ReLU 的一个变种,其中负值的斜率是一个可学习的参数。
# Sigmoid : Sigmoid 函数将输入压缩到 (0, 1) 区间内。
# Tanh (Hyperbolic Tangent) : Tanh 函数将输入压缩到 (-1, 1) 区间内。
# Softplus : Softplus 函数是 ReLU 的平滑版本,对所有输入值都是非负的。
# Mish : Mish 是一种自门控的非单调激活函数,结合了 Softplus 和 tanh 的特性。
# Swish : Swish 是一种由 Google 提出的自门控激活函数,其中 σ(x) 是 Sigmoid 函数。
# 这些激活函数通常用于神经网络中,以引入非线性,帮助网络学习复杂的函数映射。元素级激活函数因其简单和高效而在深度学习中被广泛使用。它们可以直接应用于输入张量的每个元素,而不需要考虑元素之间的空间关系,这使得它们在计算上非常高效。

7.class AconC(nn.Module): 

# 这段代码定义了一个名为 AconC 的类,它是一个 PyTorch 神经网络模块,实现了一种自适应的激活函数,称为 AconC(Adaptive Concatenation)。这个激活函数通过结合两个可学习的参数 p1 和 p2 ,以及一个可学习的缩放因子 beta ,来动态调整输入特征 x 。
# 定义一个名为 AconC 的类,它继承自 nn.Module ,这是 PyTorch 中所有神经网络模块的基类。
class AconC(nn.Module):
    # ACON 激活(激活或不激活)。
    # AconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x , beta 是可学习参数。
    # 根据“激活或不激活:学习定制激活”。
    r""" ACON activation (activate or not)
    AconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is a learnable parameter
    according to "Activate or Not: Learning Customized Activation" <https://arxiv.org/pdf/2009.04759.pdf>.
    """

    # 这段代码是一个 PyTorch 神经网络模块的构造函数( __init__ 方法),它初始化了一个名为 AconC 的类的一个实例。
    # 定义构造函数,接受两个参数。
    # 1.self :类的实例本身。
    # 2.c1 :输入通道的数量。
    def __init__(self, c1):
        # 调用父类 nn.Module 的构造函数,这是初始化 PyTorch 神经网络模块的标准做法,确保模块正确注册其参数。
        super().__init__()
        # 创建一个可学习的参数 p1 ,它是一个形状为 (1, c1, 1, 1) 的四维张量,用正态分布随机初始化。这个参数将用于后续的前向传播计算。 nn.Parameter 使得这个张量成为模块的一个参数,这样它就会被自动纳入模型的参数列表,并在训练过程中更新。
        self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1))
        # 类似地,创建另一个可学习的参数 p2 ,它也是一个形状为 (1, c1, 1, 1) 的四维张量,用正态分布随机初始化。
        self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1))
        # 创建第三个可学习的参数 beta ,它是一个形状为 (1, c1, 1, 1) 的四维张量,初始化为全1。这个参数同样被注册为模块的一个参数。
        self.beta = nn.Parameter(torch.ones(1, c1, 1, 1))
    # 这三个参数 p1 、 p2 和 beta 都是模块的可训练参数,它们将在训练过程中通过反向传播算法进行更新。这种类型的激活函数设计允许模型自适应地调整其激活行为,从而可能提高模型的性能和泛化能力。这种设计在某些情况下可以被视为一种注意力机制,因为它能够根据输入动态调整特征的权重。

    # 这段代码定义了 AconC 类的 forward 方法,它实现了 AconC 激活函数的前向传播逻辑。
    # 定义 forward 方法,这是神经网络模块的标准方法,用于定义如何对输入数据 x 进行处理。
    # 1.self :参数代表类的实例。
    # 2.x :是输入的张量。
    def forward(self, x):
        # 计算 dpx ,它是两个可学习参数 self.p1 和 self.p2 之差与输入 x 的逐元素乘积。这个操作生成了一个与输入 x 形状相同的张量,其中的每个元素都是 self.p1 和 self.p2 对应元素之差与 x 对应元素的乘积。
        dpx = (self.p1 - self.p2) * x
        # 计算 AconC 激活函数的输出,并返回结果。这个过程包括以下步骤 :
        # 计算 self.beta * dpx ,这是参数 self.beta 与 dpx 的逐元素乘积。
        # 将结果通过 Sigmoid 函数,得到一个介于 0 和 1 之间的激活值,这个值用于加权 dpx 。
        # 将 dpx 与 Sigmoid 函数的输出相乘,得到加权后的 dpx 。
        # 将加权后的 dpx 与 self.p2 * x 相加,得到最终的输出。这里 self.p2 * x 是 self.p2 与输入 x 的逐元素乘积。
        # 最终的输出是 dpx 的加权版本和 self.p2 * x 的线性组合,这种结构允许模型在保留 x 的同时,对 x 进行自适应的调整。这种激活函数的设计旨在引入非线性和自适应性,可能有助于提高模型在处理复杂数据时的表现。
        return dpx * torch.sigmoid(self.beta * dpx) + self.p2 * x
# AconC 激活函数通过引入可学习的参数 p1 、 p2 和 beta  ,为神经网络提供了一种自适应调整输入特征的能力。这种设计允许模型在训练过程中学习如何最佳地调整特征,可能有助于提高模型的性能和泛化能力。这种激活函数的设计在某些情况下可以被视为一种注意力机制,因为它能够根据输入动态调整特征的权重。

8.class MetaAconC(nn.Module): 

# 这段代码定义了一个名为 MetaAconC 的类,它是一个 PyTorch 神经网络模块,实现了一种名为 Meta AconC(Meta Activate or Not)的激活函数。这个激活函数是一种更高级的 AconC 激活函数,其中 beta 参数不是直接初始化的,而是通过一个小网络动态生成的。
# 定义一个名为 MetaAconC 的类,它继承自 nn.Module ,这是 PyTorch 中所有神经网络模块的基类。
class MetaAconC(nn.Module):
    # ACON 激活(激活或不激活)
    # MetaAconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x,beta 由小型网络生成。
    # 根据“激活或不激活:学习定制激活”。
    r""" ACON activation (activate or not)
    MetaAconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is generated by a small network
    according to "Activate or Not: Learning Customized Activation" <https://arxiv.org/pdf/2009.04759.pdf>.
    """

    # 这段代码是 MetaAconC 类的构造函数,它定义了类的初始化行为。
    # 构造函数接受四个参数。
    # 1.c1 :输入通道数( ch_in )。
    # 2.k :卷积核大小,默认为 1( kernel )。
    # 3.s :步长,默认为 1( stride )。
    # 4.r :一个用于计算第二个卷积层输出通道数的参数,默认为 16( r )。
    def __init__(self, c1, k=1, s=1, r=16):  # ch_in, kernel, stride, r
        # 调用父类 nn.Module 的构造函数,这是 Python 中继承机制的一部分,确保 MetaAconC 类正确地初始化。
        super().__init__()
        # 计算 c2 ,即第二个卷积层的输出通道数。 c2 的值是 r 和 c1 // r ( c1 除以 r 的整数商)中的较大值。这决定了 fc1 层输出的特征图的通道数。
        c2 = max(r, c1 // r)
        # 创建第一个可学习的参数 p1 ,它是一个形状为 (1, c1, 1, 1) 的张量,用随机正态分布初始化。这个参数将用于后续的前向传播计算。
        self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1))
        # 创建第二个可学习的参数 p2 ,它也是一个形状为 (1, c1, 1, 1) 的张量,用随机正态分布初始化。
        self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1))
        # 创建第一个卷积层 fc1 ,它是一个二维卷积层,将输入通道数从 c1 转换到 c2 ,卷积核大小为 k ,步长为 s ,并且包含偏置项( bias=True )。
        self.fc1 = nn.Conv2d(c1, c2, k, s, bias=True)
        # 创建第二个卷积层 fc2 ,它也是一个二维卷积层,将输入通道数从 c2 转换回 c1 ,卷积核大小为 k ,步长为 s ,并且包含偏置项( bias=True )。
        self.fc2 = nn.Conv2d(c2, c1, k, s, bias=True)
        # 注释掉的两行代码是批量归一化层( BatchNorm2d ),它们被注释掉可能是因为在某些情况下,批量归一化层可能会导致不稳定或者性能下降,特别是在处理小批量数据时。在 MetaAconC 类中,这些批量归一化层被省略,以避免潜在的稳定性问题。
        # self.bn1 = nn.BatchNorm2d(c2)
        # self.bn2 = nn.BatchNorm2d(c1)

    # 这段代码是 MetaAconC 类的 forward 方法,它定义了如何对输入数据 x 进行处理以产生输出。
    # 定义 forward 方法,这是神经网络模块的标准方法,用于定义如何对输入数据 1.x 进行处理。
    def forward(self, x):
        # 计算输入 x 在第二维(通常是高度)和第三维(通常是宽度)上的平均值。 keepdims=True 参数保持输出 y 的维度与 x 相同,这样在后续操作中可以保持维度一致性。
        y = x.mean(dim=2, keepdims=True).mean(dim=3, keepdims=True)
        # 这一行代码被注释掉了,它提到了一个与批量大小为1时的稳定性相关的问题,这个问题在 GitHub  issue #2891 中讨论。
        # batch-size 1 bug/instabilities https://github.com/ultralytics/yolov5/issues/2891
        # 原始代码中使用了两个批量归一化层( self.bn1 和 self.bn2 )和两个卷积层( self.fc1 和 self.fc2 )来计算 beta ,但由于稳定性问题,这部分代码被替换了。
        # beta = torch.sigmoid(self.bn2(self.fc2(self.bn1(self.fc1(y)))))  # bug/unstable
        # 计算 beta ,这是一个通过两个卷积层 self.fc1 和 self.fc2 传递 y 后得到的值,然后通过 Sigmoid 函数将其压缩到 [0, 1] 区间内。这个值将用于调整输入 x 的激活。
        beta = torch.sigmoid(self.fc2(self.fc1(y)))  # bug patch BN layers removed
        # 计算 dpx ,它是两个可学习参数 self.p1 和 self.p2 之差与输入 x 的逐元素乘积。
        dpx = (self.p1 - self.p2) * x
        # 计算最终的输出,这个过程包括以下步骤 :
        # 计算 beta 和 dpx 的逐元素乘积,然后通过 Sigmoid 函数。
        # 将结果与 dpx 相乘,得到加权后的 dpx 。
        # 将加权后的 dpx 与 self.p2 与 x 的逐元素乘积相加,得到最终的输出。
        return dpx * torch.sigmoid(beta * dpx) + self.p2 * x
    # 这种方法允许模型自适应地调整输入特征的激活,可能有助于提高模型的性能和泛化能力。通过这种方式, MetaAconC 激活函数能够根据输入特征动态调整其响应,从而在不同的数据和任务中提供更好的性能。
# MetaAconC 激活函数通过引入小型网络来学习输入特征的动态调整,这可能有助于模型捕捉更复杂的特征关系。通过在卷积层之间使用 Sigmoid 函数,该激活函数能够自适应地调整特征的强度。这种设计可能在某些视觉任务中提高模型的性能,尤其是在需要精细调整特征表示的情况下。

 


http://www.kler.cn/a/441876.html

相关文章:

  • 【2025】拥抱未来 砥砺前行
  • 微服务与docker
  • 云原生作业(四)
  • 基于微信小程序的安心陪诊管理系统
  • 实践深度学习:构建一个简单的图像分类器
  • k8s集群安装
  • 亚远景-实施ASPICE标准:全面提升汽车软件开发质量与效率的策略
  • leetcode二叉搜索树部分笔记
  • MySQL 中 Varchar(50) 和 varchar(500) 区别是什么?
  • 概率论深入学习书单
  • Halcon 直连相机
  • Excel加载项入门:原理、安装卸载流程与常见问题
  • CSS Grid 布局:属性及使用详解
  • qemu源码解析【总目录】
  • C/C++ 查找算法
  • 入探讨网络安全:技术与策略的双重防线深
  • 创建线程 ---- 实例
  • 每天40分玩转Django:Django缓存系统
  • 探索:为什么数组数据后端确要求前端传递,拼接的字符呢
  • 乳腺癌多模态诊断解释框架:CNN + 可解释 AI 可视化
  • 基于MNE的EEGNet 神经网络的脑电信号分类实战(附完整源码)
  • CAD xy坐标标注(跟随鼠标位置实时移动)——C#插件实现
  • dify智能体系列:selenium有啥好玩的?
  • 如何为IntelliJ IDEA配置JVM参数
  • springboot中Controller内文件上传到本地以及阿里云
  • 【Prompt Engineering】2.迭代优化