model_serialization_example/
model_serialization_example.rs

1use ndarray::Array2;
2use rand::rngs::SmallRng;
3use rand::SeedableRng;
4use scirs2_neural::layers::{Dense, Dropout, LayerNorm};
5use scirs2_neural::models::{Model, Sequential};
6use scirs2_neural::serialization::{self, SerializationFormat};
7use std::path::Path;
8
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10    println!("Model Serialization Example");
11
12    // Initialize random number generator
13    let mut rng = SmallRng::seed_from_u64(42);
14
15    // 1. Create a simple neural network model
16    let mut model = Sequential::new();
17
18    // Add layers
19    let input_dim = 784; // MNIST image size: 28x28 = 784
20    let hidden_dim_1 = 256;
21    let hidden_dim_2 = 128;
22    let output_dim = 10; // 10 classes for digits 0-9
23
24    // Input layer to first hidden layer
25    let dense1 = Dense::new(input_dim, hidden_dim_1, Some("relu"), &mut rng)?;
26    model.add_layer(dense1);
27
28    // Dropout for regularization
29    let dropout1 = Dropout::new(0.2, &mut rng)?;
30    model.add_layer(dropout1);
31
32    // First hidden layer to second hidden layer
33    let dense2 = Dense::new(hidden_dim_1, hidden_dim_2, Some("relu"), &mut rng)?;
34    model.add_layer(dense2);
35
36    // Layer normalization
37    let layer_norm = LayerNorm::new(hidden_dim_2, 1e-5, &mut rng)?;
38    model.add_layer(layer_norm);
39
40    // Second hidden layer to output layer
41    let dense3 = Dense::new(hidden_dim_2, output_dim, Some("softmax"), &mut rng)?;
42    model.add_layer(dense3);
43
44    println!(
45        "Created a neural network with {} layers",
46        model.num_layers()
47    );
48
49    // 2. Test the model with some dummy input
50    let batch_size = 2;
51    let input = Array2::<f32>::from_elem((batch_size, input_dim), 0.1);
52    let output = model.forward(&input.clone().into_dyn())?;
53
54    println!("Model output shape: {:?}", output.shape());
55    println!("First few output values:");
56    for i in 0..batch_size {
57        print!("Sample {}: [ ", i);
58        for j in 0..5 {
59            // Print first 5 values
60            print!("{:.6} ", output[[i, j]]);
61        }
62        println!("... ]");
63    }
64
65    // 3. Save the model to a file
66    let model_path = Path::new("mnist_model.json");
67    serialization::save_model(&model, model_path, SerializationFormat::JSON)?;
68
69    println!("\nModel saved to {}", model_path.display());
70
71    // 4. Load the model from the file
72    let loaded_model = serialization::load_model::<f32, _>(model_path, SerializationFormat::JSON)?;
73
74    println!(
75        "Model loaded successfully with {} layers",
76        loaded_model.num_layers()
77    );
78
79    // 5. Test the loaded model with the same input
80    let loaded_output = loaded_model.forward(&input.into_dyn())?;
81
82    println!("\nLoaded model output shape: {:?}", loaded_output.shape());
83    println!("First few output values:");
84    for i in 0..batch_size {
85        print!("Sample {}: [ ", i);
86        for j in 0..5 {
87            // Print first 5 values
88            print!("{:.6} ", loaded_output[[i, j]]);
89        }
90        println!("... ]");
91    }
92
93    // 6. Compare original and loaded model outputs
94    let mut max_diff = 0.0;
95    for i in 0..batch_size {
96        for j in 0..output_dim {
97            let diff = (output[[i, j]] - loaded_output[[i, j]]).abs();
98            if diff > max_diff {
99                max_diff = diff;
100            }
101        }
102    }
103
104    println!(
105        "\nMaximum difference between original and loaded model outputs: {:.6}",
106        max_diff
107    );
108
109    if max_diff < 1e-6 {
110        println!("Models are identical! Serialization and deserialization worked correctly.");
111    } else {
112        println!("Warning: There are differences between the original and loaded models.");
113        println!(
114            "This might be due to numerical precision issues or a problem with serialization."
115        );
116    }
117
118    Ok(())
119}