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::no_trainable_parameters_layer_functions;
use crate::neural_network::layers::upsampling::resize_engine::{
upsample_backward, upsample_forward, upsample_summary, validate_factors,
};
use crate::neural_network::layers::upsampling::{Factor3D, Interpolation};
use crate::neural_network::traits::Layer;
#[derive(Debug)]
pub struct UpSampling3D {
size: Factor3D,
input_shape: Option<Vec<usize>>,
}
impl UpSampling3D {
pub fn new(size: impl Into<Factor3D>) -> Result<Self, Error> {
let size = size.into();
validate_factors(&size.0)?;
Ok(UpSampling3D {
size,
input_shape: None,
})
}
}
impl Layer for UpSampling3D {
fn forward(&mut self, input: &Tensor) -> Result<Tensor, Error> {
let output = upsample_forward(
input,
&self.size.0,
Interpolation::Nearest,
5,
"UpSampling3D",
)?;
self.input_shape = Some(input.shape().to_vec());
Ok(output)
}
fn predict(&self, input: &Tensor) -> Result<Tensor, Error> {
upsample_forward(
input,
&self.size.0,
Interpolation::Nearest,
5,
"UpSampling3D",
)
}
fn backward(&mut self, grad_output: &Tensor) -> Result<Tensor, Error> {
upsample_backward(
grad_output,
self.input_shape.as_deref(),
&self.size.0,
Interpolation::Nearest,
"UpSampling3D",
)
}
fn layer_type(&self) -> &str {
"UpSampling3D"
}
fn output_shape(&self) -> String {
upsample_summary(self.input_shape.as_deref(), &self.size.0)
}
no_trainable_parameters_layer_functions!();
}