wikillm

Paper · 2021-04-08 · cs.CV, cs.GR

Modulated Periodic Activations for Generalizable Local Functional Representations

A ReLU modulator maps a latent code to per-layer gains on a sine-activated synthesis MLP, so one network fits many signals. A grid of tile latents gives local representations. Author-reported: CelebA 32x32 PSNR 29.42 (best of the compared methods), Div2K images PSNR 38.03 at about 15 s encoding, ShapeNet car Chamfer median 0.00230.

Implicit neural representation (INR)Multi-layer perceptron (MLP)neural-fieldsperiodic-activationsmodulationauto-decoderlocal-representation

arXivPDFCodeMarkdown13 min read

AI-compiled by claude-haiku-5-5 on 2026-11-09, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

Many signals, such as photos, video frames, 3D shapes or lighting setups, can be stored as a small neural network that answers "what colour or distance is at this position?". Usually one network is trained for each signal, which is slow and does not carry over to new signals. This paper trains one shared model that can represent many signals. Each signal gets a short list of numbers, its latent code, and a second small network turns that code into instructions that shape the main network.

The main network uses wave-like (sine) activation functions, which capture fine detail well. The second network, which reads the code, controls how strong each layer of the main network is and how it bends. Feeding the code in as an extra input works poorly with waves, so the code is used as this control signal instead.

To handle large images, the signal is cut into a grid of overlapping tiles. Each tile gets its own code, and the tiles are blended at the seams. The codes can be produced by an encoder network, or they can be found by optimising them against a fixed model. The result is a compact, continuous representation that can be queried at any position, including between the original pixels.

TL;DR

A synthesis MLP with sine activations is gated layer by layer by a ReLU modulator that reads a per-signal latent code, so one trained model represents many images, videos or shapes. Tiling the signal into overlapping local patches, each with its own code, scales the method to high-resolution inputs. Author-reported results beat the compared MLP baselines on CelebA, CIFAR-10, ShapeNet cars, Vimeo-90k and Div2K, and encode high-resolution images in about 15 s instead of about 60 min per image. Released code exists but has no licence, so use it to check details, not to copy text.

Problem

Coordinate MLPs (implicit or functional representations) are usually fitted to one signal at a time. Generalising them to many signals costs quality: the paper reports that its baselines degrade or fail to converge on varied data §4.1 tab. 2. Two obstacles are named. ReLU MLPs miss high-frequency detail, and sine networks do not accept a latent code in the obvious way. Concatenating the code to the coordinates only shifts the phase of the first layer, which the paper calls a severe expressivity limit §3.2 eq. 6 fig. 4. Global fits of large images also need costly models, because a full image has a broad frequency spectrum §1 fig. 2.

Method

The model has two parts, a synthesis network and a modulation network, both defined in §3.1.

Synthesis network §3.1.1. Coordinates x in the input domain (n = 2 for images) pass through K hidden layers. Each layer multiplies a sine of an affine map of the previous hidden features by a modulation vector alpha_i. The output layer is linear to m = 3 colour channels eq. 1 eq. 2.

Modulation network §3.1.2. A ReLU MLP reads the latent code z (d = 256 in the paper §3.1) and produces one modulation vector per hidden layer. The paper feeds z into every layer as a skip connection eq. 3 eq. 4. Because alpha_i scales the amplitude of each sine layer, z also changes the frequency and phase of later layers, since the modulated outputs feed the next sine §3.1.2 eq. 5.

Expressivity §3.2. Concatenating z with x before the first sine layer eq. 6 changes only the phase of that layer. The paper's modulator instead controls amplitude, frequency and phase at every layer fig. 4.

Local functional representation §3.3. The domain is split into a regular grid of tiles, and each tile gets its own latent code z_i. The tile function receives normalised local coordinates in [0, 1]^n. Tiles overlap, and the contributions of overlapping tiles are weighted linearly by distance to tile centres §3.3 fig. 5. The paper says the weighting is n-linear; it does not state the overlap ratio.

