Scientific ML · E42 · Implementation

Build a sinusoidal coordinate network with the right initialization

A SIREN baseline maps coordinates to a field. Its frequency scale and weight initialization are part of the architecture—not incidental optimizer settings.

PyTorch nn.LinearCustom SineLayerBenchmark harness
A coordinate network maps locations to field values through sine activations; the illustrated field is conceptual.
Figure 1. A field from coordinates. A coordinate network maps locations to field values through sine activations; the illustrated field is conceptual. Illustrative coordinate field. Original vector illustration.

Follow the information

From input to outcome

Coordinates are the input, not an image tensor. Learned sine features produce the queried field value; observations and constraints enter a separate training objective.

Coordinates are the input, not an image tensor. Learned sine features produce the queried field value; observations and constraints enter a separate training objective.
Figure 2. Information flow. Solid arrows carry observations, tensors or artifacts; other routes are explicitly labelled. Signal shapes, matrices and network icons are schematic, not measured samples or literal neuron counts. Open full-size SVG ↗ On narrow screens, scroll the diagram horizontally.

Read this alongside Figure 1: A coordinate network maps locations to field values through sine activations; the illustrated field is conceptual. The module map and layer-level figures below expand the operations in this route.

Build a sinusoidal coordinate network with the right initialization: architectureSpatial coordinates: Continuous query points → First sine layer: Frequency-scaled affine map → Hidden sine layers: Periodic representation → Linear field head: Predicted scalar / channels → Training loss: Samples and declared constraints. A high-level module map; comparison branches and training details are explained in the article.SCIENTIFIC ML / E42 / MODULE MAP01 INPUTSpatial coordinatesContinuous query points02 MODULEFirst sine layerFrequency-scaled affine map03 MODULEHidden sine layersPeriodic representation04 MODULELinear field headPredicted scalar / channels05 OUTPUTTraining lossSamples and declared constraints
Source-grounded module map. Boxes summarize operations, not individual neurons; comparison arms and training paths are detailed below. On a small screen, scroll the diagram horizontally.
Spatial coordinates — Continuous query points

The architecture in context

The system we are building

A coordinate network stores a field in its parameters and can be queried between training points. The archived SIREN implementation uses sine activations rather than a conventional ReLU stack. That makes frequency scale and initialization especially important: poorly scaled affine inputs can send both activations and derivatives into an unhelpful regime.

Who does what in the stack

PyTorch nn.Linear
Learns affine coordinate transformations.
Custom SineLayer
Implements periodic activation and scaled initialization.
Benchmark harness
Specifies observations and comparator information.

The project implements a SineLayer with separate first-layer and hidden-layer initialization, then uses it as a comparator for operator-based representations. SIREN is an established upstream architecture; the local contribution is a baseline implementation and the experiment around it.

Framework responsibility map. Each row maps a library or custom component to its job; rows are not a sequential inference graph.
Framework responsibility map. Each row maps a library or custom component to its job; rows are not a sequential inference graph. Open full-size SVG ↗

From module map to executable structure

Inside SIREN coordinate baseline

2D coordinate input; width 64; first sine layer plus three additional sine layers; omega 0=30.

Layer-level implementation. B denotes batch size; parameter and shape conventions are expanded in the table.
Layer-level implementation. B denotes batch size; parameter and shape conventions are expanded in the table. Open full-size SVG ↗
Layer / tensor / operation ledger
Layer or branchOutput shapeImplementation detail
CoordinatesN × 2Spatial x and row coordinate y, not image patches.
Linear 2→64 + sineN × 64sin(30·affine); first-layer initialization bound 1/2.
Three Linear 64→64 + sineN × 64Hidden initialization bound sqrt(6/64)/30.
Linear 64→1N × 1Final linear preactivation.
Sigmoid occupancyN × 1MSE is applied after sigmoid, despite the SDF filename.

Sine activations carry high-frequency variations through a coordinate MLP. Their scale and initialization must be considered together: multiplying preactivations by 30 also scales derivatives. The final sigmoid bounds predictions but can saturate, reducing the gradient on confidently wrong occupancy values.

