use std::{fmt, str::FromStr};
use serde::{Deserialize, Serialize};
use crate::{error::Result, tensor::R2lTensor};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum ActivationFunction {
Elu,
Gelu,
GeluApproximate,
HardSigmoid,
HardSwish,
LeakyRelu,
Relu,
Sigmoid,
#[default]
Tanh,
}
impl fmt::Display for ActivationFunction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = match self {
Self::Elu => "elu",
Self::Gelu => "gelu",
Self::GeluApproximate => "gelu_approximate",
Self::HardSigmoid => "hard_sigmoid",
Self::HardSwish => "hard_swish",
Self::LeakyRelu => "leaky_relu",
Self::Relu => "relu",
Self::Sigmoid => "sigmoid",
Self::Tanh => "tanh",
};
f.write_str(name)
}
}
impl FromStr for ActivationFunction {
type Err = String;
fn from_str(name: &str) -> std::result::Result<Self, Self::Err> {
match name {
"elu" => Ok(Self::Elu),
"gelu" => Ok(Self::Gelu),
"gelu_approximate" => Ok(Self::GeluApproximate),
"hard_sigmoid" => Ok(Self::HardSigmoid),
"hard_swish" => Ok(Self::HardSwish),
"leaky_relu" => Ok(Self::LeakyRelu),
"relu" => Ok(Self::Relu),
"sigmoid" => Ok(Self::Sigmoid),
"tanh" => Ok(Self::Tanh),
_ => Err(format!("unknown activation function: {name}")),
}
}
}
pub trait Actor: Send + 'static {
type Tensor: R2lTensor;
fn action(&self, observation: Self::Tensor) -> Result<Self::Tensor>;
fn mode_action(&self, observation: Self::Tensor) -> Result<Self::Tensor>;
}
pub trait ToSafetensors {
fn to_safetensors(&self) -> Result<Vec<u8>>;
}
pub trait Policy: Actor {
fn log_probs(
&self,
observations: &[Self::Tensor],
actions: &[Self::Tensor],
) -> Result<Self::Tensor>;
fn std(&self) -> Result<Option<f32>>;
fn entropy(&self, states: &[Self::Tensor]) -> Result<Self::Tensor>;
}
pub trait Learner {
type Losses;
fn update(&mut self, losses: Self::Losses) -> Result<()>;
}
pub trait ValueFunction {
type Tensor: Clone;
fn values(&self, observations: &[Self::Tensor]) -> Result<Self::Tensor>;
}