pub mod average_pooling_1d;
pub mod average_pooling_2d;
pub mod average_pooling_3d;
pub mod global_average_pooling_1d;
pub mod global_average_pooling_2d;
pub mod global_average_pooling_3d;
pub mod global_max_pooling_1d;
pub mod global_max_pooling_2d;
pub mod global_max_pooling_3d;
pub mod max_pooling_1d;
pub mod max_pooling_2d;
pub mod max_pooling_3d;
pub(crate) mod pooling_engine;
mod validation;
pub use average_pooling_1d::AveragePooling1D;
pub use average_pooling_2d::AveragePooling2D;
pub use average_pooling_3d::AveragePooling3D;
pub use global_average_pooling_1d::GlobalAveragePooling1D;
pub use global_average_pooling_2d::GlobalAveragePooling2D;
pub use global_average_pooling_3d::GlobalAveragePooling3D;
pub use global_max_pooling_1d::GlobalMaxPooling1D;
pub use global_max_pooling_2d::GlobalMaxPooling2D;
pub use global_max_pooling_3d::GlobalMaxPooling3D;
pub use max_pooling_1d::MaxPooling1D;
pub use max_pooling_2d::MaxPooling2D;
pub use max_pooling_3d::MaxPooling3D;
macro_rules! layer_functions_global_pooling {
($layer:literal, $rank:literal) => {
fn build(
&mut self,
input: &$crate::neural_network::Shape,
) -> Result<(), $crate::error::Error> {
let Some(built) = $crate::neural_network::layers::validation::start_build(
&self.built,
$layer,
input,
)?
else {
return Ok(());
};
$crate::neural_network::traits::UnaryLayer::compute_output_shape(self, &built)?;
self.built = Some(built);
Ok(())
}
fn compute_output_shape(
&self,
input: &$crate::neural_network::Shape,
) -> Result<$crate::neural_network::Shape, $crate::error::Error> {
input.check_rank($layer, $rank)?;
let (batch, tail) = input.split_batch($layer)?;
Ok($crate::neural_network::Shape::from_batch(
batch,
&[tail[tail.len() - 1]],
))
}
};
}
macro_rules! layer_base_functions_pooling {
() => {
$crate::neural_network::layers::built_layer_shape_functions!();
$crate::neural_network::layers::no_trainable_parameters_layer_functions!();
};
}
pub(in crate::neural_network::layers::pooling) use layer_base_functions_pooling;
macro_rules! layer_functions_1d_pooling {
($layer:literal) => {
fn build(
&mut self,
input: &$crate::neural_network::Shape,
) -> Result<(), $crate::error::Error> {
let Some(built) = $crate::neural_network::layers::validation::start_build(
&self.built,
$layer,
input,
)?
else {
return Ok(());
};
$crate::neural_network::traits::UnaryLayer::compute_output_shape(self, &built)?;
self.built = Some(built);
Ok(())
}
fn compute_output_shape(
&self,
input: &$crate::neural_network::Shape,
) -> Result<$crate::neural_network::Shape, $crate::error::Error> {
input.check_rank($layer, 3)?;
let (batch, tail) = input.split_batch($layer)?;
validate_pool_size_1d(self.pool_size, tail[0])?;
let mut dims = vec![0];
dims.extend(tail);
let output_shape =
calculate_output_shape_1d_pooling(&dims, self.pool_size, self.stride, self.padding);
Ok($crate::neural_network::Shape::from_batch(
batch,
&output_shape[1..],
))
}
};
}
macro_rules! layer_functions_2d_pooling {
($layer:literal) => {
fn build(
&mut self,
input: &$crate::neural_network::Shape,
) -> Result<(), $crate::error::Error> {
let Some(built) = $crate::neural_network::layers::validation::start_build(
&self.built,
$layer,
input,
)?
else {
return Ok(());
};
$crate::neural_network::traits::UnaryLayer::compute_output_shape(self, &built)?;
self.built = Some(built);
Ok(())
}
fn compute_output_shape(
&self,
input: &$crate::neural_network::Shape,
) -> Result<$crate::neural_network::Shape, $crate::error::Error> {
input.check_rank($layer, 4)?;
let (batch, tail) = input.split_batch($layer)?;
validate_pool_size_2d(self.pool_size, tail[0], tail[1])?;
let mut dims = vec![0];
dims.extend(tail);
let output_shape = calculate_output_shape_2d_pooling(
&dims,
self.pool_size,
self.strides,
self.padding,
);
Ok($crate::neural_network::Shape::from_batch(
batch,
&output_shape[1..],
))
}
};
}
macro_rules! layer_functions_3d_pooling {
($layer:literal) => {
fn build(
&mut self,
input: &$crate::neural_network::Shape,
) -> Result<(), $crate::error::Error> {
let Some(built) = $crate::neural_network::layers::validation::start_build(
&self.built,
$layer,
input,
)?
else {
return Ok(());
};
$crate::neural_network::traits::UnaryLayer::compute_output_shape(self, &built)?;
self.built = Some(built);
Ok(())
}
fn compute_output_shape(
&self,
input: &$crate::neural_network::Shape,
) -> Result<$crate::neural_network::Shape, $crate::error::Error> {
input.check_rank($layer, 5)?;
let (batch, tail) = input.split_batch($layer)?;
validate_pool_size_3d(self.pool_size, tail[0], tail[1], tail[2])?;
let mut dims = vec![0];
dims.extend(tail);
let output_shape = calculate_output_shape_3d_pooling(
&dims,
self.pool_size,
self.strides,
self.padding,
);
Ok($crate::neural_network::Shape::from_batch(
batch,
&output_shape[1..],
))
}
};
}
pub(in crate::neural_network::layers::pooling) use layer_functions_1d_pooling;
pub(in crate::neural_network::layers::pooling) use layer_functions_2d_pooling;
pub(in crate::neural_network::layers::pooling) use layer_functions_3d_pooling;
pub(in crate::neural_network::layers::pooling) use layer_functions_global_pooling;