Skip to content

deepbox/nn

Activation Layers

Activation functions as Module layers for use inside Sequential models.

  • Activations

Overview

  • Each layer wraps the function of the same name from deepbox/ndarray: ReLU wraps relu, GELU wraps gelu. Use the layers inside Sequential, and use the functions or tensor methods for one-off calls.
  • GELU uses the tanh approximation by default, where PyTorch's nn.GELU is exact. Build it with new GELU({ approximate: "none" }) to match PyTorch.
  • Most activations have no parameters, so plain input gives a plain Tensor. PReLU has a learnable slope and keeps it on the host. Softmax(axis) and GLU(dim) default to the last axis, and GLU halves the size of that axis.
  • 1.5.0 added ReLU6, LogSigmoid, CELU, Softshrink, Hardshrink and Threshold.

Classes

28

CELU

extends Module

Applies the CELU activation (continuously differentiable ELU).

CELU(x) = max(0, x) + min(0, alpha * (exp(x / alpha) - 1))

Example
import { CELU } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; new CELU(2).forward(tensor([-1, 0, 1])); // [-0.7869, 0, 1]
Members (5)
  • constructor(alpha?: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

ELU

extends Module

Applies the Exponential Linear Unit (ELU) activation.

ELU(x) = x if x > 0, else alpha * (exp(x) - 1)

Members (5)
  • constructor(alpha?: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

GELU

extends Module

Applies the Gaussian Error Linear Unit (GELU) activation.

GELU(x) = x * Phi(x) where Phi is the CDF of the standard normal distribution.

With approximate: "tanh" (the default) the value is computed with 0.5 x (1 + tanh(sqrt(2/pi) (x + 0.044715 x^3))), which matches PyTorch's GELU(approximate="tanh"). With approximate: "none" it is the exact erf form 0.5 x (1 + erf(x / sqrt(2))), which is PyTorch's default nn.GELU(). The two differ by up to about 5e-4.

Unlike PyTorch, the default here is "tanh". Pass { approximate: "none" } to get the values of torch.nn.GELU().

Example
import { GELU } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; const x = tensor([-1, 0, 1]);new GELU().forward(x); // tanh approximationnew GELU({ approximate: "none" }).forward(x); // exact, same as torch.nn.GELU()
Members (5)
  • constructor(options?: GeluApproximation | { readonly approximate?: GeluApproximation; })
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

GLU

extends Module

GLU (Gated Linear Unit) activation.

GLU(a, b) = a ⊗ σ(b) where [a, b] = split(input, dim)

Splits the input tensor in half along dim and applies sigmoid gating. Used in modern NLP architectures.

Members (5)
  • constructor(dim?: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Hardshrink

extends Module

Applies the Hardshrink activation.

Hardshrink(x) = x if |x| > lambd, otherwise 0.

Example
import { Hardshrink } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; new Hardshrink().forward(tensor([-2, -0.3, 0.3, 2])); // [-2, 0, 0, 2]
Members (5)
  • constructor(lambd?: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Hardsigmoid

extends Module

Hardsigmoid activation: piecewise linear approximation of sigmoid.

Hardsigmoid(x) = clamp(x/6 + 0.5, 0, 1)

Efficient for mobile/embedded (MobileNetV3).

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Hardswish

extends Module

Hardswish activation: piecewise linear approximation of swish.

Hardswish(x) = x * Hardsigmoid(x) = x * clamp(x/6 + 0.5, 0, 1)

Efficient for mobile/embedded (MobileNetV3).

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Hardtanh

extends Module

Applies the HardTanh activation function.

HardTanh(x) = max(minVal, min(maxVal, x))

Members (5)
  • constructor(minVal?: number, maxVal?: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

LeakyReLU

extends Module

Applies the Leaky Rectified Linear Unit (Leaky ReLU) activation.

LeakyReLU(x) = x if x > 0, else alpha * x

Members (5)
  • constructor(alpha?: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

LogSigmoid

extends Module

Applies the LogSigmoid activation: log(1 / (1 + exp(-x))).

Computed as min(x, 0) - log1p(exp(-|x|)), so it neither overflows for very negative inputs nor loses precision for large positive ones.

Example
import { LogSigmoid } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; new LogSigmoid().forward(tensor([-1, 0, 1])); // [-1.3133, -0.6931, -0.3133]
Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

LogSoftmax

extends Module

Applies the Log Softmax activation function.

LogSoftmax(x_i) = log(exp(x_i) / sum(exp(x_j)))

Members (5)
  • constructor(axis?: Axis)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Mish

extends Module

Applies the Mish activation function.

Mish(x) = x * tanh(softplus(x))

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

PReLU

extends Module

PReLU (Parametric ReLU) activation with learnable slope parameter.

PReLU(x) = max(0, x) + a * min(0, x)

Where a is learnable. With numParameters = 1 a single slope is shared by all elements. With numParameters = C there is one slope per channel, taken along axis 1 of the input (axis 0 for 1-D input), as in PyTorch.

The slope is a parameter named weight in the layer dtype (float32 unless the dtype option or the global default dtype says otherwise). The layer computes in that dtype and casts the input to it (differentiably). A GradTensor input gives a GradTensor; a plain Tensor input gives a GradTensor while the slope requires grad and gradient tracking is on, and a plain Tensor otherwise.

Members (5)
  • constructor(numParameters?: number, init?: number, options?: { readonly dtype?: LayerDType; })
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): AnyTensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

ReLU

extends Module

Applies the Rectified Linear Unit (ReLU) activation function element-wise.

ReLU(x) = max(0, x)

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

ReLU6

extends Module

Applies the ReLU6 activation: min(max(0, x), 6).

Used by MobileNet. NaN propagates. The gradient is 1 strictly between 0 and 6 and 0 elsewhere, including at the two kinks (as in PyTorch).

Example
import { ReLU6 } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; new ReLU6().forward(tensor([-2, 3, 8])); // [0, 3, 6]
Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

SELU

extends Module

SELU (Scaled Exponential Linear Unit) activation for self-normalizing networks.

SELU(x) = scale * (max(0, x) + min(0, alpha * (exp(x) - 1)))

With specific alpha and scale values that enable self-normalization.

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Sigmoid

extends Module

Applies the Sigmoid activation function element-wise.

Sigmoid(x) = 1 / (1 + exp(-x))

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

SiLU

extends Swish

SiLU (Sigmoid Linear Unit) activation, an alias for Swish.

SiLU(x) = x * sigmoid(x)

Standard name in PyTorch. Identical to Swish.

Members (1)
  • toString(): string

Softmax

extends Module

Applies the Softmax activation function.

Softmax(x_i) = exp(x_i) / sum(exp(x_j))

Members (5)
  • constructor(axis?: Axis)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Softmax2d

extends Module

Applies softmax over the channel dimension at every spatial location.

Accepts (C, H, W) or (N, C, H, W) input (as PyTorch's Softmax2d) and normalizes along the channel axis (ndim - 3), so the values at each pixel sum to 1 across channels.

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Softmin

extends Module

Applies the Softmin activation function.

Softmin(x_i) = softmax(-x_i)

Members (5)
  • constructor(axis?: Axis)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Softplus

extends Module

Applies the Softplus activation function.

Softplus(x) = log(1 + exp(beta * x)) / beta

A smooth approximation of ReLU. It is evaluated without overflow for large inputs, in both the tensor and the autograd path.

Members (5)
  • constructor(beta?: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Softshrink

extends Module

Applies the Softshrink activation.

Softshrink(x) = x - lambd if x > lambd, x + lambd if x < -lambd, otherwise 0.

Example
import { Softshrink } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; new Softshrink().forward(tensor([-2, -0.3, 0.3, 2])); // [-1.5, 0, 0, 1.5]
Members (5)
  • constructor(lambd?: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Softsign

extends Module

Softsign activation function.

Softsign(x) = x / (1 + |x|)

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Swish

extends Module

Applies the Swish activation function (also known as SiLU).

Swish(x) = x * sigmoid(x)

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Tanh

extends Module

Applies the Hyperbolic Tangent (Tanh) activation function element-wise.

Tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Tanhshrink

extends Module

Applies the Tanhshrink activation function element-wise.

Tanhshrink(x) = x - tanh(x)

Members (4)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string

Threshold

extends Module

Replaces every element that is not above a threshold with a fixed value.

Threshold(x) = x if x > threshold, otherwise value. NaN passes through unchanged. The gradient is 1 where x > threshold and 0 elsewhere.

Example
import { Threshold } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; new Threshold(0.1, 20).forward(tensor([0, 0.1, 0.5])); // [20, 20, 0.5]
Members (5)
  • constructor(threshold: number, value: number)
  • forward(input: GradTensor): GradTensor
  • forward(input: Tensor): Tensor
  • forward(input: AnyTensor): AnyTensor
  • toString(): string
nn-activations.ts
import { tensor } from "deepbox/ndarray";import { GELU, GLU, Linear, Mish, ReLU, Sequential, Softmax, Swish } from "deepbox/nn"; const x = tensor([[1, -2, 3, -4]]); console.log(new ReLU().forward(x).toString());console.log(new GELU().forward(x).toString()); // tanh approximationconsole.log(new GELU({ approximate: "none" }).forward(x).toString()); // exactconsole.log(new Swish().forward(x).toString(), new Mish().forward(x).toString());console.log(new GLU().forward(x).shape); // [1, 2]: the last axis is halvedconsole.log(new Softmax().forward(x).toString()); const head = new Sequential(new Linear(4, 8), new GELU(), new Linear(8, 2));console.log(head.forward(x).shape);