Skip to main content

burn_nn/activation/
elu.rs

1use burn::config::Config;
2use burn::module::Module;
3use burn::module::{Content, DisplaySettings, ModuleDisplay};
4use burn::tensor::Tensor;
5use burn::tensor::backend::Backend;
6use burn_core as burn;
7
8use burn::tensor::activation::elu;
9
10/// ELU (Exponential Linear Unit) layer.
11///
12/// Should be created with [EluConfig](EluConfig).
13#[derive(Module, Clone, Debug)]
14#[module(custom_display)]
15pub struct Elu {
16    /// The alpha value.
17    pub alpha: f64,
18}
19/// Configuration to create an [Elu](Elu) layer using the [init function](EluConfig::init).
20#[derive(Config, Debug)]
21pub struct EluConfig {
22    /// The alpha value. Default is 1.0
23    #[config(default = "1.0")]
24    pub alpha: f64,
25}
26impl EluConfig {
27    /// Initialize a new [Elu](Elu) Layer
28    pub fn init(&self) -> Elu {
29        Elu { alpha: self.alpha }
30    }
31}
32
33impl ModuleDisplay for Elu {
34    fn custom_settings(&self) -> Option<DisplaySettings> {
35        DisplaySettings::new()
36            .with_new_line_after_attribute(false)
37            .optional()
38    }
39
40    fn custom_content(&self, content: Content) -> Option<Content> {
41        content.add("alpha", &self.alpha).optional()
42    }
43}
44
45impl Elu {
46    /// Forward pass for the ELU layer.
47    ///
48    /// See [elu](burn::tensor::activation::elu) for more information.
49    ///
50    /// # Shapes
51    /// - input: `[..., any]`
52    /// - output: `[..., any]`
53    pub fn forward<B: Backend, const D: usize>(&self, input: Tensor<B, D>) -> Tensor<B, D> {
54        elu(input, self.alpha)
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    use crate::TestBackend;
62    use burn::tensor::TensorData;
63    use burn::tensor::{Tolerance, ops::FloatElem};
64    type FT = FloatElem<TestBackend>;
65
66    #[test]
67    fn test_elu_forward() {
68        let device = Default::default();
69        let model: Elu = EluConfig::new().init();
70        let input =
71            Tensor::<TestBackend, 2>::from_data(TensorData::from([[0.4410, -0.2507]]), &device);
72        let out = model.forward(input);
73        // elu(0.4410, 1.0) = 0.4410
74        // elu(-0.2507, 1.0) = 1.0 * (exp(-0.2507) - 1) = -0.22186
75        let expected = TensorData::from([[0.4410, -0.22186]]);
76        out.to_data()
77            .assert_approx_eq::<FT>(&expected, Tolerance::default());
78    }
79
80    #[test]
81    fn display() {
82        let config = EluConfig::new().init();
83        assert_eq!(alloc::format!("{config}"), "Elu {alpha: 1}");
84    }
85}