use crate::error::Error;
use crate::neural_network::Tensor;
use crate::neural_network::layers::TrainingParameters;
use crate::neural_network::layers::layer_weight::LayerWeight;
use crate::neural_network::layers::pooling::layer_functions_global_pooling;
use crate::neural_network::layers::pooling::pooling_engine::{
PoolKind, global_pool_backward, global_pool_forward,
};
use crate::neural_network::traits::Layer;
#[derive(Debug)]
pub struct GlobalAveragePooling1D {
input_shape: Vec<usize>,
}
impl GlobalAveragePooling1D {
pub fn new() -> Self {
GlobalAveragePooling1D {
input_shape: Vec::new(),
}
}
}
impl Default for GlobalAveragePooling1D {
fn default() -> Self {
Self::new()
}
}
impl Layer for GlobalAveragePooling1D {
fn forward(&mut self, input: &Tensor) -> Result<Tensor, Error> {
if input.ndim() != 3 {
return Err(Error::invalid_input("input tensor is not 3D"));
}
self.input_shape = input.shape().to_vec();
let (output, _) = global_pool_forward(input, PoolKind::Average);
Ok(output)
}
fn predict(&self, input: &Tensor) -> Result<Tensor, Error> {
if input.ndim() != 3 {
return Err(Error::invalid_input("input tensor is not 3D"));
}
let (output, _) = global_pool_forward(input, PoolKind::Average);
Ok(output)
}
fn backward(&mut self, grad_output: &Tensor) -> Result<Tensor, Error> {
if self.input_shape.is_empty() {
return Err(Error::forward_pass_not_run("GlobalAveragePooling1D"));
}
Ok(global_pool_backward(
grad_output,
&self.input_shape,
PoolKind::Average,
None,
))
}
fn layer_type(&self) -> &str {
"GlobalAveragePooling1D"
}
layer_functions_global_pooling!();
}