---
title: "ClikaRT::nn::GroupNorm"
sidebar_label: "GroupNorm"
description: "Group normalization. \\[ y = \\frac{x - \\mu_g}{\\sqrt{\\sigma_g^2 + \\varepsilon}} \\cdot \\mathrm{weight} + \\mathrm{bias} \\] with mu_g / sigma_g^2 taken per (sample, group); num_groups must divide the chann…"
---

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

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

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

Group normalization.

$$
y = \frac{x - \mu_g}{\sqrt{\sigma_g^2 + \varepsilon}} \cdot
\mathrm{weight} + \mathrm{bias}
$$

with `mu_g` / `sigma_g^2` taken per `(sample, group)`; [`num_groups`](./GroupNorm.md#num_groups) must divide the channel count, and the channel axis is the last one. The module form of [`ops::group_norm`](../ops/group_norm.md#group_norm).

```cpp
auto gn = ClikaRT::nn::GroupNorm::make(32, 256);
gn->set_weights(gamma, beta);
auto y = (*gn)(x);                 // [N, H, W, 256] -> [N, H, W, 256]
```

## Static member functions

### make() {#make}

<div class="api-signature">

`static` `std::shared_ptr<GroupNorm>` **`make`**(<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::int64_t` `num_groups`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;`std::int64_t` `num_channels`,<br />
&nbsp;&nbsp;&nbsp;&nbsp;[`GroupNormOptions`](./GroupNormOptions.md) `options` `=` `{}`<br />
)

</div>

Construct from config with storage-free slots: registers the `[`[`num_channels`](./GroupNorm.md#num_channels)`]` parameter slots (`weight`, `bias`, when `options.affine`) on `options.dtype` / `options.device`; no weight memory is allocated. The first [`forward`](./GroupNorm.md#forward) builds. Raises [`ClikaRT::Error`](../Error.md) when a count is not positive, when [`num_groups`](./GroupNorm.md#num_groups) does not divide [`num_channels`](./GroupNorm.md#num_channels), or when `eps` is not positive.

<div class="api-declared">

Declared in `ClikaRT/nn/group_norm.h`, line 81

</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; the next [`forward`](./GroupNorm.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/group_norm.h`, line 92

</div>

### \~GroupNorm() {#GroupNorm}

<div class="api-signature">

**`~GroupNorm`**() `override`

</div>

<div class="api-declared">

Declared in `ClikaRT/nn/group_norm.h`, line 96

</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/group_norm.h`, line 100

</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/group_norm.h`, line 101

</div>

### forward() {#forward}

<div class="api-signature">

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

</div>

Normalizes `input` `[N, D1..Dn, C]` per sample and group, applies the affine parameters when declared and 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/group_norm.h`, line 109

</div>

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

<div class="api-signature">

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

</div>

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

<div class="api-declared">

Declared in `ClikaRT/nn/group_norm.h`, line 113

</div>

### num\_groups() {#num_groups}

<div class="api-signature">

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

</div>

The group count the module was made with.

<div class="api-declared">

Declared in `ClikaRT/nn/group_norm.h`, line 118

</div>

### num\_channels() {#num_channels}

<div class="api-signature">

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

</div>

The channel count the module was made with.

<div class="api-declared">

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

</div>

### options() {#options}

<div class="api-signature">

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

</div>

The settings the module was made with.

<div class="api-declared">

Declared in `ClikaRT/nn/group_norm.h`, line 122

</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/group_norm.h`, line 133

</div>
