1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// @generated by tool/gen/nn/generate.py; DO NOT EDIT.
// Source: tool/gen/nn/schema/ml/ml_nn_dropout.json
// generator_version=8; schema_sha256=1085da85bad321bbb437d0acc0f39a9f47f779759f0ddfb821c60fc53999e290
use crate::{Error, Matrix, Result, matrix};
use super::super::{Module, ModuleRegistry};
// OA donor: oacpp/source/cpp/lib/oa/ml/nn/dropout/dropout.cpp
// Adaptation: Rust ownership, ModuleRegistry and checked error contracts; preserved operation behavior
/// Inverted Dropout with explicit train/eval behavior.
pub struct Dropout {
probability: f32,
seed: u64,
registry: ModuleRegistry,
}
impl Dropout {
/// Construct Dropout with the thread-local random seed source.
///
/// # Errors
///
/// Returns an error unless `probability` is finite and in `[0, 1)`.
pub fn new(probability: f32) -> Result<Self> {
Self::with_seed(probability, 0)
}
/// Construct Dropout with an explicit Philox seed.
///
/// A nonzero seed makes independently recorded eager calls reproducible.
/// Captured programs still advance their private random counter on every
/// replay. Zero consumes the thread-local seed source when training forward
/// is recorded.
///
/// # Errors
///
/// Returns an error unless `probability` is finite and in `[0, 1)`.
pub fn with_seed(probability: f32, seed: u64) -> Result<Self> {
if !probability.is_finite() || !(0.0..1.0).contains(&probability) {
return Err(Error::invalid_argument(
"Dropout probability must be finite and in [0, 1)",
));
}
Ok(Self {
probability,
seed,
registry: ModuleRegistry::new(),
})
}
/// Return the probability of dropping each element during training.
pub const fn probability(&self) -> f32 {
self.probability
}
/// Apply Dropout in training mode or return an identity handle in eval mode.
///
/// # Errors
///
/// Returns an error from the underlying Matrix operation.
pub fn forward(&self, input: &Matrix) -> Result<Matrix> {
if !self.is_training() || self.probability == 0.0 {
return Ok(input.clone());
}
matrix::dropout(input, self.probability, self.seed)
}
}
impl Module for Dropout {
fn forward(&self, input: &Matrix) -> Result<Matrix> {
Dropout::forward(self, input)
}
fn registry(&self) -> &ModuleRegistry {
&self.registry
}
}