Training §3.4.

  • Auto-encoder §3.4.1: a convolutional encoder predicts z from the discrete signal; encoder, modulator and synthesis are trained together §4.1.
  • Auto-decoder §3.4.2: the codes for all training signals are optimised together with the network weights, as in DeepSDF. A new signal is fitted by optimising a fresh code with the weights frozen, using the same objective. Codes start from N(0, s²) with s = 10^-2 §3.4.2.

Pseudocode for one modulated evaluation. The paper gives no frequency scale, so omega is a placeholder (see Hyperparameters and Paper vs code).

Pseudocode
# Modulated synthesis for one signal or tile  [§3.1] [eq. 2] [eq. 3-4]
# Input:  coords (N, 2) in [0, 1]^2; latent (256,)
# Output: rgb (N, 3)

def modulated_synthesis(coords, latent, params):
    # Modulator: ReLU MLP on the latent, one gain vector per hidden layer
    # [§3.1.2] [eq. 3] [eq. 4]
    gains = modulator(latent, params.modulator)  # K vectors, each (W,)
    # First sine layer; the paper gives no frequency scale, so omega is
    # a free choice here [§3.1.1] [eq. 2]
    hidden = sin(omega * (coords @ w_first.T + b_first))  # (N, W)
    for i in range(K):
        # Gate each hidden layer: alpha_i * sin(W_i h + b_i)  [§3.1.1] [eq. 2]
        pre = hidden @ w[i].T + b[i]  # (N, W)
        hidden = gains[i] * sin(pre)  # (N, W)
    # Linear read-out to colour  [§3.1.1] [eq. 1]
    return hidden @ w_out.T + b_out  # (N, 3)

Local evaluation at a query point. The paper states the blending in words §3.3 fig. 5; the exact weights are an implementation choice.

Pseudocode
# Local evaluation at one query point  [§3.3] [fig. 5]
# Input:  x (2,) in the signal domain; codebook (T, 256), one code per tile

def local_value(x, codebook):
    # Find the overlapping tiles whose support contains x  [§3.3]
    tiles = covering_tiles(x)
    total = zeros(3)
    for tile in tiles:
        # Normalised coordinates inside this tile  [§3.3]
        local = (x - tile.origin) / tile.size  # (2,)
        # Linear weight from the distance to the tile centre  [§3.3]
        weight = linear_weight(x, tile.centre)  # scalar
        # Tile function with this tile's code  [§3.3] [eq. 2-4]
        value = modulated_synthesis(local, codebook[tile.id])
        total = total + weight * value
    # Normalisation of the weights is not stated in the paper
    return total

Test-time fitting in the auto-decoder setting. The paper states the initialisation and the objective, but not the optimiser, learning rate or step count.

Pseudocode
# Auto-decoder fitting of a new signal  [§3.4.2]
# Network weights are frozen; only the latent code is optimised.

def fit_latent(coords, targets, params, steps):
    # Random start, N(0, s^2) with s = 1e-2  [§3.4.2]
    latent = normal(0.0, 1e-2, size=(256,))
    for step in range(steps):
        # Same objective as in training, with weights fixed  [§3.4.2] [eq. 7]
        output = modulated_synthesis(coords, latent, params)
        loss = mean((output - targets) ** 2)  # (scalar)
        # Optimiser and learning rate are not stated in the paper
        latent = latent - learning_rate * grad(loss, latent)
    return latent

Hyperparameters

Values are as the paper states them unless the Where column names the code. "Not stated" means the text read did not give a value.

