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:ReLUwrapsrelu,GELUwrapsgelu. Use the layers insideSequential, and use the functions or tensor methods for one-off calls. GELUuses the tanh approximation by default, where PyTorch'snn.GELUis exact. Build it withnew GELU({ approximate: "none" })to match PyTorch.- Most activations have no parameters, so plain input gives a plain
Tensor.PReLUhas a learnable slope and keeps it on the host.Softmax(axis)andGLU(dim)default to the last axis, andGLUhalves the size of that axis. - 1.5.0 added
ReLU6,LogSigmoid,CELU,Softshrink,HardshrinkandThreshold.
CELU
extends ModuleApplies the CELU activation (continuously differentiable ELU).
CELU(x) = max(0, x) + min(0, alpha * (exp(x / alpha) - 1))
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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
ELU
extends ModuleApplies 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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
GELU
extends ModuleApplies 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().
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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
GLU
extends ModuleGLU (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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Hardshrink
extends ModuleApplies the Hardshrink activation.
Hardshrink(x) = x if |x| > lambd, otherwise 0.
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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Hardsigmoid
extends ModuleHardsigmoid 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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Hardswish
extends ModuleHardswish 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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Hardtanh
extends ModuleApplies the HardTanh activation function.
HardTanh(x) = max(minVal, min(maxVal, x))
Members (5)
constructor(minVal?: number, maxVal?: number)forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
LeakyReLU
extends ModuleApplies 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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
LogSigmoid
extends ModuleApplies 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.
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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
LogSoftmax
extends ModuleApplies the Log Softmax activation function.
LogSoftmax(x_i) = log(exp(x_i) / sum(exp(x_j)))
Members (5)
constructor(axis?: Axis)forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Mish
extends ModuleApplies the Mish activation function.
Mish(x) = x * tanh(softplus(x))
Members (4)
forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
PReLU
extends ModulePReLU (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): GradTensorforward(input: Tensor): AnyTensorforward(input: AnyTensor): AnyTensortoString(): string
ReLU
extends ModuleApplies the Rectified Linear Unit (ReLU) activation function element-wise.
ReLU(x) = max(0, x)
Members (4)
forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
ReLU6
extends ModuleApplies 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).
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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
SELU
extends ModuleSELU (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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Sigmoid
extends ModuleApplies the Sigmoid activation function element-wise.
Sigmoid(x) = 1 / (1 + exp(-x))
Members (4)
forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
SiLU
extends SwishSiLU (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 ModuleApplies the Softmax activation function.
Softmax(x_i) = exp(x_i) / sum(exp(x_j))
Members (5)
constructor(axis?: Axis)forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Softmax2d
extends ModuleApplies 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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Softmin
extends ModuleApplies the Softmin activation function.
Softmin(x_i) = softmax(-x_i)
Members (5)
constructor(axis?: Axis)forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Softplus
extends ModuleApplies 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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Softshrink
extends ModuleApplies the Softshrink activation.
Softshrink(x) = x - lambd if x > lambd, x + lambd if x < -lambd, otherwise 0.
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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Softsign
extends ModuleSoftsign activation function.
Softsign(x) = x / (1 + |x|)
Members (4)
forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Swish
extends ModuleApplies the Swish activation function (also known as SiLU).
Swish(x) = x * sigmoid(x)
Members (4)
forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Tanh
extends ModuleApplies the Hyperbolic Tangent (Tanh) activation function element-wise.
Tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
Members (4)
forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Tanhshrink
extends ModuleApplies the Tanhshrink activation function element-wise.
Tanhshrink(x) = x - tanh(x)
Members (4)
forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Threshold
extends ModuleReplaces 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.
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): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
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);Found a mistake? Open an issue.