tracel-ai/burn · error
Standard deviation is required to be non-negative, but got {
Error message
Standard deviation is required to be non-negative, but got {} What it means
GaussianNoiseConfig::init in burn-nn panics when the configured standard deviation is negative (std.is_sign_negative() is true, which also catches -0.0). A Gaussian noise layer is parameterized by a standard deviation, which is mathematically undefined for negative values, so the library rejects the config at initialization time rather than producing undefined sampling behavior later.
Source
Thrown at crates/burn-nn/src/modules/noise.rs:36
/// distortion.
///
/// Should be created with [GaussianNoiseConfig].
#[derive(Module, Debug)]
#[module(custom_display)]
pub struct GaussianNoise {
/// Standard deviation of the normal noise distribution.
pub std: f64,
/// Whether to behave as during training. Cleared by
/// [`freeze`](burn::module::Module::freeze) and matching
/// [`freeze_group`](burn::module::Module::freeze_group) traversals.
pub training: Param<Flag>,
}
impl GaussianNoiseConfig {
/// Initialize a new [Gaussian noise](GaussianNoise) module.
pub fn init(&self) -> GaussianNoise {
if self.std.is_sign_negative() {
panic!(
"Standard deviation is required to be non-negative, but got {}",
self.std
);
}
GaussianNoise {
std: self.std,
training: Param::from_bool(true),
}
}
}
impl GaussianNoise {
/// Applies the forward pass on the input tensor.
///
/// See [GaussianNoise](GaussianNoise) for more information.
///
/// # Shapes
///View on GitHub (pinned to d16f7ba2ed)
Solutions
- Pass a non-negative standard deviation to GaussianNoiseConfig::new(...) (strictly positive if you want actual noise; use 0.0 to disable).
- Clamp computed values: std = std.max(0.0) before constructing the config.
- If std comes from a sweep or external config, validate range (0.0..=upper_bound) before init().
- Check for accidental sign flips in the expression that produces std.
Example fix
// before let cfg = GaussianNoiseConfig::new(-0.5); let noise = cfg.init(); // panics // after let sigma = 0.5_f64.max(0.0); let cfg = GaussianNoiseConfig::new(sigma); let noise = cfg.init();
Defensive patterns
Strategy: validation
Validate before calling
// before GaussianNoiseConfig::init()
assert!(!std_dev.is_sign_negative(), "std must be non-negative, got {}", std_dev); Type guard
fn is_valid_std(std: f64) -> bool {
std.is_finite() && !std.is_sign_negative()
} Try / catch
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| config.init()));
match result {
Ok(module) => module,
Err(_) => GaussianNoiseConfig::new(0.0).init(), // noise disabled fallback
} Prevention
- Clamp any computed sigma with .max(0.0) before constructing the config.
- Validate externally-sourced noise magnitudes are in a sane range (0.0..=1.0) at load time.
- Watch for -0.0: is_sign_negative() rejects it too, so normalize -0.0 to 0.0.
When it happens
Trigger: Calling GaussianNoiseConfig::init() (or building it via GaussianNoiseConfig::new(std)) with a negative std, e.g. GaussianNoiseConfig::new(-0.5). Also triggered by std = -0.0, or a std computed from a formula/sign-flip (e.g. -temperature, 1.0 - x where x > 1) that went negative at runtime.
Common situations: Sign errors when wiring hyperparameters (noise = -sigma), loading noise magnitude from a config file with a stray minus sign, computing std as a difference that underflows below zero (e.g. start_noise - end_noise with swapped bounds), or hand-tuned sweeps that iterate sigma over a range including negatives.
Related errors
- Both channels must be divisible by the number of groups. Got
- Channels must be divisible by the number of groups. Got chan
- Dropout probability should be between 0 and 1, but got {}
- Either output_size or scale_factor must be provided
- Scale factor for height is too large
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/25f10a405a9bf98e.
Report an issue: GitHub.