NameValueWhereNotes
Latent dimension d256§3.1Code uses 256 for CIFAR and CelebA modsiren.yml; 64 in the single-image config modsiren.yml
Input / output dims (images)n = 2, m = 3§3.1Pixel coordinates to RGB
Activationssine (synthesis), ReLU (modulator)§3.1.1 §3.1.2
Synthesis hidden layers Knot statedCode: 4 modsiren.yml
Hidden widthnot statedCode: 256 modsiren.yml
Sine frequency scale omeganot statedCode: 30 in hidden layers models_bak.py; first layer uses freq_scale, which is 1.0 in the image configs modsiren.yml
Tile size32 x 32 (Div2K)§4.2Code: tile_size 32 modsiren.yml
Tile overlap"overlapping", ratio not stated§3.3Code: half-cell offsets, codebook of (2 x cells)^2 codes train_single_img_patches.py
Latent init, auto-decoderN(0, s^2), s = 1e-2§3.4.2Code: var_factor 1e-3 for image configs modsiren.yml; 1e-4 for shapes modsiren.yml
Training epochs1000 for all models§4.1Code: 400 for CIFAR modsiren.yml; 1000 for the large CelebA config modsiren_large_32.yml; 500 for single image modsiren.yml; 1000 for shapes modsiren.yml
Optimisernot statedCode: Adam train_img_gen.py
Learning ratenot statedCode: 1e-4 modsiren.yml
Batch sizenot statedCode: 128 for CIFAR modsiren.yml; 64 for single image modsiren.yml
Latent L2 regularisernot statedCode: reg_lam 0.1 modsiren.yml applied to mean of z^2 train_img_gen.py
Image losssquared L2§4.1 eq. 7Code averages over pixels train_img_gen.py
Shape lossL1 penalty on SDF§4.1Code clamps SDF to +/-0.1 modsiren.yml train_shape_gen.py
CelebA crop and size128 x 128 centre crop, resampled to 64 and 32 (bicubic)§4.1Evaluated at 1x (32) and 2x (64)
CIFAR-10full image, resampled to 64 and 32§4.12x ground truth is bilinear per Table 2 caption, see Pitfalls
Video tile32 x 32 x 7§4.1 §4.2Random crops in training
Shape samples500 K points per shape, half near the surface§4.1ShapeNet cars, 3514 shapes tab. 3
Scene training48^3 voxels from Scene A§4.2Scene B fitted by optimising latent codes only
FFN scale sigma1 and 10 compared; sigma = 10 called "recommended"§4.1 tab. 1 tab. 2Scale strongly affects continuity
Relighting data90 cropped 300 x 300 images, 80 train / 10 val§4.3Input: pixel x in R^2, light direction z in R^3; output RGB

Results

Author-reported. The paper does not state the hardware in the text read. Baselines are ReLU-MLP, FFN, SIREN+ (sine network with the latent concatenated to coordinates), and HyperNet-SIREN §4. Each table is cited in the Source column.

Global generalisation, CelebA (32 x 32 training images, 1x and 2x PSNR) tab. 1:

MethodPSNR 1xPSNR 2xParamsSource
ReLU28.3124.911.1 Mtab. 1
SIREN+20.1519.191.1 Mtab. 1
FFN sigma = 1026.484.221.2 Mtab. 1
FFN sigma = 127.8724.371.2 Mtab. 1
HyperNet-SIREN26.7024.5472 Mtab. 1
Ours29.4225.491.3 Mtab. 1
Ours, large conv. encoder29.6426.0517 Mtab. 1

Global generalisation, CIFAR-10 (10 K test images; PSNR 1x and 2x) tab. 2:

MethodPSNR 1xPSNR 2xSource
ReLU23.6525.18tab. 2
SIREN+not convergednot convergedtab. 2
FFN sigma = 1022.755.75tab. 2
FFN sigma = 124.9725.51tab. 2
HyperNet-SIREN18.0719.16tab. 2
Ours25.7327.05tab. 2

ShapeNet cars, auto-decoder, bi-directional Chamfer distance (3514 shapes) tab. 3:

MethodMedianMeanStdSource
DeepSDF0.002840.003630.00559tab. 3
DeepSDF + SIRENnot convergednot convergednot convergedtab. 3
DeepSDF + FFN0.003990.005190.00757tab. 3
Ours0.002300.002730.00285tab. 3