The equation and the update

hl+1=sin⁡(30(Wlhl+bl)),L=1N∑i(σ(fθ(xi))−yi)2h_{l+1}=\sin(30(W_lh_l+b_l)),\qquad \mathcal L=\frac 1N\sum_i(\sigma(f_\theta(x_i))-y_i)^2

Adam 1e-4, full coordinate batch, MSE(sigmoid(model(coords)), target); epoch count is a caller argument. The baseline fits sampled occupancy; the operator comparison receives exact innovation information.

Learning or solution path. A parameter-update path is different from the forward inference path; see text for target-network, frozen-feature and local-loss boundaries.
Learning or solution path. A parameter-update path is different from the forward inference path; see text for target-network, frozen-feature and local-loss boundaries. Open full-size SVG ↗

Implementation card / no invented benchmarks

Capacity, budget and execution evidence

Parameters / retained state
12,737 scalars including biases.
Duration and hardware evidence
The function measures training milliseconds, but this card does not substitute a new timing for an unidentified run.
Source coordinates
E42 lines 49–118
Current reproduction context
Current workstation, supplied by the author: Apple M4, 128 GB unified RAM, 40 GPU cores and 16 CPU cores. This is context for prospective reproduction, not attribution of every archived run. Python and framework versions are not fully locked for these historical sources; declarations, when available, are identified separately.

Counts above are calculated from the stated layer shapes unless identified as saved measurements. They exclude optimizer state and nontrainable buffers. No archived training was rerun for this revision.

What these design choices change

Width increases stored weights roughly quadratically in the hidden layers; more coordinates increase training activation memory without changing parameter count. Equal parameter count does not imply equal information access when one comparison arm receives exact edge innovations.

Reproduction and measurement protocol

Test coordinate normalization and the target’s meaning first. An occupancy discontinuity is not a signed distance function. Plot boundary localization as well as global MSE; a blurred edge can have reasonable average error while failing the geometric task.

For a new run, save the resolved Python/framework versions, backend, dtype, seed, input shapes, batch size and exact source revision. Start with one batch and one update. Log training steps separately from epochs or environment steps. Do not equate the configured maximum with a completed budget or convergence.

Measure initialization/compilation, data preparation, warmed forward pass, training updates and evaluation separately. Synchronize accelerator work around timed regions using the chosen framework’s supported mechanism. Report peak process memory and framework allocation separately; parameter bytes exclude activations, gradients, optimizer state and input buffers. On a shared machine, begin with a single CPU worker and a small batch rather than claiming all available resources.

A closer look at the implementation

The code that carries the idea

The excerpt initializes first-layer weights using the input width, while later layers include the frequency scale in the bound. Forward evaluation applies sine to a scaled affine transform. Reproducing only the sine activation while omitting these conventions would not reproduce this baseline.

Python · file · lines 49–69
class SineLayer(nn.Module):
    def __init__(self, in_features: int, out_features: int, omega0: float, is_first: bool = False) -> None:
        super().__init__()
        self.linear = nn.Linear(in_features, out_features)
        self.omega0 = float(omega0)
        self.is_first = bool(is_first)
        self.reset_parameters()

    def reset_parameters(self) -> None:
        with torch.no_grad():
            in_features = self.linear.weight.shape[1]
            if self.is_first:
                bound = 1.0 / in_features
            else:
                bound = np.sqrt(6.0 / in_features) / self.omega0
            self.linear.weight.uniform_(-bound, bound)
            self.linear.bias.uniform_(-bound, bound)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return torch.sin(self.omega0 * self.linear(x))

Verbatim archive excerpt from compare_siren_sdf.py. Context-dependent historical code, not a standalone runnable program. Comments retain their original wording; the article distinguishes implemented behavior from stale or overbroad comments.

The boundary that matters

The surrounding comparison includes an operator reconstruction supplied with exact innovation moments. That is a different information interface from learning solely from point samples. Any speed or accuracy comparison must expose the cost and availability of those moments.

Keep building

Other posts of interest