There was an error while loading. Please reload this page.
1 parent 18672fb commit 9b95475Copy full SHA for 9b95475
2 files changed
python/mlx/nn/layers/normalization.py
@@ -64,12 +64,19 @@ def __call__(self, x: mx.array) -> mx.array:
64
f"InstanceNorm expects inputs with at least 3 dimensions"
65
f" (N, ..., C) but the input has {x.ndim} dimensions."
66
)
67
- reduction_axes = tuple(range(1, x.ndim - 1))
68
- # Compute stats
69
- mean = mx.mean(x, axis=reduction_axes, keepdims=True)
70
- var = mx.var(x, axis=reduction_axes, keepdims=True)
71
- # Normalize
72
- x = (x - mean) * mx.rsqrt(var + self.eps)
+ batch_size, features = x.shape[0], x.shape[-1]
+ spatial_shape = x.shape[1:-1]
+ channels_first = mx.transpose(x, (0, x.ndim - 1, *range(1, x.ndim - 1)))
+ x = mx.fast.layer_norm(
+ channels_first.reshape(batch_size, features, -1),
+ None,
73
74
+ self.eps,
75
+ )
76
+ x = mx.transpose(
77
+ x.reshape(batch_size, features, *spatial_shape),
78
+ (0, *range(2, len(spatial_shape) + 2), 1),
79
80
# Scale and shift if necessary
81
return (self.weight * x + self.bias) if "weight" in self else x
82
python/tests/test_nn.py
@@ -693,6 +693,21 @@ def test_instance_norm(self):
693
]
694
self.assertTrue(x.shape == y.shape)
695
self.assertTrue(np.allclose(y, expected_y, atol=1e-5))
696
+ # Reduced-precision statistics must not overflow for finite feature maps.
697
+ checkerboard = np.indices((4, 4, 4)).sum(axis=0) % 2
698
+ x = mx.array(
699
+ np.stack(
700
+ [
701
+ np.where(checkerboard, -512, 512),
702
+ np.where(checkerboard, -256, 256),
703
+ ],
704
+ axis=-1,
705
+ ).astype(np.float16)
706
+ )[None]
707
+ y = nn.InstanceNorm(dims=2)(x)
708
+ self.assertEqual(y.dtype, mx.float16)
709
+ self.assertTrue(mx.allclose(y.min(), mx.array(-1.0, dtype=mx.float16)))
710
+ self.assertTrue(mx.allclose(y.max(), mx.array(1.0, dtype=mx.float16)))
711
# Test repr
712
self.assertTrue(str(inorm) == "InstanceNorm(3, eps=1e-05, affine=False)")
713
# Raise for inputs without spatial dimensions
0 commit comments