Video, Vimeo-90k (7 K test videos, PSNR) tab. 4:

MethodPSNRSource
ReLU23.06tab. 4
SIREN+does not convergetab. 4
FFN19.38tab. 4
HyperNet-SIREN23.61tab. 4
Ours25.28tab. 4

Local, Div2K (50 unseen 2K images, 32 x 32 tiles; PSNR 1x) tab. 5. Global methods are overfitted per image; the local methods are pre-trained:

MethodLocalPSNR 1xEncoding timeSource
ReLUno18.94~60 mintab. 5
SIRENno22.88~60 mintab. 5
FFNno28.48~60 mintab. 5
Ours-ReLUyes34.7313 stab. 5
Oursyes38.0315 stab. 5

3D scenes, ThreedScans, Chamfer distance x 10^-5 tab. 6:

MethodLocalScene A (9 shapes)Scene B (9 shapes)Source
ReLUno2.163.61tab. 6
SIRENno2.007.36tab. 6
FFNno1.933.54tab. 6
Ours-ReLUyes1.378.37tab. 6
Oursyes1.322.40tab. 6

Videos, high resolution (6 Pexels clips at 640 x 256; PSNR) tab. 7:

MethodPSNREncoding timeSource
ReLU19.28~15 htab. 7
FFN20.87~15 htab. 7
SIREN25.19~15 htab. 7
Ours-Generalized25.21~1 mintab. 7

The text says this is about 1000x faster §4.2; the table times give roughly 900x. Relighting is shown qualitatively only §4.3 fig. 11. Qualitative results are also shown for CelebA fig. 7, cars fig. 8, video cuts fig. 9 and 3D scenes fig. 10.

Paper vs code

Official code: https://github.com/ishit/modsiren, cloned at commit 6108cc1fafb8eea2dda2891e029e483944f3a886. The paper does not link it. The paper has no project page link, and the arXiv metadata has no comments field. GitHub search on the title phrases and method phrases returned nothing. The repository was found through the first author's account (ishit, profile name Ishit Mehta). Its folder and script names match the paper's experiments (CelebA, CIFAR, Div2K, video, shapes, relighting). The repository has no README and no LICENSE, so it is cited only, with no verbatim snippets. Attribution rests on the owner check above and should be confirmed by a human before the card is reviewed.

Discrepancies between paper and code. Each item cites both sides.

  • Layer gating indices. Paper eq. 3 defines the modulator's first output h'_0 but gives alpha_{i+1} = h'_{i+1}, so alpha_1 is never defined eq. 3 eq. 4. The code applies a sine layer with no gate first, then gates the next K sine layers models_bak.py.
  • Modulator skip. Paper feeds z into every modulator layer by concatenation ([h_i z]) eq. 4. The code adds a skip of the first-layer embedding after each ReLU layer models_bak.py. The cleaner ModSiren class in the release does not re-feed z at all, and gates only the first K-1 hidden layers models.py.
  • Frequency. Paper eq. 2 has no frequency scale eq. 2. The code uses omega = 30 in hidden layers, and the first layer uses freq_scale (1.0 in the image configs). Init is uniform in +/- sqrt(6/n)/omega models_bak.py models_bak.py modsiren.yml.
  • Modulator input. Paper says the modulator acts on z alone §3.1.2. The single-image config sets concat: True, which also feeds coordinates into the modulator modsiren.yml models_bak.py.
  • Latent init. Paper uses s = 1e-2 §3.4.2. Image configs use 1e-3 modsiren.yml and shape configs 1e-4 modsiren.yml.
  • Epochs. Paper says all models train for 1000 epochs §4.1. The CIFAR config uses 400 modsiren.yml.
  • Image loss. Paper eq. 7 is a squared L2 norm with no regulariser eq. 7. The code takes the mean of the squared error over elements and adds reg_lam times mean z^2 train_img_gen.py. The relative weight of the regulariser depends on that normalisation, and the paper does not say which one it uses.
  • Shape loss. Paper uses an L1 penalty §4.1. The code clamps both prediction and ground-truth SDF to +/-0.1 before the L1 loss train_shape_gen.py train_shape_gen.py modsiren.yml.
  • Config names. config/img_gen/celeba/modsiren_32.yml points to a castle image, not CelebA modsiren_32.yml. The mapping from config files to the table rows is therefore inferred, not stated.
  • Two model files. The image scripts import LocalMLP from models_bak.py train_img_gen.py, not from models.py. Results should be traced to models_bak.py.

