pub type AFI = ActivationFunctionIdentifier;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum ActivationFunctionIdentifier {
Identity,
Sign,
ReLu,
Sigmoid,
Step,
}
const IDEN_LOOKUP_TABLE: [ActivationFunctionIdentifier ; 5] = [
ActivationFunctionIdentifier::Identity,
ActivationFunctionIdentifier::Sign,
ActivationFunctionIdentifier::ReLu,
ActivationFunctionIdentifier::Sigmoid,
ActivationFunctionIdentifier::Step,
];
impl ActivationFunctionIdentifier {
pub fn from_int(n: u64) -> ActivationFunctionIdentifier {
IDEN_LOOKUP_TABLE[n as usize]
}
pub fn raw_value(self) -> u64 {
match self {
ActivationFunctionIdentifier::Identity => 0,
ActivationFunctionIdentifier::Sign => 1,
ActivationFunctionIdentifier::ReLu => 2,
ActivationFunctionIdentifier::Sigmoid => 3,
ActivationFunctionIdentifier::Step => 4,
}
}
pub fn evaluate(self, x: f64) -> f64 {
match self {
ActivationFunctionIdentifier::Identity => (Identity {}).evaluate(x),
ActivationFunctionIdentifier::Sign => (Sign {}).evaluate(x),
ActivationFunctionIdentifier::ReLu => (ReLu {}).evaluate(x),
ActivationFunctionIdentifier::Sigmoid => (Sigmoid {}).evaluate(x),
ActivationFunctionIdentifier::Step => (Step {}).evaluate(x),
}
}
pub fn derivative(self, x: f64) -> f64 {
match self {
ActivationFunctionIdentifier::Identity => (Identity {}).derivative(x),
ActivationFunctionIdentifier::Sign => (Sign {}).derivative(x),
ActivationFunctionIdentifier::ReLu => (ReLu {}).derivative(x),
ActivationFunctionIdentifier::Sigmoid => (Sigmoid {}).derivative(x),
ActivationFunctionIdentifier::Step => (Step {}).derivative(x),
}
}
}
trait ActivationFunction {
fn evaluate(&self, x: f64) -> f64;
fn derivative(&self, x: f64) -> f64;
}
struct Identity {}
impl ActivationFunction for Identity {
fn evaluate(&self, x: f64) -> f64 {
x
}
fn derivative(&self, _x: f64) -> f64 {
1.0
}
}
struct Sign {}
impl ActivationFunction for Sign {
fn evaluate(&self, x: f64) -> f64 {
x.signum()
}
fn derivative(&self, _x: f64) -> f64 {
0.0
}
}
struct ReLu {}
impl ActivationFunction for ReLu {
fn evaluate(&self, x: f64) -> f64 {
if x >= 0.0 { x } else { 0.0 }
}
fn derivative(&self, x: f64) -> f64 {
if x == 0.0 { f64::NAN } else if x > 0.0 { 1.0 }
else { 0.0 }
}
}
struct Sigmoid {}
impl ActivationFunction for Sigmoid {
fn evaluate(&self, x: f64) -> f64 {
1.0 / (1.0 + (-x).exp())
}
fn derivative(&self, x: f64) -> f64 {
self.evaluate(x) * (1.0 - self.evaluate(x))
}
}
struct Step {}
impl ActivationFunction for Step {
fn evaluate(&self, x: f64) -> f64 {
if x <= 0.0 {
0.0
} else {
1.0
}
}
fn derivative(&self, _x: f64) -> f64 {
0.0
}
}