use std::collections::HashMap;
use super::architecture::*;
#[derive(Debug, Clone)]
pub struct ArchitectureSearchSpace {
pub layer_types: Vec<LayerType>,
pub hidden_sizes: Vec<usize>,
pub num_layers_range: (usize, usize),
pub activation_functions: Vec<ActivationType>,
pub connection_patterns: Vec<ConnectionPattern>,
pub attention_mechanisms: Vec<AttentionType>,
pub normalization_options: Vec<NormalizationType>,
pub optimizer_components: Vec<OptimizerComponent>,
pub memory_mechanisms: Vec<MemoryType>,
pub skip_connections: Vec<SkipConnectionType>,
}
impl Default for ArchitectureSearchSpace {
fn default() -> Self {
Self {
layer_types: vec![
LayerType::Linear,
LayerType::LSTM,
LayerType::GRU,
LayerType::Transformer,
LayerType::Attention,
LayerType::Dense,
],
hidden_sizes: vec![32, 64, 128, 256, 512],
num_layers_range: (1, 10),
activation_functions: vec![
ActivationType::ReLU,
ActivationType::GELU,
ActivationType::Tanh,
ActivationType::Sigmoid,
ActivationType::Swish,
],
connection_patterns: vec![
ConnectionPattern::Sequential,
ConnectionPattern::Residual,
ConnectionPattern::DenseNet,
ConnectionPattern::Attention,
],
attention_mechanisms: vec![
AttentionType::None,
AttentionType::SelfAttention,
AttentionType::MultiHeadAttention,
AttentionType::LocalAttention,
],
normalization_options: vec![
NormalizationType::None,
NormalizationType::LayerNorm,
NormalizationType::BatchNorm,
],
optimizer_components: vec![
OptimizerComponent::MomentumTracker,
OptimizerComponent::AdaptiveLearningRate,
OptimizerComponent::GradientClipping,
],
memory_mechanisms: vec![
MemoryType::None,
MemoryType::ShortTerm,
MemoryType::LongTerm,
MemoryType::WorkingMemory,
],
skip_connections: vec![
SkipConnectionType::None,
SkipConnectionType::Residual,
SkipConnectionType::Dense,
SkipConnectionType::Highway,
],
}
}
}
impl ArchitectureSearchSpace {
pub fn search_space_size(&self) -> u64 {
let layer_combinations = self.layer_types.len().pow(self.num_layers_range.1 as u32) as u64;
let hidden_size_combinations = self.hidden_sizes.len().pow(self.num_layers_range.1 as u32) as u64;
let activation_combinations = self.activation_functions.len().pow(self.num_layers_range.1 as u32) as u64;
layer_combinations * hidden_size_combinations * activation_combinations
}
pub fn sample_random(&self) -> ArchitectureSpec {
use scirs2_core::random::seq::SliceRandom;
let num_layers = scirs2_core::random::random::<usize>() % (self.num_layers_range.1 - self.num_layers_range.0 + 1) + self.num_layers_range.0;
let mut layers = Vec::new();
for i in 0..num_layers {
let layer_type = *self.layer_types.choose(&mut scirs2_core::random::thread_rng()).unwrap_or(&LayerType::Linear);
let hidden_size = *self.hidden_sizes.choose(&mut scirs2_core::random::thread_rng()).unwrap_or(&128);
let activation = *self.activation_functions.choose(&mut scirs2_core::random::thread_rng()).unwrap_or(&ActivationType::ReLU);
let dimensions = LayerDimensions {
input_dim: if i == 0 { hidden_size } else { layers[i-1].dimensions.output_dim },
output_dim: hidden_size,
hidden_dims: vec![],
};
layers.push(LayerSpec::new(layer_type, dimensions, activation));
}
ArchitectureSpec::new(layers, GlobalArchitectureConfig::default())
}
}