dropout_example/
dropout_example.rs1use ndarray::{Array2, Array4};
2use rand::prelude::*;
3use rand::rngs::SmallRng;
4use rand::SeedableRng;
5use scirs2_neural::layers::{BatchNorm, Conv2D, Dense, Dropout, Layer, PaddingMode};
6
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 println!("Dropout Example");
9
10 let mut rng = SmallRng::seed_from_u64(42);
12
13 println!("\nExample 1: Simple dropout on a vector");
15
16 let n_features = 20;
18 let input = Array2::<f32>::from_elem((1, n_features), 1.0);
19
20 let dropout = Dropout::new(0.5, &mut rng)?;
22
23 let output = dropout.forward(&input.into_dyn())?;
25
26 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 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 println!("\nExample 2: Using dropout in a simple neural network");
48
49 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 let dropout1 = Dropout::new(0.2, &mut rng)?;
58
59 let dense2 = Dense::new(hidden_dim, output_dim, None, &mut rng)?;
61
62 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 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 println!("\nExample 3: Dropout in a CNN architecture");
83
84 let in_channels = 3; 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 let bn1 = BatchNorm::new(out_channels, 0.9, 1e-5, &mut rng)?;
100
101 let dropout_conv = Dropout::new(0.25, &mut rng)?;
103
104 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 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 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 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 println!("\nExample 4: Switching between training and inference modes");
149
150 let mut switchable_dropout = Dropout::new(0.5, &mut rng)?;
152
153 let test_input = Array2::<f32>::from_elem((1, 10), 1.0);
155
156 let training_output = switchable_dropout.forward(&test_input.clone().into_dyn())?;
158
159 let training_nonzero = training_output.iter().filter(|&&x| x != 0.0).count();
161
162 switchable_dropout.set_training(false);
164 let inference_output = switchable_dropout.forward(&test_input.clone().into_dyn())?;
165
166 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 assert_eq!(inference_nonzero, 10);
174
175 println!("\nDropout implementation demonstration completed successfully!");
176
177 Ok(())
178}