Struct LayerNorm

Source
pub struct LayerNorm<F: Float + Debug> { /* private fields */ }
Expand description

Layer Normalization layer

Implements layer normalization as described in “Layer Normalization” by Ba, Kiros, and Hinton. It normalizes the inputs across the last dimension and applies learnable scale and shift parameters.

§Examples

use scirs2_neural::layers::{LayerNorm, Layer};
use ndarray::{Array, Array3};
use rand::rngs::SmallRng;
use rand::SeedableRng;

// Create a layer normalization layer for a 64-dimensional feature space
let mut rng = SmallRng::seed_from_u64(42);
let layer_norm = LayerNorm::new(64, 1e-5, &mut rng).unwrap();

// Forward pass with a batch of 2 samples, sequence length 3
let batch_size = 2;
let seq_len = 3;
let d_model = 64;
let input = Array3::<f64>::from_elem((batch_size, seq_len, d_model), 0.1).into_dyn();
let output = layer_norm.forward(&input).unwrap();

// Output shape should match input shape
assert_eq!(output.shape(), input.shape());

Implementations§

Source§

impl<F: Float + Debug + ScalarOperand + 'static> LayerNorm<F>

Source

pub fn new<R: Rng>( normalized_shape: usize, eps: f64, _rng: &mut R, ) -> Result<Self>

Create a new layer normalization layer

§Arguments
  • normalized_shape - Shape of the input features to normalize over
  • eps - Small constant added for numerical stability
  • rng - Random number generator for initialization
§Returns
  • A new layer normalization layer
Examples found in repository?
examples/model_serialization_example.rs (line 37)
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}
Source

pub fn normalized_shape(&self) -> usize

Get the normalized shape

Source

pub fn eps(&self) -> f64

Get the epsilon value

Trait Implementations§

Source§

impl<F: Float + Debug + ScalarOperand + 'static> Clone for LayerNorm<F>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

const fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<F: Debug + Float + Debug> Debug for LayerNorm<F>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<F: Float + Debug + ScalarOperand + 'static> Layer<F> for LayerNorm<F>

Source§

fn as_any(&self) -> &dyn Any

Get the layer as a dyn Any for downcasting Read more
Source§

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>>

Forward pass of the layer Read more
Source§

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<()>

Update the layer parameters with the given gradients Read more
Source§

fn params(&self) -> Vec<Array<F, IxDyn>>

Get the parameters of the layer Read more
Source§

fn gradients(&self) -> Vec<Array<F, IxDyn>>

Get the gradients of the layer parameters Read more
Source§

fn set_gradients(&mut self, _gradients: &[Array<F, IxDyn>]) -> Result<()>

Set the gradients of the layer parameters Read more
Source§

fn set_params(&mut self, _params: &[Array<F, IxDyn>]) -> Result<()>

Set the parameters of the layer Read more
Source§

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

Get the current training mode Read more
Source§

fn layer_type(&self) -> &str

Get the type of the layer (e.g., “Dense”, “Conv2D”) Read more
Source§

fn parameter_count(&self) -> usize

Get the number of trainable parameters in this layer Read more
Source§

fn layer_description(&self) -> String

Get a detailed description of this layer Read more
Source§

impl<F: Float + Debug + ScalarOperand + 'static> ParamLayer<F> for LayerNorm<F>

Source§

fn get_parameters(&self) -> Vec<&Array<F, IxDyn>>

Get the parameters of the layer as a vector of arrays
Source§

fn get_gradients(&self) -> Vec<&Array<F, IxDyn>>

Get the gradients of the parameters
Source§

fn set_parameters(&mut self, params: Vec<Array<F, IxDyn>>) -> Result<()>

Set the parameters of the layer

Auto Trait Implementations§

§

impl<F> Freeze for LayerNorm<F>
where F: Freeze,

§

impl<F> RefUnwindSafe for LayerNorm<F>
where F: RefUnwindSafe,

§

impl<F> Send for LayerNorm<F>
where F: Send + Sync,

§

impl<F> Sync for LayerNorm<F>
where F: Sync + Send,

§

impl<F> Unpin for LayerNorm<F>
where F: Unpin,

§

impl<F> UnwindSafe for LayerNorm<F>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V