deepbox/nn
Dense, Conv & Utility Layers
Linear, embeddings, 1-D, 2-D and 3-D convolution and pooling, padding, Upsample, Flatten, Identity and SpectralNorm.
- Layers
Overview
- Layers compute in their parameter dtype (
float32by default, or thedtypeoption) and cast their input to it.Linearand the convolutions take{ bias, dtype }. Weights use PyTorch's initialization, so callsetSeedbefore you build a model to make it repeatable. - Image layers use channel-first layout:
Conv2dtakes[batch, channels, height, width]. Convolutions acceptstride,padding(a number,"same"or"valid"),dilationandgroups. Pooling layers acceptceilMode.Upsampledefaults toalignCorners: truein bilinear mode, where PyTorch usesfalse. - Layers without parameters (
Flatten, pooling, padding,Upsample) return a plainTensorfor plain input. Read the result directly instead of through.tensor. Conv2dandLinearhave device kernels, as do the 2-D pooling layers.Embedding,Conv3dand the transposed convolutions run host kernels and keep their weights on the CPU.
AdaptiveAvgPool1d
extends Module1D Adaptive Average Pooling.
Produces fixed output length regardless of input size. Output cell o averages the input range [floor(o * L / out), ceil((o + 1) * L / out)). Input: (N, C, L) -> Output: (N, C, outputSize)
import { AdaptiveAvgPool1d } from 'deepbox/nn'; const pool = new AdaptiveAvgPool1d(1); // global average over the length axisMembers (5)
constructor(outputSize: number)forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
AdaptiveAvgPool2d
extends Module2D Adaptive Average Pooling.
Produces output of specified size regardless of input dimensions. Output cell o averages the input range [floor(o * in / out), ceil((o + 1) * in / out)), so neighbouring windows overlap when in is not a multiple of out. Typical use is a global average pool ([1, 1]) before a classifier head, so that the head does not depend on the input resolution.
import { AdaptiveAvgPool2d } from 'deepbox/nn'; const pool = new AdaptiveAvgPool2d([1, 1]); // Global average poolingMembers (5)
constructor(outputSize: number | [ number, number ])forward(x: GradTensor): GradTensorforward(x: Tensor): Tensorforward(x: AnyTensor): AnyTensortoString(): string
AdaptiveMaxPool1d
extends Module1D Adaptive Max Pooling.
Produces fixed output length regardless of input size, taking the maximum of each adaptive window (the windows are the same as in AdaptiveAvgPool1d). Input: (N, C, L) -> Output: (N, C, outputSize)
import { AdaptiveMaxPool1d } from 'deepbox/nn'; const pool = new AdaptiveMaxPool1d(1); // global max over the length axisMembers (5)
constructor(outputSize: number)forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
AdaptiveMaxPool2d
extends Module2D Adaptive Max Pooling.
Produces output of specified size regardless of input dimensions, selecting the maximum value from each adaptive window (the windows are the same as in AdaptiveAvgPool2d).
import { AdaptiveMaxPool2d } from 'deepbox/nn'; const pool = new AdaptiveMaxPool2d([1, 1]); // Global max poolingMembers (5)
constructor(outputSize: number | [ number, number ])forward(x: GradTensor): GradTensorforward(x: Tensor): Tensorforward(x: AnyTensor): AnyTensortoString(): string
AvgPool1d
extends Module1D Average Pooling.
Applies average pooling over a 1D signal. Input: (N, C, L) -> Output: (N, C, L_out)
By default padded zeros count towards the average (PyTorch's count_include_pad=True); pass countIncludePad: false to divide by the number of real elements in each window. The stride defaults to the kernel size and padding may be at most half of kernelSize.
import { AvgPool1d } from 'deepbox/nn'; const pool = new AvgPool1d(2);Members (5)
constructor(kernelSize: number, options?: { readonly stride?: number; readonly padding?: number; readonly countIncludePad?: boolean; readonly ceilMode?: boolean; })forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
AvgPool2d
extends Module2D Average Pooling Layer.
Applies a 2D average pooling over an input of shape (batch, channels, height, width). By default padded zeros count towards the average (PyTorch's count_include_pad=True); pass countIncludePad: false to divide by the number of real elements in each window.
The stride defaults to the kernel size. As in PyTorch, padding may be at most half of kernelSize.
import { AvgPool2d } from 'deepbox/nn'; const pool = new AvgPool2d(2); // 2x2 poolingMembers (5)
constructor(kernelSize: number | [ number, number ], options?: { readonly stride?: number | [ number, number ]; readonly padding?: number | [ number, number ]; readonly countIncludePad?: boolean; readonly ceilMode?: boolean; })forward(x: GradTensor): GradTensorforward(x: Tensor): Tensorforward(x: AnyTensor): AnyTensortoString(): string
AvgPool3d
extends Module3D Average Pooling Layer.
Applies average pooling over a 3D input signal (volumetric data). Input: (N, C, D, H, W) -> Output: (N, C, D_out, H_out, W_out)
By default padded zeros count towards the average (PyTorch's count_include_pad=True); pass countIncludePad: false to divide by the number of real elements in each window. The stride defaults to the kernel size and padding may be at most half of kernelSize.
import { AvgPool3d } from 'deepbox/nn'; const pool = new AvgPool3d(2); // 2x2x2 poolingMembers (5)
constructor(kernelSize: number | [ number, number, number ], options?: { readonly stride?: number | [ number, number, number ]; readonly padding?: number | [ number, number, number ]; readonly countIncludePad?: boolean; readonly ceilMode?: boolean; })forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Conv1d
extends Module1D Convolutional Layer.
Applies a 1D cross-correlation over an input of shape (batch, inChannels, length) and returns (batch, outChannels, outLength) with outLength = floor((length + 2 * padding - dilation * (kernelSize - 1) - 1) / stride) + 1.
Weights have shape (outChannels, inChannels / groups, kernelSize). As in PyTorch, weights and bias are drawn from U(-1/sqrt(fanIn), 1/sqrt(fanIn)) with fanIn = inChannels / groups * kernelSize.
dilation spaces out the kernel taps, groups splits the channels into independent groups (groups = inChannels gives a depthwise convolution), and padding accepts "valid" (no padding) or "same" (output length equals input length; stride 1 only).
The layer computes in its parameter dtype (float32 unless dtype or the global default dtype says otherwise) and casts the input to it. A GradTensor input gives a GradTensor; a plain Tensor input gives a GradTensor that tracks the weights while they require grad and gradient tracking is on, and a plain Tensor otherwise (inside noGrad() or with frozen weights).
import { Conv1d } from 'deepbox/nn'; const conv = new Conv1d(16, 33, 3); // in_channels=16, out_channels=33, kernel_size=3const same = new Conv1d(16, 32, 5, { padding: 'same', dilation: 2, groups: 4 });Members (7)
constructor(inChannels: number, outChannels: number, kernelSize: number, options?: { readonly stride?: number; readonly padding?: ConvPadding<number>; readonly dilation?: number; readonly groups?: number; readonly bias?: boolean; readonly dtype?: LayerDType; })weight: GradTensorLearnable kernel of shape
(outChannels, inChannels / groups, kernelSize).bias: GradTensor | undefinedLearnable bias of shape
(outChannels), orundefinedwhen the layer was built withbias: false.forward(x: GradTensor): GradTensorforward(x: Tensor): AnyTensorforward(x: AnyTensor): AnyTensortoString(): string
Conv2d
extends Module2D Convolutional Layer.
Applies a 2D cross-correlation over an input of shape (batch, inChannels, height, width) and returns (batch, outChannels, outH, outW) with outH = floor((height + 2 * padH - dilH * (kH - 1) - 1) / strideH) + 1 (and likewise for the width).
Weights have shape (outChannels, inChannels / groups, kH, kW). As in PyTorch, weights and bias are drawn from U(-1/sqrt(fanIn), 1/sqrt(fanIn)) with fanIn = inChannels / groups * kH * kW.
dilation spaces out the kernel taps, groups splits the channels into independent groups (groups = inChannels gives a depthwise convolution), and padding accepts "valid" (no padding) or "same" (output size equals input size; stride 1 only).
The layer computes in its parameter dtype (float32 unless dtype or the global default dtype says otherwise) and casts the input to it. A GradTensor input gives a GradTensor; a plain Tensor input gives a GradTensor that tracks the weights while they require grad and gradient tracking is on, and a plain Tensor otherwise (inside noGrad() or with frozen weights).
import { Conv2d } from 'deepbox/nn'; const conv = new Conv2d(3, 64, 3); // RGB to 64 channels, 3x3 kernelconst depthwise = new Conv2d(32, 32, 3, { padding: 'same', groups: 32 });const dilated = new Conv2d(8, 8, 3, { dilation: 2, padding: 2 });Members (7)
constructor(inChannels: number, outChannels: number, kernelSize: number | [ number, number ], options?: { readonly stride?: number | [ number, number ]; readonly padding?: ConvPadding<number | [ number, number ]>; readonly dilation?: number | [ number, number ]; readonly groups?: number; readonly bias?: boolean; reado…weight: GradTensorLearnable kernel of shape
(outChannels, inChannels / groups, kH, kW).bias: GradTensor | undefinedLearnable bias of shape
(outChannels), orundefinedwhen the layer was built withbias: false.forward(x: GradTensor): GradTensorforward(x: Tensor): AnyTensorforward(x: AnyTensor): AnyTensortoString(): string
Conv3d
extends Module3D Convolutional Layer.
Applies a 3D cross-correlation over an input signal composed of several input planes. Used for video processing, medical imaging (CT/MRI), and 3D point clouds.
Input: (N, C_in, D, H, W) -> Output: (N, C_out, D_out, H_out, W_out), where each output size is floor((in + 2 * padding - dilation * (kernel - 1) - 1) / stride) + 1.
Weights have shape (outChannels, inChannels / groups, kD, kH, kW). As in PyTorch, weights and bias are drawn from U(-1/sqrt(fanIn), 1/sqrt(fanIn)) with fanIn = inChannels / groups * kD * kH * kW.
dilation spaces out the kernel taps, groups splits the channels into independent groups, and padding accepts "valid" (no padding) or "same" (output size equals input size; stride 1 only).
The layer computes in its parameter dtype and casts the input to it. A GradTensor input gives a GradTensor; a plain Tensor input gives a GradTensor while the weights require grad and gradient tracking is on, and a plain Tensor otherwise.
import { Conv3d } from 'deepbox/nn'; const conv = new Conv3d(1, 16, 3); // 1 input channel, 16 output channels, 3x3x3 kernelconst same = new Conv3d(4, 8, 3, { padding: 'same', dilation: 2, groups: 2 });Members (7)
constructor(inChannels: number, outChannels: number, kernelSize: number | [ number, number, number ], options?: { readonly stride?: number | [ number, number, number ]; readonly padding?: ConvPadding<number | [ number, number, number ]>; readonly dilation?: number | [ number, number, number ]; readonly groups?: number…weight: GradTensorLearnable kernel of shape
(outChannels, inChannels / groups, kD, kH, kW).bias: GradTensor | undefinedLearnable bias of shape
(outChannels), orundefinedwhen the layer was built withbias: false.forward(x: GradTensor): GradTensorforward(x: Tensor): AnyTensorforward(x: AnyTensor): AnyTensortoString(): string
ConvTranspose1d
extends Module1D Transposed Convolution Layer (Deconvolution).
Applies a transposed 1D convolution over an input signal. Used for upsampling in sequence generation, audio synthesis, etc.
Output size: outL = (inL - 1) * stride - 2 * padding + kernelSize + outputPadding
Weights have shape (inChannels, outChannels, kernelSize). outputPadding must be smaller than the stride. As in PyTorch, weights and bias are drawn from U(-1/sqrt(fanIn), 1/sqrt(fanIn)) with fanIn = outChannels * kernelSize.
The layer computes in its parameter dtype and casts the input to it. A GradTensor input gives a GradTensor; a plain Tensor input gives a GradTensor while the weights require grad and gradient tracking is on, and a plain Tensor otherwise.
import { ConvTranspose1d } from 'deepbox/nn'; const deconv = new ConvTranspose1d(16, 33, 3, { stride: 2 });Members (7)
constructor(inChannels: number, outChannels: number, kernelSize: number, options?: { readonly stride?: number; readonly padding?: number; readonly outputPadding?: number; readonly bias?: boolean; readonly dtype?: LayerDType; })weight: GradTensorLearnable kernel of shape
(inChannels, outChannels, kernelSize).bias: GradTensor | undefinedLearnable bias of shape
(outChannels), orundefinedwhen the layer was built withbias: false.forward(x: GradTensor): GradTensorforward(x: Tensor): AnyTensorforward(x: AnyTensor): AnyTensortoString(): string
ConvTranspose2d
extends Module2D Transposed Convolution Layer (Deconvolution).
Applies a transposed 2D convolution operator over an input image. Used in image generation (GANs), semantic segmentation (U-Net), autoencoders, and super-resolution networks.
Output size:
outH = (inH - 1) * strideH - 2 * padH + kernelH + outputPadHoutW = (inW - 1) * strideW - 2 * padW + kernelW + outputPadWWeights have shape (inChannels, outChannels, kH, kW). outputPadding must be smaller than the stride; it only resolves the output-size ambiguity of strided convolutions and adds no values of its own. As in PyTorch, weights and bias are drawn from U(-1/sqrt(fanIn), 1/sqrt(fanIn)) with fanIn = outChannels * kH * kW.
The layer computes in its parameter dtype and casts the input to it. A GradTensor input gives a GradTensor; a plain Tensor input gives a GradTensor while the weights require grad and gradient tracking is on, and a plain Tensor otherwise.
import { ConvTranspose2d } from 'deepbox/nn'; const deconv = new ConvTranspose2d(16, 33, 3, { stride: 2, padding: 1 });Members (7)
constructor(inChannels: number, outChannels: number, kernelSize: number | [ number, number ], options?: { readonly stride?: number | [ number, number ]; readonly padding?: number | [ number, number ]; readonly outputPadding?: number | [ number, number ]; readonly bias?: boolean; readonly dtype?: LayerDType; })weight: GradTensorLearnable kernel of shape
(inChannels, outChannels, kH, kW).bias: GradTensor | undefinedLearnable bias of shape
(outChannels), orundefinedwhen the layer was built withbias: false.forward(x: GradTensor): GradTensorforward(x: Tensor): AnyTensorforward(x: AnyTensor): AnyTensortoString(): string
MaxPool1d
extends Module1D Max Pooling.
Applies max pooling over a 1D signal (e.g., sequences, audio). Input: (N, C, L) -> Output: (N, C, L_out)
The stride defaults to the kernel size. Padding is ignored by the maximum, a NaN inside a window propagates, and padding may be at most half of kernelSize.
import { MaxPool1d } from 'deepbox/nn'; const pool = new MaxPool1d(2);Members (5)
constructor(kernelSize: number, options?: { readonly stride?: number; readonly padding?: number; readonly ceilMode?: boolean; })forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
MaxPool2d
extends Module2D Max Pooling Layer.
Applies a 2D max pooling over an input of shape (batch, channels, height, width). Padding is ignored by the maximum (it behaves like -Infinity), a NaN inside a window propagates to the output, and the gradient flows to the first maximum of each window.
The stride defaults to the kernel size. As in PyTorch, padding may be at most half of kernelSize.
import { MaxPool2d } from 'deepbox/nn'; const pool = new MaxPool2d(2); // 2x2 poolingMembers (5)
constructor(kernelSize: number | [ number, number ], options?: { readonly stride?: number | [ number, number ]; readonly padding?: number | [ number, number ]; readonly ceilMode?: boolean; })forward(x: GradTensor): GradTensorforward(x: Tensor): Tensorforward(x: AnyTensor): AnyTensortoString(): string
MaxPool3d
extends Module3D Max Pooling Layer.
Applies max pooling over a 3D input signal (volumetric data). Input: (N, C, D, H, W) -> Output: (N, C, D_out, H_out, W_out)
The stride defaults to the kernel size. Padding is ignored by the maximum, a NaN inside a window propagates, and padding may be at most half of kernelSize.
import { MaxPool3d } from 'deepbox/nn'; const pool = new MaxPool3d(2); // 2x2x2 poolingMembers (5)
constructor(kernelSize: number | [ number, number, number ], options?: { readonly stride?: number | [ number, number, number ]; readonly padding?: number | [ number, number, number ]; readonly ceilMode?: boolean; })forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Embedding
extends ModuleA lookup table that stores embeddings of a fixed dictionary and size.
This module is often used to store word embeddings and retrieve them using indices. The input to the module is a list of indices, and the output is the corresponding word embeddings.
Mathematical Formulation:
output[i] = weight[indices[i]]The weight table is initialized from a standard normal distribution. With paddingIdx, that row is initialized to zeros and receives no gradient. As in PyTorch, the lookup returns the stored row, which stays zero unless you write to it.
The output has the dtype of the weight table. A GradTensor index gives a GradTensor; a plain index tensor gives a GradTensor that tracks the weight while it requires grad and gradient tracking is on, and a plain Tensor otherwise (for example inside noGrad() or for a frozen table).
import { Embedding } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; const embedding = new Embedding(10, 3); // 10 words, 3-dim embeddingsconst indices = tensor([1, 2, 4, 5]);const output = embedding.forward(indices); // shape: [4, 3]Members (10)
constructor(numEmbeddings: number, embeddingDim: number, options?: { readonly paddingIdx?: number; readonly dtype?: LayerDType; })Create a new Embedding layer.
readonly numEmbeddings: numberNumber of embeddings (vocabulary size)
readonly embeddingDim: numberDimension of each embedding vector
readonly paddingIdx: number | undefinedPadding index with negative values already resolved; this row receives no gradient
weight: GradTensorAccess the weight parameter
static fromPretrained(weights: AnyTensor, options?: { readonly freeze?: boolean; readonly paddingIdx?: number; readonly dtype?: LayerDType; }): EmbeddingCreate an Embedding layer from an existing weight matrix.
forward(indices: GradTensor): GradTensorForward pass: look up embeddings for the given indices.
forward(indices: Tensor): AnyTensorforward(indices: AnyTensor): AnyTensortoString(): string
EmbeddingBag
extends ModuleComputes sums, means, or maxes of "bags" of embeddings, without instantiating the intermediate per-embedding matrix.
Indices can be given as a 1-D tensor together with offsets that mark where each bag starts, or as a 2-D tensor (numBags, bagSize) without offsets. Entries equal to paddingIdx are left out of the reduction (and receive no gradient). An empty bag, or a bag made only of padding, gives a row of zeros.
import { EmbeddingBag } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; const bag = new EmbeddingBag(10, 3, { mode: 'mean' });const indices = tensor([1, 2, 4, 5, 4, 3, 2, 9]);const offsets = tensor([0, 4]); // two bags: [1,2,4,5] and [4,3,2,9]const output = bag.forward(indices, offsets); // shape: [2, 3]Members (11)
constructor(numEmbeddings: number, embeddingDim: number, options?: { readonly mode?: EmbeddingBagMode; readonly paddingIdx?: number; readonly includeLastOffset?: boolean; readonly dtype?: LayerDType; })readonly numEmbeddings: numberNumber of embeddings (vocabulary size)
readonly embeddingDim: numberDimension of each embedding vector
readonly mode: EmbeddingBagModeReduction applied to each bag
readonly paddingIdx: number | undefinedPadding index with negative values already resolved; it is skipped in every bag
readonly includeLastOffset: booleanWhether
offsetscarries a final entry that marks the end of the last bagweight: GradTensorAccess the weight parameter
forward(indices: GradTensor, ...rest: AnyTensor[]): GradTensorForward pass: compute bag embeddings.
forward(indices: Tensor, ...rest: AnyTensor[]): AnyTensorforward(indices: AnyTensor, ...rest: AnyTensor[]): AnyTensortoString(): string
Linear
extends ModuleApplies a linear transformation to the incoming data: y = xA^T + b
This is also known as a fully connected layer or dense layer.
Mathematical Formulation:
y = x * W^T + bWhere: - x is the input tensor of shape (*, in_features) - W is the weight matrix of shape (out_features, in_features) - b is the bias vector of shape (out_features,) - y is the output tensor of shape (*, out_features)
Shape Conventions: - Input: (*, in_features) where * means any number of leading dimensions - 1D: (in_features) → Output: (out_features) - 2D: (batch, in_features) → Output: (batch, out_features) - 3D: (batch, seq_len, in_features) → Output: (batch, seq_len, out_features) - The last dimension must equal in_features - All leading dimensions are preserved in the output
Parameters: - inFeatures: Size of each input sample - outFeatures: Size of each output sample - bias: If true, adds a learnable bias to the output
Attributes: - weight: Learnable weights of shape (out_features, in_features) - bias: Learnable bias of shape (out_features,) if bias=true
Initialization: As in PyTorch, weights and biases are drawn from the uniform distribution U(-1/sqrt(in_features), 1/sqrt(in_features)) (Kaiming uniform with a = sqrt(5) for the weights). Seed the global generator with manualSeed for reproducible weights.
Input dtype: The layer computes in its parameter dtype (float32 unless dtype is given, or the global default dtype), so integer, boolean and float64 inputs all work. For a GradTensor input the conversion is differentiable.
Gradient tracking: With a GradTensor input the result is a GradTensor. With a plain Tensor input the result is a GradTensor that tracks the weights while gradient tracking is on and a weight requires grad (the input itself is not tracked), so a training loop needs no wrapping of the data. Inside noGrad(), or when every weight is frozen, a plain Tensor is returned. eval() alone does not switch tracking off.
import { Linear } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; // Create a linear layer with 3 input features and 2 output featuresconst layer = new Linear(3, 2); // Forward passconst input = tensor([[1, 2, 3]]); // shape: (1, 3)const output = layer.forward(input); // shape: (1, 2) // Without biasconst layerNoBias = new Linear(10, 5, { bias: false });Members (9)
constructor(inFeatures: number, outFeatures: number, options?: { readonly bias?: boolean; readonly dtype?: "float32" | "float64"; readonly device?: "cpu" | "webgpu" | "wasm"; })Create a new Linear layer.
inputSize: numberGet the number of input features.
outputSize: numberGet the number of output features.
forward(input: GradTensor): GradTensorForward pass: compute y = x * W^T + b
forward(input: Tensor): AnyTensorforward(input: AnyTensor): AnyTensortoString(): stringGet extra representation string for this layer.
getWeight(): TensorGet the weight matrix.
getBias(): Tensor | undefinedGet the bias vector.
ConstantPad2d
extends ModulePads the input tensor using a constant value.
The padding is [left, right, top, bottom], or a single number applied to all four sides. Negative values crop. For integer and boolean inputs the value is truncated to the input dtype.
const pad = new ConstantPad2d(1, -1); // pad 1 on all sides with -1Members (5)
constructor(padding: number | Padding4, value: number)forward(input: GradTensor): GradTensorforward(input: TensorClass): TensorClassforward(input: AnyTensor): AnyTensortoString(): string
ReflectionPad2d
extends ModulePads using reflection of the input boundary (the edge row or column is not repeated). Each pad must be smaller than the corresponding input size.
const pad = new ReflectionPad2d(1);Members (5)
constructor(padding: number | Padding4)forward(input: GradTensor): GradTensorforward(input: TensorClass): TensorClassforward(input: AnyTensor): AnyTensortoString(): string
ReplicationPad2d
extends ModulePads using replication of the input boundary values.
const pad = new ReplicationPad2d(1);Members (5)
constructor(padding: number | Padding4)forward(input: GradTensor): GradTensorforward(input: TensorClass): TensorClassforward(input: AnyTensor): AnyTensortoString(): string
ZeroPad2d
extends ModulePads the input tensor using zeros.
The padding is [left, right, top, bottom], or a single number applied to all four sides. Negative values crop. Accepts (N, C, H, W) and unbatched (C, H, W) input.
const pad = new ZeroPad2d(1); // pad 1 on all sidesconst pad2 = new ZeroPad2d([1, 1, 2, 2]); // [left, right, top, bottom]Members (5)
constructor(padding: number | Padding4)forward(input: GradTensor): GradTensorforward(input: TensorClass): TensorClassforward(input: AnyTensor): AnyTensortoString(): string
SpectralNorm
extends ModuleApplies Spectral Normalization to a weight parameter of a module.
Spectral normalization constrains the spectral norm (largest singular value) of a weight matrix to 1, stabilizing the training of GANs and other networks.
Mathematical Formulation:
W_SN = W / σ(W)where σ(W) is the largest singular value of W, estimated via power iteration.
Behavior: - The wrapped module is registered as the child module, so parameters() and stateDict() include its weights (for example module.weight). - The raw weight stays in the wrapped module and is never modified. During forward the module sees the normalized weight, and gradients flow back to the raw weight through the normalization, treating the power-iteration vectors as constants (as PyTorch does). - The power iteration vectors u and v are stored as buffers named <weightName>_u and <weightName>_v. They are refined by nPowerIterations steps on each training-mode forward pass and are left unchanged in evaluation mode. Fifteen warm-up iterations run at construction. - Weights with more than two dimensions are reshaped to (shape[0], rest).
Purpose: - Stabilizes GAN training by controlling the Lipschitz constant - Prevents mode collapse in generative models - More efficient than full SVD: uses power iteration (O(mn) per step)
import { SpectralNorm, Linear } from 'deepbox/nn';import { tensor } from 'deepbox/ndarray'; const linear = new Linear(10, 5);const snLinear = new SpectralNorm(linear, 'weight');const input = tensor([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]);const output = snLinear.forward(input);Members (7)
constructor(module: Module, weightName?: string, nPowerIterations?: number, eps?: number)Create a SpectralNorm wrapper around a module.
spectralNormValue: numberGet the current estimated spectral norm (largest singular value).
module: ModuleGet the wrapped module.
forward(input: GradTensor): GradTensorForward pass: normalize the weight by its spectral norm, then delegate.
forward(input: Tensor): AnyTensorforward(input: AnyTensor): AnyTensortoString(): string
Upsample
extends ModuleUpsamples a 4D input (N, C, H, W) using nearest-neighbor or bilinear interpolation.
Specify either scaleFactor or size, not both. With scaleFactor, the output height and width are floor(input * scaleFactor). The output keeps the input's float dtype (integer and bool inputs produce float64) and is differentiable with respect to the input.
Bilinear mode follows alignCorners. The default is true (corner pixels of input and output coincide), which is the convention Deepbox has always used. PyTorch's nn.Upsample defaults to false; pass alignCorners: false for results that match it.
const up = new Upsample({ scaleFactor: 2, mode: 'nearest' });// input: (1, 3, 4, 4) -> output: (1, 3, 8, 8) const up2 = new Upsample({ size: [16, 16], mode: 'bilinear', alignCorners: false });Members (5)
constructor(options: { readonly scaleFactor?: number | readonly [ number, number ]; readonly size?: number | readonly [ number, number ]; readonly mode?: UpsampleMode; readonly alignCorners?: boolean; })forward(input: GradTensor): GradTensorforward(input: TensorClass): TensorClassforward(input: AnyTensor): AnyTensortoString(): string
Flatten
extends ModuleFlattens a contiguous range of dims into a single dim.
Negative startDim / endDim count from the last dimension. A 0-d input is flattened to shape [1], as in PyTorch.
const flatten = new Flatten(); // default: startDim=1, endDim=-1// input: (batch, C, H, W) -> output: (batch, C*H*W)Members (5)
constructor(startDim?: number, endDim?: number)forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Identity
extends ModuleIdentity layer: returns its input unchanged (the same object, no copy).
Useful for skip connections and placeholder layers.
const identity = new Identity();const output = identity.forward(input); // output === inputMembers (4)
forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
Unflatten
extends ModuleUnflattens a single dim into multiple dims.
At most one entry of unflattenedSize may be -1; it is inferred from the size of the dimension being split.
const unflatten = new Unflatten(1, [2, 5, 5]);// input: (batch, 50) -> output: (batch, 2, 5, 5) const inferred = new Unflatten(1, [2, -1]);// input: (batch, 50) -> output: (batch, 2, 25)Members (5)
constructor(dim: number, unflattenedSize: readonly number[])forward(input: GradTensor): GradTensorforward(input: Tensor): Tensorforward(input: AnyTensor): AnyTensortoString(): string
import { randn, tensor } from "deepbox/ndarray";import { Conv2d, Embedding, Flatten, Linear, MaxPool2d, ReLU, Sequential,} from "deepbox/nn"; const cnn = new Sequential( new Conv2d(1, 4, 3, { padding: 1 }), new ReLU(), new MaxPool2d(2), new Flatten(), new Linear(4 * 14 * 14, 10)); const images = randn([2, 1, 28, 28]); // [batch, channels, height, width]console.log(cnn.forward(images).shape); // [2, 10] const embedding = new Embedding(100, 16);console.log(embedding.forward(tensor([[1, 2, 3]], { dtype: "int32" })).shape); // [1, 3, 16]Found a mistake? Open an issue.