use crate::compat::Sequential;
use crate::{AutodiffError, Tape, Tensor, Var};
pub struct LeNet {
model: Sequential,
num_classes: usize,
}
impl LeNet {
pub fn new(num_classes: usize, seed: u64) -> Result<Self, AutodiffError> {
if num_classes == 0 {
return Err(AutodiffError::InvalidArgument(
"LeNet::new: num_classes は 0 より大きい必要がある".to_string(),
));
}
let model = Sequential::new()
.add_conv2d(1, 6, [5, 5], [1, 1], [0, 0], [1, 1], 1, seed)?
.add_relu() .add_max_pool2d([2, 2], None, [0, 0], [1, 1])? .add_conv2d(
6,
16,
[5, 5],
[1, 1],
[0, 0],
[1, 1],
1,
seed.wrapping_add(1),
)?
.add_relu() .add_max_pool2d([2, 2], None, [0, 0], [1, 1])? .add_flatten(1, 3) .add_linear(16 * 4 * 4, 120, seed.wrapping_add(2))?
.add_relu() .add_linear(120, num_classes, seed.wrapping_add(3))?;
Ok(LeNet { model, num_classes })
}
pub fn forward<'t>(&self, tape: &'t Tape, x: &Var<'t>) -> Result<Var<'t>, AutodiffError> {
self.model.forward(tape, x)
}
pub fn predict(&self, x: &Tensor<f32>) -> Result<Tensor<f32>, AutodiffError> {
self.model.predict(x)
}
pub fn sequential(&self) -> &Sequential {
&self.model
}
pub fn sequential_mut(&mut self) -> &mut Sequential {
&mut self.model
}
pub fn num_classes(&self) -> usize {
self.num_classes
}
}