pub struct Dropout<F: Float + Debug + Send + Sync> { /* private fields */ }
Expand description
Dropout layer
During training, randomly sets input elements to zero with probability p
.
During inference, scales the output by 1/(1-p) to maintain the expected value.
§Examples
use scirs2_neural::layers::{Dropout, Layer};
use ndarray::{Array, Array2};
use rand::rngs::SmallRng;
use rand::SeedableRng;
// Create a dropout layer with 0.5 dropout probability
let mut rng = SmallRng::seed_from_u64(42);
let dropout = Dropout::new(0.5, &mut rng).unwrap();
// Forward pass with a batch of 2 samples, 10 features
let batch_size = 2;
let features = 10;
let input = Array2::<f64>::from_elem((batch_size, features), 1.0).into_dyn();
// Forward pass in training mode (some values will be dropped)
let output = dropout.forward(&input).unwrap();
// Output shape should match input shape
assert_eq!(output.shape(), input.shape());
Implementations§
Source§impl<F: Float + Debug + ScalarOperand + Send + Sync + 'static> Dropout<F>
impl<F: Float + Debug + ScalarOperand + Send + Sync + 'static> Dropout<F>
Sourcepub fn new<R: Rng + 'static + Clone + Send + Sync>(
p: f64,
rng: &mut R,
) -> Result<Self>
pub fn new<R: Rng + 'static + Clone + Send + Sync>( p: f64, rng: &mut R, ) -> Result<Self>
Create a new dropout layer
§Arguments
p
- Dropout probability (0.0 to 1.0)rng
- Random number generator
§Returns
- A new dropout layer
Examples found in repository?
examples/model_evaluation_example.rs (line 54)
43 fn build(&self) -> Result<Self::Model> {
44 let mut model = Sequential::new();
45
46 let mut rng = SmallRng::seed_from_u64(42);
47 model.add(Dense::<F>::new(
48 self.input_dim,
49 self.hidden_dim,
50 Some("relu"),
51 &mut rng,
52 )?);
53
54 model.add(Dropout::<F>::new(0.2, &mut rng)?);
55
56 model.add(Dense::<F>::new(
57 self.hidden_dim,
58 self.output_dim,
59 None,
60 &mut rng,
61 )?);
62
63 Ok(model)
64 }
More examples
examples/image_classification_complete.rs (line 165)
151fn build_cnn_model(
152 input_channels: usize,
153 num_classes: usize,
154 rng: &mut SmallRng,
155) -> Result<Sequential<f32>> {
156 let mut model = Sequential::new();
157
158 // First convolutional block
159 model.add(Dense::new(
160 input_channels * 32 * 32,
161 512,
162 Some("relu"),
163 rng,
164 )?);
165 model.add(Dropout::new(0.25, rng)?);
166
167 // Hidden layers
168 model.add(Dense::new(512, 256, Some("relu"), rng)?);
169 model.add(Dropout::new(0.25, rng)?);
170
171 model.add(Dense::new(256, 128, Some("relu"), rng)?);
172 model.add(Dropout::new(0.25, rng)?);
173
174 // Output layer
175 model.add(Dense::new(128, num_classes, Some("softmax"), rng)?);
176
177 Ok(model)
178}
examples/model_architecture_visualization.rs (line 98)
91fn create_mlp_model(rng: &mut SmallRng) -> Result<Sequential<f32>> {
92 let mut model = Sequential::new();
93
94 // Hidden layers with decreasing sizes
95 let dense1 = Dense::new(784, 512, Some("relu"), rng)?;
96 model.add_layer(dense1);
97
98 let dropout1 = Dropout::new(0.2, rng)?;
99 model.add_layer(dropout1);
100
101 let dense2 = Dense::new(512, 256, Some("relu"), rng)?;
102 model.add_layer(dense2);
103
104 let dense3 = Dense::new(256, 128, Some("relu"), rng)?;
105 model.add_layer(dense3);
106
107 let dropout2 = Dropout::new(0.3, rng)?;
108 model.add_layer(dropout2);
109
110 // Output layer
111 let dense4 = Dense::new(128, 10, Some("softmax"), rng)?;
112 model.add_layer(dense4);
113
114 Ok(model)
115}
116
117// Create a simple CNN model for MNIST
118fn create_cnn_model(rng: &mut SmallRng) -> Result<Sequential<f32>> {
119 let mut model = Sequential::new();
120
121 // First convolutional block
122 let conv1 = Conv2D::new(
123 1, // input channels
124 32, // output channels
125 (3, 3), // kernel size
126 (1, 1), // stride
127 PaddingMode::Custom(1), // padding mode
128 rng,
129 )?;
130 model.add_layer(conv1);
131
132 let batch_norm1 = BatchNorm::new(32, 0.99, 1e-5, rng)?;
133 model.add_layer(batch_norm1);
134
135 // Second convolutional block
136 let conv2 = Conv2D::new(
137 32, // input channels
138 64, // output channels
139 (3, 3), // kernel size
140 (2, 2), // stride (downsampling)
141 PaddingMode::Custom(1), // padding mode
142 rng,
143 )?;
144 model.add_layer(conv2);
145
146 let batch_norm2 = BatchNorm::new(64, 0.99, 1e-5, rng)?;
147 model.add_layer(batch_norm2);
148
149 let dropout1 = Dropout::new(0.25, rng)?;
150 model.add_layer(dropout1);
151
152 // Flatten for fully connected layers - commented out as Flatten is not available
153 // let flatten = Flatten::new()?;
154 // model.add_layer(flatten);
155
156 // Dense layers
157 let dense1 = Dense::new(64 * 14 * 14, 128, Some("relu"), rng)?;
158 model.add_layer(dense1);
159
160 let dropout2 = Dropout::new(0.5, rng)?;
161 model.add_layer(dropout2);
162
163 // Output layer
164 let dense2 = Dense::new(128, 10, Some("softmax"), rng)?;
165 model.add_layer(dense2);
166
167 Ok(model)
168}
examples/improved_model_serialization.rs (line 26)
13fn create_xor_model(rng: &mut SmallRng) -> Result<Sequential<f32>> {
14 let mut model = Sequential::new();
15
16 // XOR problem requires a hidden layer
17 let input_dim = 2;
18 let hidden_dim = 4;
19 let output_dim = 1;
20
21 // Input to hidden layer with ReLU activation
22 let dense1 = Dense::new(input_dim, hidden_dim, Some("relu"), rng)?;
23 model.add_layer(dense1);
24
25 // Optional dropout for regularization (low rate as XOR is small)
26 let dropout = Dropout::new(0.1, rng)?;
27 model.add_layer(dropout);
28
29 // Hidden to output layer with sigmoid activation (binary output)
30 let dense2 = Dense::new(hidden_dim, output_dim, Some("sigmoid"), rng)?;
31 model.add_layer(dense2);
32
33 Ok(model)
34}
examples/advanced_training_example.rs (line 37)
20fn create_regression_model<
21 F: Float + Debug + ScalarOperand + Send + Sync + FromPrimitive + 'static,
22>(
23 input_dim: usize,
24 hidden_dim: usize,
25 output_dim: usize,
26) -> Result<Sequential<F>> {
27 let mut model = Sequential::new();
28
29 // Create RNG for initializing layers
30 let mut rng = SmallRng::seed_from_u64(42);
31
32 // First dense layer with ReLU activation
33 let dense1 = Dense::new(input_dim, hidden_dim, Some("relu"), &mut rng)?;
34 model.add(dense1);
35
36 // Dropout layer for regularization
37 let dropout1 = Dropout::new(0.2, &mut rng)?;
38 model.add(dropout1);
39
40 // Second dense layer with ReLU activation
41 let dense2 = Dense::new(hidden_dim, hidden_dim / 2, Some("relu"), &mut rng)?;
42 model.add(dense2);
43
44 // Another dropout layer
45 let dropout2 = Dropout::new(0.2, &mut rng)?;
46 model.add(dropout2);
47
48 // Output layer with no activation
49 let dense3 = Dense::new(hidden_dim / 2, output_dim, None, &mut rng)?;
50 model.add(dense3);
51
52 Ok(model)
53}
examples/text_classification_complete.rs (line 336)
313fn build_text_model(
314 _vocab_size: usize,
315 embedding_dim: usize,
316 hidden_dim: usize,
317 num_classes: usize,
318 max_length: usize,
319 rng: &mut SmallRng,
320) -> StdResult<Sequential<f32>> {
321 let mut model = Sequential::new();
322
323 // Note: This is a simplified version since our Sequential model expects specific layer types
324 // In a real implementation, we'd need specialized text layers
325
326 // Flatten the input tokens and use dense layers to simulate embedding and LSTM processing
327 let input_size = max_length; // Each token position
328
329 // Simulate embedding layer with dense transformation
330 model.add(Dense::new(
331 input_size,
332 embedding_dim * 2,
333 Some("relu"),
334 rng,
335 )?);
336 model.add(Dropout::new(0.1, rng)?);
337
338 // Simulate LSTM processing with dense layers
339 model.add(Dense::new(
340 embedding_dim * 2,
341 hidden_dim,
342 Some("tanh"),
343 rng,
344 )?);
345 model.add(Dropout::new(0.2, rng)?);
346
347 // Add attention-like mechanism with another dense layer
348 model.add(Dense::new(hidden_dim, hidden_dim / 2, Some("relu"), rng)?);
349 model.add(Dropout::new(0.2, rng)?);
350
351 // Classification head
352 model.add(Dense::new(
353 hidden_dim / 2,
354 num_classes,
355 Some("softmax"),
356 rng,
357 )?);
358
359 Ok(model)
360}
361
362/// Build an advanced text model with attention
363fn build_attention_text_model(
364 _vocab_size: usize,
365 embedding_dim: usize,
366 hidden_dim: usize,
367 num_classes: usize,
368 max_length: usize,
369 rng: &mut SmallRng,
370) -> StdResult<Sequential<f32>> {
371 let mut model = Sequential::new();
372
373 // Simplified attention-based model using dense layers
374 let input_size = max_length;
375
376 // Multi-layer processing to simulate transformer-like behavior
377 model.add(Dense::new(input_size, embedding_dim, Some("relu"), rng)?);
378 model.add(Dropout::new(0.1, rng)?);
379
380 // Simulate self-attention with dense layers
381 model.add(Dense::new(embedding_dim, hidden_dim, Some("relu"), rng)?);
382 model.add(Dropout::new(0.1, rng)?);
383
384 // Second attention layer
385 model.add(Dense::new(hidden_dim, hidden_dim, Some("relu"), rng)?);
386 model.add(Dropout::new(0.1, rng)?);
387
388 // Global pooling simulation
389 model.add(Dense::new(hidden_dim, hidden_dim / 2, Some("relu"), rng)?);
390 model.add(Dropout::new(0.2, rng)?);
391
392 // Classification head
393 model.add(Dense::new(
394 hidden_dim / 2,
395 num_classes,
396 Some("softmax"),
397 rng,
398 )?);
399
400 Ok(model)
401}
Sourcepub fn set_training(&mut self, training: bool)
pub fn set_training(&mut self, training: bool)
Set the training mode
In training mode, elements are randomly dropped. In inference mode, all elements are kept but scaled.
Examples found in repository?
examples/dropout_example.rs (line 163)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 println!("Dropout Example");
9
10 // Initialize random number generator with a fixed seed for reproducibility
11 let mut rng = SmallRng::seed_from_u64(42);
12
13 // 1. Example: Simple dropout on a vector
14 println!("\nExample 1: Simple dropout on a vector");
15
16 // Create a vector of ones
17 let n_features = 20;
18 let input = Array2::<f32>::from_elem((1, n_features), 1.0);
19
20 // Create a dropout layer with dropout probability 0.5
21 let dropout = Dropout::new(0.5, &mut rng)?;
22
23 // Apply dropout in training mode
24 let output = dropout.forward(&input.into_dyn())?;
25
26 // Count elements that were dropped
27 let mut dropped_count = 0;
28 for i in 0..n_features {
29 let val = output.slice(ndarray::s![0, i]).into_scalar();
30 if *val == 0.0 {
31 dropped_count += 1;
32 }
33 }
34
35 // Print results
36 println!("Input: Array of {} ones", n_features);
37 println!(
38 "Output after dropout (p=0.5): {} elements dropped",
39 dropped_count
40 );
41 println!(
42 "Dropout rate: {:.2}%",
43 (dropped_count as f32 / n_features as f32) * 100.0
44 );
45
46 // 2. Example: Using dropout in a neural network to prevent overfitting
47 println!("\nExample 2: Using dropout in a simple neural network");
48
49 // Create a simple neural network with dropout
50 // 1. Create dense layer (input -> hidden)
51 let input_dim = 10;
52 let hidden_dim = 100;
53 let output_dim = 2;
54 let dense1 = Dense::new(input_dim, hidden_dim, Some("relu"), &mut rng)?;
55
56 // 2. Create dropout layer (after first dense layer)
57 let dropout1 = Dropout::new(0.2, &mut rng)?;
58
59 // 3. Create second dense layer (hidden -> output)
60 let dense2 = Dense::new(hidden_dim, output_dim, None, &mut rng)?;
61
62 // Generate a random input
63 let batch_size = 16;
64 let mut input_data = Array2::<f32>::zeros((batch_size, input_dim));
65 for i in 0..batch_size {
66 for j in 0..input_dim {
67 input_data[[i, j]] = rng.random_range(-1.0..1.0);
68 }
69 }
70
71 // Forward pass through the network with dropout
72 println!("Running forward pass with dropout...");
73 let hidden_output = dense1.forward(&input_data.clone().into_dyn())?;
74 let hidden_dropped = dropout1.forward(&hidden_output)?;
75 let final_output = dense2.forward(&hidden_dropped)?;
76
77 println!("Input shape: {:?}", input_data.shape());
78 println!("Hidden layer shape: {:?}", hidden_output.shape());
79 println!("Output shape: {:?}", final_output.shape());
80
81 // 3. Example: Dropout in a CNN architecture
82 println!("\nExample 3: Dropout in a CNN architecture");
83
84 // Create a sample CNN architecture with dropout
85
86 // 1. Create convolutional layer
87 let in_channels = 3; // RGB input
88 let out_channels = 16;
89 let conv1 = Conv2D::new(
90 in_channels,
91 out_channels,
92 (3, 3),
93 (1, 1),
94 PaddingMode::Same,
95 &mut rng,
96 )?;
97
98 // 2. Create batch normalization layer
99 let bn1 = BatchNorm::new(out_channels, 0.9, 1e-5, &mut rng)?;
100
101 // 3. Create dropout layer for spatial dropout (dropping entire feature maps)
102 let dropout_conv = Dropout::new(0.25, &mut rng)?;
103
104 // 4. Create flattened dense layer
105 let height = 32;
106 let width = 32;
107 let flattened_size = out_channels * height * width;
108 let dense3 = Dense::new(flattened_size, output_dim, None, &mut rng)?;
109
110 // Generate random input image
111 let mut image_input = Array4::<f32>::zeros((batch_size, in_channels, height, width));
112 for n in 0..batch_size {
113 for c in 0..in_channels {
114 for h in 0..height {
115 for w in 0..width {
116 image_input[[n, c, h, w]] = rng.random_range(-1.0..1.0);
117 }
118 }
119 }
120 }
121
122 // Forward pass through CNN with dropout
123 println!("Running forward pass through CNN with dropout...");
124 let conv_output = conv1.forward(&image_input.clone().into_dyn())?;
125 let bn_output = bn1.forward(&conv_output)?;
126 let dropout_output = dropout_conv.forward(&bn_output)?;
127
128 // Reshape for dense layer (flatten spatial and channel dimensions)
129 let mut flattened = Array2::<f32>::zeros((batch_size, flattened_size));
130 for n in 0..batch_size {
131 let mut idx = 0;
132 for c in 0..out_channels {
133 for h in 0..height {
134 for w in 0..width {
135 flattened[[n, idx]] =
136 *dropout_output.slice(ndarray::s![n, c, h, w]).into_scalar();
137 idx += 1;
138 }
139 }
140 }
141 }
142
143 let cnn_output = dense3.forward(&flattened.into_dyn())?;
144
145 println!("CNN output shape: {:?}", cnn_output.shape());
146
147 // 4. Example: Switching between training and inference modes
148 println!("\nExample 4: Switching between training and inference modes");
149
150 // Create dropout layer with p=0.5
151 let mut switchable_dropout = Dropout::new(0.5, &mut rng)?;
152
153 // Create some input data
154 let test_input = Array2::<f32>::from_elem((1, 10), 1.0);
155
156 // Training mode (default)
157 let training_output = switchable_dropout.forward(&test_input.clone().into_dyn())?;
158
159 // Count non-zero elements in training mode
160 let training_nonzero = training_output.iter().filter(|&&x| x != 0.0).count();
161
162 // Switch to inference mode
163 switchable_dropout.set_training(false);
164 let inference_output = switchable_dropout.forward(&test_input.clone().into_dyn())?;
165
166 // Count non-zero elements in inference mode
167 let inference_nonzero = inference_output.iter().filter(|&&x| x != 0.0).count();
168
169 println!("Training mode: {} of 10 elements kept", training_nonzero);
170 println!("Inference mode: {} of 10 elements kept", inference_nonzero);
171
172 // In inference mode, all elements should be preserved
173 assert_eq!(inference_nonzero, 10);
174
175 println!("\nDropout implementation demonstration completed successfully!");
176
177 Ok(())
178}
Sourcepub fn is_training(&self) -> bool
pub fn is_training(&self) -> bool
Get the training mode
Trait Implementations§
Source§impl<F: Float + Debug + ScalarOperand + Send + Sync + 'static> Layer<F> for Dropout<F>
impl<F: Float + Debug + ScalarOperand + Send + Sync + 'static> Layer<F> for Dropout<F>
Source§fn as_any_mut(&mut self) -> &mut dyn Any
fn as_any_mut(&mut self) -> &mut dyn Any
Get the layer as a mutable dyn Any for downcasting Read more
Source§fn forward(&self, input: &Array<F, IxDyn>) -> Result<Array<F, IxDyn>>
fn forward(&self, input: &Array<F, IxDyn>) -> Result<Array<F, IxDyn>>
Forward pass of the layer Read more
Source§fn backward(
&self,
_input: &Array<F, IxDyn>,
grad_output: &Array<F, IxDyn>,
) -> Result<Array<F, IxDyn>>
fn backward( &self, _input: &Array<F, IxDyn>, grad_output: &Array<F, IxDyn>, ) -> Result<Array<F, IxDyn>>
Backward pass of the layer to compute gradients Read more
Source§fn update(&mut self, _learning_rate: F) -> Result<()>
fn update(&mut self, _learning_rate: F) -> Result<()>
Update the layer parameters with the given gradients Read more
Source§fn layer_type(&self) -> &str
fn layer_type(&self) -> &str
Get the type of the layer (e.g., “Dense”, “Conv2D”) Read more
Source§fn parameter_count(&self) -> usize
fn parameter_count(&self) -> usize
Get the number of trainable parameters in this layer Read more
Source§fn layer_description(&self) -> String
fn layer_description(&self) -> String
Get a detailed description of this layer Read more
Source§fn set_training(&mut self, training: bool)
fn set_training(&mut self, training: bool)
Set the layer to training mode (true) or evaluation mode (false) Read more
Source§fn is_training(&self) -> bool
fn is_training(&self) -> bool
Get the current training mode Read more
Source§fn gradients(&self) -> Vec<Array<F, IxDyn>> ⓘ
fn gradients(&self) -> Vec<Array<F, IxDyn>> ⓘ
Get the gradients of the layer parameters Read more
Auto Trait Implementations§
impl<F> Freeze for Dropout<F>where
F: Freeze,
impl<F> RefUnwindSafe for Dropout<F>where
F: RefUnwindSafe,
impl<F> Send for Dropout<F>
impl<F> Sync for Dropout<F>
impl<F> Unpin for Dropout<F>where
F: Unpin,
impl<F> UnwindSafe for Dropout<F>where
F: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more