---
title: "ClikaRT::nn::BatchNorm"
sidebar_label: "BatchNorm"
description: "Batch normalization, inference form. \\[ y = \\frac{x - \\mathrm{running\\_mean}}{\\sqrt{\\mathrm{running\\_var} + \\varepsilon}} \\cdot \\mathrm{weight} + \\mathrm{bias} \\] Every operand is per channel ([C]), t…"
---

<!-- Generated by tools/doxygen2mdx from Doxygen XML. Do not edit. -->

<span class="api-kind api-kind--class">class</span>

**Header:** `ClikaRT/nn/batch_norm.h`  
**Inherits:** [`ClikaRT::nn::Module`](./Module.md)

Batch normalization, inference form.

$$
y = \frac{x - \mathrm{running\_mean}}{\sqrt{\mathrm{running\_var} +
\varepsilon}} \cdot \mathrm{weight} + \mathrm{bias}
$$

Every operand is per channel (`[C]`), the channel axis is the last one, and the stored statistics ARE the statistics (no batch statistics, no momentum). The module form of [`ops::batch_norm`](../ops/batch_norm.md#batch_norm).

```cpp
auto bn = ClikaRT::nn::BatchNorm::make(64);
bn->load_state_dict(checkpoint);   // weight, bias, running_mean, ...
auto y = (*bn)(x);                 // [N, H, W, 64] -> [N, H, W, 64]
```

## Static member functions

### make() {#make}

<div class="api-signature">

`static` `std::shared_ptr<BatchNorm>` **`make`**(`std::int64_t` `num_features`, [`BatchNormOptions`](./BatchNormOptions.md) `options` `=` `{}`)

</div>

Construct from config with storage-free slots: registers the `[`[`num_features`](./BatchNorm.md#num_features)`]` parameter slots (`weight`, `bias`, when `options.affine`) and buffer slots (`running_mean`, `running_var`, plus the `num_batches_tracked` counter) on `options.dtype` / `options.device`; no weight memory is allocated. [`named_parameters()`](./Module.md#named_parameters) and [`named_buffers()`](./Module.md#named_buffers) report the slots, so a strict [`load_state_dict`](./Module.md#load_state_dict) both expects and satisfies them; the first [`forward`](./BatchNorm.md#forward) builds. Raises [`ClikaRT::Error`](../Error.md) on a channel count or `eps` that is not positive.

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 92

</div>

## Member functions

### set\_weights() {#set_weights}

<div class="api-signature">

`void` **`set_weights`**([`Tensor`](../Tensor.md) `weight`, [`OptionalTensor`](../../index.md#OptionalTensor) `bias` `=` `{}`)

</div>

Bind the affine parameters positionally: `weight` (scale, `[C]`) and `bias` (shift, `[C]`). The declared placement wins; shapes must match the declaration. Re-binding drops the built primitive; the next [`forward`](./BatchNorm.md#forward) rebuilds. Raises [`ClikaRT::Error`](../Error.md) on a geometry mismatch or on a module made with `affine = false`.

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 103

</div>

### set\_running\_stats() {#set_running_stats}

<div class="api-signature">

`void` **`set_running_stats`**([`Tensor`](../Tensor.md) `running_mean`, [`Tensor`](../Tensor.md) `running_var`)

</div>

Bind the statistics positionally: `running_mean` and `running_var`, both `[C]`. Same placement and shape rules as [`set_weights`](./BatchNorm.md#set_weights); the next [`forward`](./BatchNorm.md#forward) rebuilds. Raises [`ClikaRT::Error`](../Error.md) on a geometry mismatch.

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 112

</div>

### \~BatchNorm() {#BatchNorm}

<div class="api-signature">

**`~BatchNorm`**() `override`

</div>

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 116

</div>

### to\_impl(StreamOrDevice) {#to_impl}

<div class="api-signature">

`virtual` [`Result`](../Result.md)`<void>` **`to_impl`**([`StreamOrDevice`](../StreamOrDevice.md) `where`) `override`

</div>

Move to a placement ([`Device`](../Device.md) / [`Stream`](../Stream.md)) or cast to a dtype. Rebuilds over the moved slots on the next forward.

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 120

</div>

### to\_impl(DataType) {#to_impl-2}

<div class="api-signature">

`virtual` [`Result`](../Result.md)`<void>` **`to_impl`**([`DataType`](../../index.md#DataType) `dtype`) `override`

</div>

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 121

</div>

### forward() {#forward}

<div class="api-signature">

[`Tensor`](../Tensor.md) **`forward`**([`Tensor`](../Tensor.md) `input`) `const`

</div>

Normalizes `input` `[N, D1..Dn, C]` with the stored statistics and the affine parameters, then the fused activation when set; output shape and dtype follow `input`. The first call builds (once, thread-safe). Raises [`ClikaRT::Error`](../Error.md) when a slot is still unbound or the channel count does not match.

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 129

</div>

### operator()() {#operator-call}

<div class="api-signature">

[`Tensor`](../Tensor.md) **`operator()`**([`Tensor`](../Tensor.md) `input`) `const`

</div>

Same as [`forward`](./BatchNorm.md#forward).

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 133

</div>

### num\_features() {#num_features}

<div class="api-signature">

`std::int64_t` **`num_features`**() `const noexcept`

</div>

The channel count the module was made with.

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 138

</div>

### options() {#options}

<div class="api-signature">

`const` [`BatchNormOptions`](./BatchNormOptions.md)`&` **`options`**() `const noexcept`

</div>

The settings the module was made with.

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 140

</div>

## Protected member functions

### initialize\_impl() {#initialize_impl}

<div class="api-signature">

`virtual` [`Result`](../Result.md)`<void>` **`initialize_impl`**() `override`

</div>

The pack hook ([`Module::initialize_impl`](./Module.md#initialize_impl)): builds the normalization over the bound slots (idempotent, thread-safe). Every declared slot must hold a real (loaded) tensor; a still-unbound slot is a clean error naming it.

<div class="api-declared">

Declared in `ClikaRT/nn/batch_norm.h`, line 151

</div>
