use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub enum Activation {
#[default]
ReLU,
GELU,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub enum HeadType {
#[default]
Flat,
Hierarchical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MultiBranchConfig {
pub char_dim: usize,
pub embed_dim: usize,
pub stats_dim: usize,
#[serde(default)]
pub header_dim: usize,
pub char_hidden: [usize; 2],
pub embed_hidden: [usize; 2],
pub stats_hidden: [usize; 2],
#[serde(default)]
pub header_hidden: [usize; 2],
pub merge_hidden: [usize; 2],
pub n_classes: usize,
pub dropout: f32,
pub head_type: HeadType,
#[serde(default)]
pub activation: Activation,
#[serde(default)]
pub use_layer_norm: bool,
#[serde(default)]
pub valid_dim: usize,
#[serde(default)]
pub valid_hidden: [usize; 2],
#[serde(default)]
pub type_index_keys: Vec<String>,
#[serde(default)]
pub value_embed_model: Option<String>,
#[serde(default)]
pub value_attention: Option<crate::value_attention::ValueAttentionConfig>,
}
impl MultiBranchConfig {
pub fn has_header_branch(&self) -> bool {
self.header_dim > 0 && self.header_hidden[0] > 0 && self.header_hidden[1] > 0
}
pub fn has_validation_branch(&self) -> bool {
self.valid_dim > 0 && self.valid_hidden[0] > 0 && self.valid_hidden[1] > 0
}
pub fn embed_branch_input_dim(&self) -> usize {
match &self.value_attention {
Some(va) => {
let blender = if va.keep_blender_concat {
self.embed_dim
} else {
0
};
blender + va.output_dim()
}
None => self.embed_dim,
}
}
pub fn merged_dim(&self) -> usize {
let mut dim = self.char_hidden[1] + self.embed_hidden[1] + self.stats_hidden[1];
if self.has_header_branch() {
dim += self.header_hidden[1];
}
if self.has_validation_branch() {
dim += self.valid_hidden[1];
}
dim
}
}