use std::fmt::Debug;
use crate::device::*;
use crate::{Stack};
use crate::error::{EvaluateError, PersistenceError, TrainingError};
use crate::ope::UnitValue;
use crate::lossfunction::*;
#[cfg(feature = "cuda")]
use crate::error::{TypeConvertError};
#[cfg(feature = "cuda")]
use crate::cuda::allocator::CudaAllocator;
#[cfg(feature = "cuda")]
use crate::cuda::ToCuda;
use crate::persistence::PersistenceType;
pub mod input;
pub mod output;
pub mod linear;
pub mod activation;
pub mod bridge;
pub mod logging;
pub mod batchnormalization;
pub mod bias;
#[derive(Debug)]
pub struct DiffInput<'a,T,O>
where T: Debug,
O: Debug {
pub diff: T,
pub output: &'a O
}
impl<'a,T,O> DiffInput<'a,T,O>
where T: Debug + Clone,
O: Debug{
pub fn new(diff: T, output: &'a O) -> Self {
DiffInput {
diff,
output
}
}
}
impl<'a,T,O> Clone for DiffInput<'a,T,O>
where T: Debug + Clone,
O: Debug {
fn clone(&self) -> Self {
DiffInput {
diff: self.diff.clone(),
output: self.output
}
}
}
pub trait BatchDataType {
type Type;
}
impl BatchDataType for () {
type Type = ();
}
impl<'a,T,O> BatchDataType for DiffInput<'a,T,O>
where T: Debug,
O: Debug + 'a {
type Type = Vec<DiffInput<'a,T,O>>;
}
#[cfg(feature = "cuda")]
impl<'a,T,O,U,A> ToCuda<U,A> for DiffInput<'a,T,O>
where U: UnitValue<U> + Clone + Copy + Debug,
T: Debug,
O: Debug + 'a,
A: CudaAllocator {
type Output = Self;
fn to_cuda(self, _: &DeviceGpu<U,A>) -> Result<Self::Output, TypeConvertError> {
Ok(self)
}
}
#[cfg(feature = "cuda")]
impl<'a,T,O,U,A> ToCuda<U,A> for Vec<DiffInput<'a,T,O>>
where U: UnitValue<U> + Clone + Copy + Debug,
T: Debug,
O: Debug + 'a,
A: CudaAllocator {
type Output = Self;
fn to_cuda(self, _: &DeviceGpu<U,A>) -> Result<Self::Output, TypeConvertError> {
Ok(self)
}
}
pub trait BatchSize {
fn size(&self) -> usize;
}
pub trait Forward<I,O> {
fn forward(&self,input:&I) -> O;
}
pub trait ForwardAll {
type Input: Debug;
type Output: Debug + 'static;
fn forward_all(&self, input:Self::Input) -> Result<Self::Output, EvaluateError>;
}
pub trait BackwardAll<U>: PreTrain<U> + UpdateWeight<U> where U: UnitValue<U> {
type LossInput: Debug;
type LossOutput: Debug;
fn backward_all<L: LossFunction<U>>(&mut self, input:Self::LossInput, stack:Self::OutStack, lossf:&L)
-> Result<(<Self as BackwardAll<U>>::LossOutput,<Self as UpdateWeight<U>>::GradientStack), TrainingError>;
fn is_canonical_link<L: LossFunction<U>>(&self,_:&L) -> bool {
false
}
}
pub trait Loss<U>: BackwardAll<U> where U: UnitValue<U> {
fn loss<L: LossFunction<U>>(&mut self, loss:Self::LossInput, _lossf:&L, stack:Self::OutStack) -> Result<(Self::OutStack, Self::LossInput), TrainingError> {
Ok((stack,loss))
}
}
pub trait Backward<U,I,O> where U: UnitValue<U> {
fn backward(&mut self, input:I) -> O;
}
pub trait PreTrain<U>: ForwardAll where U: UnitValue<U> {
type PreOutput: Debug + 'static;
type OutStack: Stack<Head=Self::PreOutput> + Debug + Sized;
fn pre_train(&self, input:Self::Input) -> Result<Self::OutStack, EvaluateError>;
}
pub trait UpdateWeight<U> where U: UnitValue<U> {
type GradientStack: Stack + Debug + Sized;
fn update_weight(&mut self, stack:Self::GradientStack, batch_size: usize) -> Result<(), TrainingError>;
}
pub trait Train<U,L>: PreTrain<U>
where U: UnitValue<U> {
fn train(&mut self, expected:Self::Output, input:Self::Input, lossf:&L) -> Result<U, TrainingError>;
}
pub trait PartialForward: ForwardAll {
type PartialOutput: Debug;
type PartialOutputByDiff: Debug;
type DiffInput: Debug;
type DiffOutput: Debug;
fn partial_forward(&self, input:Self::Input) -> Result<Self::PartialOutput, EvaluateError>;
fn partial_forward_by_diff(&self, input:Self::DiffInput) -> Result<Self::PartialOutputByDiff, EvaluateError>;
}
pub trait ForwardDiff: PartialForward {
fn forward_diff(&self, input:Self::DiffInput) -> Result<Self::DiffOutput, EvaluateError>;
}
pub trait ContinueForward: PartialForward {
type ConinueOutput;
fn continue_forward(&self, input:&Self::PartialOutput) -> Result<Self::ConinueOutput, EvaluateError>;
}
pub trait BatchForwardBase: ForwardAll {
type BatchInput: Debug;
type BatchOutput: Debug;
}
pub trait BatchForward: BatchForwardBase {
fn batch_forward(&self,input:Self::BatchInput) -> Result<Self::BatchOutput, TrainingError>;
}
pub trait BatchBackward<U>: BatchPreTrainBase<U> + UpdateWeight<U> where U: UnitValue<U> {
type BatchLossInput: Debug;
type BatchLossOutput: Debug;
fn batch_backward<L: LossFunction<U>>(&mut self, input:Self::BatchLossInput, stack:Self::BatchOutStack, lossf:&L)
-> Result<(<Self as BatchBackward<U>>::BatchLossOutput,<Self as UpdateWeight<U>>::GradientStack), TrainingError>;
}
pub trait BatchLoss<U>: BatchBackward<U> + Loss<U> where U: UnitValue<U> {
fn batch_loss<L: LossFunction<U>>(&self, loss:Self::BatchLossInput, _lossf:&L, stack:Self::BatchOutStack) -> Result<(Self::BatchOutStack, Self::BatchLossInput), TrainingError> {
Ok((stack,loss))
}
}
pub trait BatchPreTrainBase<U>: BatchForwardBase + PreTrain<U> where U: UnitValue<U> {
type BatchPreOutput: Debug + 'static;
type BatchOutStack: Stack<Head=Self::BatchPreOutput> + Sized + Debug;
}
pub trait BatchPreTrain<U>: BatchPreTrainBase<U> + BatchForwardBase + BatchForward + where U: UnitValue<U> {
fn batch_pre_train(&self, input:Self::BatchInput) -> Result<Self::BatchOutStack, TrainingError>;
}
pub trait BatchTrain<U,D,L>: BatchPreTrainBase<U> + BatchPreTrain<U> + BatchBackward<U> + PreTrain<U>
where U: UnitValue<U>, D: Device<U>,
L: LossFunction<U> {
fn batch_train(&mut self, expected:Self::BatchOutput, input:Self::BatchInput, lossf:&L) -> Result<U, TrainingError>;
}
pub trait Step {
fn step(&mut self) -> Result<(), TrainingError>;
fn frequently_step(&mut self) -> Result<(), TrainingError>;
}
pub trait OnStep {
fn on_step(&mut self, step:usize) -> Result<(), TrainingError>;
fn on_frequently_step(&mut self, step: usize, frequently_step: usize) -> Result<(), TrainingError>;
}
pub trait PersistProgress<P,K> where K: PersistenceType {
fn load_progress(&mut self, persistence:&mut P) -> Result<(),TrainingError>;
fn save_progress(&mut self, persistence:&mut P) -> Result<(), PersistenceError>;
}
pub trait AddLayer: ForwardAll where Self: Sized {
fn add_layer<C,F>(self,f:F) -> C where C: ForwardAll, F: FnOnce(Self) -> C;
}
impl<T> AddLayer for T where T: ForwardAll + Sized {
fn add_layer<C, F>(self, f: F) -> C where C: ForwardAll, F: FnOnce(Self) -> C {
f(self)
}
}
pub trait TryAddLayer: ForwardAll where Self: Sized {
fn try_add_layer<C,F,E>(self,f:F) -> Result<C,E> where C: ForwardAll, F: FnOnce(Self) -> Result<C,E>;
}
impl<T> TryAddLayer for T where T: ForwardAll + Sized {
fn try_add_layer<C,F,E>(self, f: F) -> Result<C,E> where C: ForwardAll, F: FnOnce(Self) -> Result<C,E> {
f(self)
}
}