Not compared: the toy concatenation experiment (concat_expriment/main.py), the relighting and video scripts, and the encoder architectures. The tile-blending weights are compared only in Pitfalls, because the paper leaves them unspecified.

Pitfalls

  • Gate indexing is ambiguous (see Paper vs code). An implementer must choose whether the first sine layer is gated, and whether the modulator emits K or K+1 vectors. The code gates K layers after an ungated first layer.
  • The frequency scale is not in the paper. The code's omega = 30 with SIREN-style init is a large effective frequency. A reimplementation following eq. 2 literally, with no omega and default init, will produce different detail.
  • Test-time fitting is under-specified. The optimiser, learning rate and step count are not stated. Only the initial code scale is given §3.4.2. The released test-time routine uses Adam with a separate val_lr setting, which is not in the image configs read here train_img_gen.py modsiren.yml.
  • Tile overlap and blend weights are not given. The code uses half-cell offsets and a linear ramp over half a cell, applied along rows and then columns train_single_img_patches.py. Normalisation is not stated.
  • Continuity depends sharply on the FFN scale. With sigma = 10, FFN's 2x PSNR falls to 4.22 on CelebA tab. 1 and to 5.75 on CIFAR-10 tab. 2.
  • Dataset counts disagree. The text gives CelebA as 167 K train and 33 K test §4.1, but the Table 1 caption says 200 K images.
  • CIFAR-10 2x evaluation disagrees. The text says ground truth is resampled bicubically §4.1; the Table 2 caption says bilinear upsampling.
  • Costs are hidden in the comparisons. Global baselines are overfitted per image, which takes about 60 min per Div2K image and about 15 h per video tab. 5 tab. 7. The local method's speed depends on a pre-trained model on Vimeo-90k §4.2.
  • HyperNet-SIREN needs about 72 M parameters against 1.3 M for this method tab. 1.
  • SIREN+ does not converge on CIFAR-10 or Vimeo-90k in the authors' runs tab. 2 tab. 4. The paper attributes this to data variability, which it does not test.
  • The Div2K single-instance results use 2K images with 32 x 32 tiles and about 2 M tiles in training §4.2.
  • The released repository has no README and no LICENSE, so reuse terms are unknown. Treat it as reference material only.

Lineage

  • Builds on: sine-activated networks trained for signal fitting (SIREN, Sitzmann et al. 2020), for the sine layers and initialisation §1 models_bak.py. DeepSDF (Park et al. 2019) for the auto-decoder setup §3.4.2. Local shape latents (Chabra et al. 2020; Jiang et al. 2020) for the tiled representation §1. Hypernetworks (Ha et al. 2016) are a baseline §4.
  • Compared against: ReLU-MLP, FFN (Tancik et al. 2020), SIREN+, HyperNet-SIREN §4 fig. 6. DeepSDF and DeepSDF with SIREN or FFN on ShapeNet cars tab. 3. Stated as baselines; no arXiv ids are given in the paper, so none are linked here.
  • Superseded by: not known from content already in this wiki.

Source and license

Adapted from “Modulated Periodic Activations for Generalizable Local Functional Representations” by Ishit Mehta, Michaël Gharbi, Connelly Barnes, Eli Shechtman, Ravi Ramamoorthi, Manmohan Chandraker (arXiv:2104.03960), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/ishit/modsiren at commit 6108cc1fafb8 (none (no LICENSE file in repository)). Any quoted code is shown under that license.