Source code for torch_activation.trig

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

from torch import Tensor

from torch_activation.utils import plot_activation


[docs]class GCU(nn.Module): r""" Applies the Growing Cosine Unit activation function: :math:`\text{GCU}(x) = x \cos (x)` See: https://doi.org/10.48550/arXiv.2108.12943 Args: inplace (bool, optional): can optionally do the operation in-place. Default: ``False`` Shape: - Input: :math:`(*)`, where :math:`*` means any number of dimensions. - Output: :math:`(*)`, same shape as the input. Examples:: >>> m = nn.GCU() >>> x = torch.randn(2) >>> output = m(x) >>> m = nn.GCU(inplace=True) >>> x = torch.randn(2) >>> m(x) """ def __init__(self, inplace: bool = False): super(GCU, self).__init__() self.inplace = inplace
[docs] def forward(self, x) -> Tensor: if self.inplace: return x.mul_(torch.cos(x)) else: return x * torch.cos(x)
[docs]class CosLU(nn.Module): r""" Applies the Cosine Linear Unit function: :math:`\text{CosLU}(x) = (x + a \cdot \cos(b x)) \cdot \sigma(x)` See: https://doi.org/10.20944/preprints202301.0463.v1 Args: a (float, optional): Scaling factor for the cosine term. Default is 1.0. b (float, optional): Frequency factor for the cosine term. Default is 1.0. inplace (bool, optional): can optionally do the operation in-place. Default: ``False`` Shape: - Input: :math:`(*)`, where :math:`*` means any number of dimensions. - Output: :math:`(*)`, same shape as the input. Examples:: >>> m = CosLU(alpha=2.0, beta=1.0) >>> x = torch.randn(2) >>> output = m(x) >>> m = CosLU(inplace=True) >>> x = torch.randn(2, 3, 4) >>> m(x) """ def __init__(self, a: float = 1.0, b: float = 1.0, inplace: bool = False): super(CosLU, self).__init__() self.alpha = nn.Parameter(Tensor(a)) self.beta = nn.Parameter(Tensor(b)) self.inplace = inplace
[docs] def forward(self, x) -> Tensor: return self._forward_inplace(x) if self.inplace else self._forward(x)
def _forward(self, x): result = x + self.alpha * torch.cos(self.beta * x) result *= torch.sigmoid(x) return result def _forward_inplace(self, x): s_x = torch.sigmoid(x) x.add_(self.alpha * torch.cos(self.beta * x)) x.mul_(s_x) return x
[docs]class SinLU(nn.Module): r""" Applies the Sinu-sigmoidal Linear Unit activation function: :math:`\text{SinLU}(x) = (x + \alpha \sin (\beta x)) \sigma (x)` See: https://doi.org/10.3390/math10030337 Args: a (float, optional): Initial value for sine function magnitude. Default: 1.0. b (float, optional): Initial value for sine function period. Default: 1.0. inplace (bool, optional): can optionally do the operation in-place. Default: ``False`` Shape: - Input: :math:`(*)`, where :math:`*` means any number of dimensions. - Output: :math:`(*)`, same shape as the input. Examples:: >>> m = nn.SinLU(a=5.0, b=6.0) >>> x = torch.randn(2) >>> output = m(x) """ def __init__(self, a: float = 1.0, b: float = 1.0, inplace: bool = False): super(SinLU, self).__init__() self.alpha = nn.Parameter(Tensor(a)) self.beta = nn.Parameter(Tensor(b)) self.inplace = inplace
[docs] def forward(self, x) -> Tensor: return self._forward_inplace(x) if self.inplace else self._forward(x)
def _forward(self, x): result = x + self.alpha * torch.sin(self.beta * x) result *= torch.sigmoid(x) return result def _forward_inplace(self, x): s_x = torch.sigmoid(x) x.add_(self.alpha * torch.sin(self.beta * x)) x.mul_(s_x) return x