use super::config::*;
use super::optimizer::{Adaptation, AdaptationPriority, AdaptationType, StreamingDataPoint};
use super::performance::{PerformanceSnapshot, PerformanceTracker};
use scirs2_core::numeric::Float;
use scirs2_core::random::{thread_rng, Rng};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
use std::time::{Duration, Instant};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MetaModelType {
NeuralNetwork,
LinearRegression,
RandomForest,
GradientBoosting,
SupportVectorMachine,
}
pub struct MetaLearner<A: Float + Send + Sync> {
config: MetaLearningConfig,
experience_buffer: ExperienceBuffer<A>,
meta_model: MetaModel<A>,
strategy_selector: StrategySelector<A>,
transfer_learning: TransferLearning<A>,
statistics: MetaLearningStatistics<A>,
learning_rate_adapter: LearningRateAdapter<A>,
}
pub type ExperienceReplay<A> = ExperienceBuffer<A>;
pub struct ExperienceBuffer<A: Float + Send + Sync> {
config: ExperienceReplayConfig,
experiences: VecDeque<MetaExperience<A>>,
priority_queue: VecDeque<(MetaExperience<A>, A)>,
importance_weights: HashMap<usize, A>,
diversity_tracker: ExperienceDiversityTracker<A>,
}
#[derive(Debug, Clone)]
pub struct MetaExperience<A: Float + Send + Sync> {
pub id: u64,
pub state: MetaState<A>,
pub action: MetaAction<A>,
pub reward: A,
pub next_state: Option<MetaState<A>>,
pub timestamp: Instant,
pub episode_context: EpisodeContext<A>,
pub priority: A,
pub replay_count: usize,
}
#[derive(Debug, Clone)]
pub struct MetaState<A: Float + Send + Sync> {
pub performance_metrics: Vec<A>,
pub resource_state: Vec<A>,
pub drift_indicators: Vec<A>,
pub adaptation_history: usize,
pub timestamp: Instant,
}
#[derive(Debug, Clone)]
pub struct MetaAction<A: Float + Send + Sync> {
pub adaptation_magnitudes: Vec<A>,
pub adaptation_types: Vec<AdaptationType>,
pub learning_rate_change: A,
pub buffer_size_change: A,
pub timestamp: Instant,
}
#[derive(Debug, Clone)]
pub struct EpisodeContext<A: Float + Send + Sync> {
pub episode_id: u64,
pub start_time: Instant,
pub duration: Duration,
pub initial_performance: A,
pub final_performance: A,
pub adaptation_count: usize,
pub outcome: EpisodeOutcome,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EpisodeOutcome {
Success,
PartialSuccess,
Neutral,
Failure,
CriticalFailure,
}
pub struct ExperienceDiversityTracker<A: Float + Send + Sync> {
state_clusters: Vec<StateCluster<A>>,
action_clusters: Vec<ActionCluster<A>>,
diversity_metrics: DiversityMetrics<A>,
novelty_detector: NoveltyDetector<A>,
}
#[derive(Debug, Clone)]
pub struct StateCluster<A: Float + Send + Sync> {
pub center: MetaState<A>,
pub members: Vec<usize>,
pub radius: A,
pub last_update: Instant,
}
#[derive(Debug, Clone)]
pub struct ActionCluster<A: Float + Send + Sync> {
pub center: MetaAction<A>,
pub members: Vec<usize>,
pub effectiveness: A,
pub usage_frequency: usize,
}
#[derive(Debug, Clone)]
pub struct DiversityMetrics<A: Float + Send + Sync> {
pub state_coverage: A,
pub action_coverage: A,
pub experience_entropy: A,
pub temporal_diversity: A,
pub outcome_diversity: A,
}
pub struct NoveltyDetector<A: Float + Send + Sync> {
reference_experiences: VecDeque<MetaExperience<A>>,
novelty_threshold: A,
feature_weights: Vec<A>,
}
pub struct MetaModel<A: Float + Send + Sync> {
model_type: MetaModelType,
parameters: MetaModelParameters<A>,
training_history: VecDeque<TrainingEpisode<A>>,
performance_metrics: ModelPerformanceMetrics<A>,
feature_importance: Vec<A>,
}
#[derive(Debug, Clone)]
pub struct MetaModelParameters<A: Float + Send + Sync> {
pub weights: Vec<Vec<A>>,
pub biases: Vec<A>,
pub learning_rate: A,
pub regularization: RegularizationParams<A>,
pub optimization: OptimizationParams<A>,
}
#[derive(Debug, Clone)]
pub struct RegularizationParams<A: Float + Send + Sync> {
pub l1_lambda: A,
pub l2_lambda: A,
pub dropout_rate: A,
pub early_stopping_patience: usize,
}
#[derive(Debug, Clone)]
pub struct OptimizationParams<A: Float + Send + Sync> {
pub momentum: A,
pub beta1: A,
pub beta2: A,
pub epsilon: A,
pub grad_clip_threshold: A,
}
#[derive(Debug, Clone)]
pub struct TrainingEpisode<A: Float + Send + Sync> {
pub episode_id: u64,
pub training_loss: A,
pub validation_loss: A,
pub training_accuracy: A,
pub validation_accuracy: A,
pub duration: Duration,
pub timestamp: Instant,
}
#[derive(Debug, Clone)]
pub struct ModelPerformanceMetrics<A: Float + Send + Sync> {
pub prediction_accuracy: A,
pub decision_quality: A,
pub adaptation_effectiveness: A,
pub transfer_success_rate: A,
pub generalization_performance: A,
}
pub struct StrategySelector<A: Float + Send + Sync> {
strategies: HashMap<String, AdaptationStrategy<A>>,
strategy_performance: HashMap<String, StrategyPerformance<A>>,
selection_policy: SelectionPolicy,
exploration_params: ExplorationParams<A>,
context_selector: ContextBasedSelector<A>,
}
#[derive(Debug, Clone)]
pub struct AdaptationStrategy<A: Float + Send + Sync> {
pub name: String,
pub parameters: HashMap<String, A>,
pub strategy_type: StrategyType,
pub conditions: Vec<StrategyCondition<A>>,
pub expected_outcomes: Vec<A>,
}
#[derive(Debug, Clone)]
pub enum StrategyType {
Conservative,
Aggressive,
Balanced,
Reactive,
Proactive,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct StrategyCondition<A: Float + Send + Sync> {
pub condition_type: ConditionType,
pub threshold: A,
pub operator: ComparisonOperator,
pub weight: A,
}
#[derive(Debug, Clone)]
pub enum ConditionType {
Performance,
ResourceUtilization,
DataQuality,
DriftDetection,
Temporal,
Custom(String),
}
#[derive(Debug, Clone)]
pub enum ComparisonOperator {
GreaterThan,
LessThan,
EqualTo,
Between(f64, f64),
InSet(Vec<f64>),
}
#[derive(Debug, Clone)]
pub struct StrategyPerformance<A: Float + Send + Sync> {
pub usage_count: usize,
pub success_rate: A,
pub avg_improvement: A,
pub best_improvement: A,
pub worst_outcome: A,
pub recent_trend: TrendDirection,
pub context_performance: HashMap<String, A>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TrendDirection {
Improving,
Declining,
Stable,
Oscillating,
}
#[derive(Debug, Clone)]
pub enum SelectionPolicy {
EpsilonGreedy { epsilon: f64 },
UCB { confidence_parameter: f64 },
ThompsonSampling,
Softmax { temperature: f64 },
ContextAware,
MultiArmedBandit,
}
#[derive(Debug, Clone)]
pub struct ExplorationParams<A: Float + Send + Sync> {
pub exploration_rate: A,
pub exploration_decay: A,
pub min_exploration_rate: A,
pub curiosity_weight: A,
pub novelty_weight: A,
}
pub struct ContextBasedSelector<A: Float + Send + Sync> {
context_features: Vec<ContextFeature<A>>,
context_clusters: Vec<ContextCluster<A>>,
context_strategies: HashMap<String, Vec<String>>,
context_model: ContextModel<A>,
}
#[derive(Debug, Clone)]
pub struct ContextFeature<A: Float + Send + Sync> {
pub name: String,
pub value: A,
pub importance: A,
pub stability: A,
}
#[derive(Debug, Clone)]
pub struct ContextCluster<A: Float + Send + Sync> {
pub id: String,
pub center: Vec<A>,
pub radius: A,
pub strategies: Vec<String>,
pub performance: A,
}
pub struct ContextModel<A: Float + Send + Sync> {
parameters: Vec<A>,
feature_weights: Vec<A>,
threshold: A,
accuracy: A,
}
pub struct TransferLearning<A: Float + Send + Sync> {
source_experiences: HashMap<String, Vec<MetaExperience<A>>>,
transfer_strategies: Vec<TransferStrategy>,
domain_adaptation: DomainAdaptation<A>,
transfer_metrics: TransferMetrics<A>,
}
#[derive(Debug, Clone)]
pub enum TransferStrategy {
ParameterTransfer,
FeatureTransfer,
InstanceTransfer,
RelationalTransfer,
MetaTransfer,
}
pub struct DomainAdaptation<A: Float + Send + Sync> {
source_characteristics: Vec<A>,
target_characteristics: Vec<A>,
adaptation_weights: Vec<A>,
domain_similarity: A,
}
#[derive(Debug, Clone)]
pub struct TransferMetrics<A: Float + Send + Sync> {
pub success_rate: A,
pub improvement: A,
pub efficiency: A,
pub negative_transfer_count: usize,
}
pub struct LearningRateAdapter<A: Float + Send + Sync> {
current_rate: A,
rate_history: VecDeque<A>,
performance_feedback: VecDeque<A>,
adaptation_strategy: LearningRateStrategy,
min_rate: A,
max_rate: A,
}
#[derive(Debug, Clone)]
pub enum LearningRateStrategy {
Fixed,
StepDecay { decay_factor: f64, step_size: usize },
ExponentialDecay { decay_rate: f64 },
PerformanceBased,
Cyclical {
min_lr: f64,
max_lr: f64,
cycle_length: usize,
},
Adaptive,
}
#[derive(Debug, Clone)]
pub struct MetaLearningStatistics<A: Float + Send + Sync> {
pub total_experiences: usize,
pub training_episodes: usize,
pub avg_reward_per_episode: A,
pub best_episode_reward: A,
pub learning_progress: A,
pub strategy_selection_accuracy: A,
pub transfer_success_rate: A,
pub replay_effectiveness: A,
}
impl<A: Float + Default + Clone + std::iter::Sum + Send + Sync + std::fmt::Debug> MetaLearner<A> {
pub fn new(config: &StreamingConfig) -> Result<Self, String> {
let meta_config = config.meta_learning_config.clone();
let experience_buffer = ExperienceBuffer::new(&meta_config.replay_config);
let meta_model = MetaModel::new(meta_config.model_complexity.clone())?;
let strategy_selector = StrategySelector::new();
let transfer_learning = TransferLearning::new();
let learning_rate_adapter = LearningRateAdapter::new(meta_config.meta_learning_rate);
let statistics = MetaLearningStatistics {
total_experiences: 0,
training_episodes: 0,
avg_reward_per_episode: A::zero(),
best_episode_reward: A::zero(),
learning_progress: A::zero(),
strategy_selection_accuracy: A::zero(),
transfer_success_rate: A::zero(),
replay_effectiveness: A::zero(),
};
Ok(Self {
config: meta_config,
experience_buffer,
meta_model,
strategy_selector,
transfer_learning,
statistics,
learning_rate_adapter,
})
}
pub fn update_experience(
&mut self,
state: MetaState<A>,
action: MetaAction<A>,
reward: A,
) -> Result<(), String> {
let experience = MetaExperience {
id: self.generate_experience_id(),
state,
action,
reward,
next_state: None, timestamp: Instant::now(),
episode_context: self.create_episode_context(reward)?,
priority: self.calculate_experience_priority(reward),
replay_count: 0,
};
self.experience_buffer.add_experience(experience)?;
self.statistics.total_experiences += 1;
if self
.statistics
.total_experiences
.is_multiple_of(self.config.update_frequency)
{
self.trigger_learning()?;
}
Ok(())
}
fn generate_experience_id(&self) -> u64 {
self.statistics.total_experiences as u64 + 1
}
fn create_episode_context(&self, reward: A) -> Result<EpisodeContext<A>, String> {
let outcome = if reward > A::from(0.8).expect("unwrap failed") {
EpisodeOutcome::Success
} else if reward > A::from(0.5).expect("unwrap failed") {
EpisodeOutcome::PartialSuccess
} else if reward > A::from(0.2).expect("unwrap failed") {
EpisodeOutcome::Neutral
} else if reward > A::from(-0.2).expect("unwrap failed") {
EpisodeOutcome::Failure
} else {
EpisodeOutcome::CriticalFailure
};
Ok(EpisodeContext {
episode_id: self.statistics.training_episodes as u64,
start_time: Instant::now(),
duration: Duration::from_secs(60), initial_performance: A::from(0.5).expect("unwrap failed"), final_performance: reward,
adaptation_count: 1, outcome,
})
}
fn calculate_experience_priority(&self, reward: A) -> A {
let abs_reward = reward.abs();
if abs_reward > A::from(0.8).expect("unwrap failed") {
A::from(1.0).expect("unwrap failed")
} else {
abs_reward
}
}
fn trigger_learning(&mut self) -> Result<(), String> {
let training_batch = self
.experience_buffer
.sample_batch(self.config.replay_config.batch_size)?;
self.meta_model.train_on_batch(&training_batch)?;
self.strategy_selector
.update_from_experiences(&training_batch)?;
self.statistics.training_episodes += 1;
Ok(())
}
pub fn recommend_adaptations(
&mut self,
current_data: &[StreamingDataPoint<A>],
performance_tracker: &PerformanceTracker<A>,
) -> Result<Vec<Adaptation<A>>, String> {
let current_state = self.extract_meta_state(current_data, performance_tracker)?;
let predicted_action = self.meta_model.predict_action(¤t_state)?;
let strategy = self.strategy_selector.select_strategy(¤t_state)?;
let adaptations =
self.generate_adaptations_from_prediction(&predicted_action, &strategy)?;
Ok(adaptations)
}
fn extract_meta_state(
&self,
current_data: &[StreamingDataPoint<A>],
performance_tracker: &PerformanceTracker<A>,
) -> Result<MetaState<A>, String> {
let recent_performance = performance_tracker.get_recent_performance(5);
let performance_metrics = if !recent_performance.is_empty() {
vec![
recent_performance[0].loss,
recent_performance[0].accuracy.unwrap_or(A::zero()),
recent_performance[0].convergence_rate.unwrap_or(A::zero()),
]
} else {
vec![A::zero(), A::zero(), A::zero()]
};
let resource_state = vec![
A::from(0.5).expect("unwrap failed"),
A::from(0.3).expect("unwrap failed"),
];
let drift_indicators = vec![A::from(0.1).expect("unwrap failed")];
Ok(MetaState {
performance_metrics,
resource_state,
drift_indicators,
adaptation_history: self.statistics.total_experiences,
timestamp: Instant::now(),
})
}
fn generate_adaptations_from_prediction(
&self,
predicted_action: &MetaAction<A>,
_strategy: &AdaptationStrategy<A>,
) -> Result<Vec<Adaptation<A>>, String> {
let mut adaptations = Vec::new();
for (i, &magnitude) in predicted_action.adaptation_magnitudes.iter().enumerate() {
if magnitude.abs() > A::from(0.05).expect("unwrap failed") {
let adaptation_type = if i < predicted_action.adaptation_types.len() {
predicted_action.adaptation_types[i].clone()
} else {
AdaptationType::LearningRate };
let adaptation = Adaptation {
adaptation_type,
magnitude,
target_component: "meta_learner".to_string(),
parameters: std::collections::HashMap::new(),
priority: if magnitude.abs() > A::from(0.3).expect("unwrap failed") {
AdaptationPriority::High
} else {
AdaptationPriority::Normal
},
timestamp: Instant::now(),
};
adaptations.push(adaptation);
}
}
Ok(adaptations)
}
pub fn apply_adaptation(&mut self, adaptation: &Adaptation<A>) -> Result<(), String> {
match adaptation.adaptation_type {
AdaptationType::MetaLearning => {
let new_rate = self.learning_rate_adapter.current_rate + adaptation.magnitude;
self.learning_rate_adapter.update_rate(new_rate)?;
}
_ => {
}
}
Ok(())
}
pub fn get_effectiveness_score(&self) -> f32 {
self.statistics.learning_progress.to_f32().unwrap_or(0.0)
}
pub fn get_diagnostics(&self) -> MetaLearningDiagnostics {
MetaLearningDiagnostics {
total_experiences: self.statistics.total_experiences,
training_episodes: self.statistics.training_episodes,
current_learning_rate: self
.learning_rate_adapter
.current_rate
.to_f64()
.unwrap_or(0.0),
model_accuracy: self
.meta_model
.performance_metrics
.prediction_accuracy
.to_f64()
.unwrap_or(0.0),
strategy_count: self.strategy_selector.strategies.len(),
transfer_success_rate: self
.statistics
.transfer_success_rate
.to_f64()
.unwrap_or(0.0),
}
}
}
impl<A: Float + Default + Clone + Send + Sync + std::iter::Sum> ExperienceBuffer<A> {
fn new(config: &ExperienceReplayConfig) -> Self {
Self {
config: config.clone(),
experiences: VecDeque::with_capacity(10000),
priority_queue: VecDeque::new(),
importance_weights: HashMap::new(),
diversity_tracker: ExperienceDiversityTracker::new(),
}
}
fn add_experience(&mut self, experience: MetaExperience<A>) -> Result<(), String> {
if self.experiences.len() >= 10000 {
self.experiences.pop_front();
}
self.experiences.push_back(experience.clone());
if self.config.enable_prioritized_replay {
let priority = experience.priority;
self.priority_queue.push_back((experience, priority));
self.priority_queue
.make_contiguous()
.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
if self.priority_queue.len() > 1000 {
self.priority_queue.pop_front();
}
}
Ok(())
}
fn sample_batch(&mut self, batch_size: usize) -> Result<Vec<MetaExperience<A>>, String> {
if self.experiences.is_empty() {
return Ok(Vec::new());
}
let mut batch = Vec::with_capacity(batch_size);
if self.config.enable_prioritized_replay && !self.priority_queue.is_empty() {
for _ in 0..batch_size.min(self.priority_queue.len()) {
if let Some((experience, _)) = self.priority_queue.pop_front() {
batch.push(experience);
}
}
} else {
for _ in 0..batch_size.min(self.experiences.len()) {
let idx = thread_rng().gen_range(0..self.experiences.len());
if let Some(experience) = self.experiences.get(idx) {
batch.push(experience.clone());
}
}
}
Ok(batch)
}
}
impl<A: Float + Default + Clone + Send + Sync + std::iter::Sum> ExperienceDiversityTracker<A> {
fn new() -> Self {
Self {
state_clusters: Vec::new(),
action_clusters: Vec::new(),
diversity_metrics: DiversityMetrics {
state_coverage: A::zero(),
action_coverage: A::zero(),
experience_entropy: A::zero(),
temporal_diversity: A::zero(),
outcome_diversity: A::zero(),
},
novelty_detector: NoveltyDetector::new(),
}
}
}
impl<A: Float + Default + Clone + Send + Sync + std::iter::Sum> NoveltyDetector<A> {
fn new() -> Self {
Self {
reference_experiences: VecDeque::with_capacity(1000),
novelty_threshold: A::from(0.5).expect("unwrap failed"),
feature_weights: Vec::new(),
}
}
}
impl<A: Float + Default + Clone + Send + Sync + std::iter::Sum> MetaModel<A> {
fn new(complexity: MetaModelComplexity) -> Result<Self, String> {
let parameters = match complexity {
MetaModelComplexity::Low => MetaModelParameters {
weights: vec![vec![A::from(0.1).expect("unwrap failed"); 10]; 2],
biases: vec![A::zero(); 10],
learning_rate: A::from(0.01).expect("unwrap failed"),
regularization: RegularizationParams {
l1_lambda: A::from(0.001).expect("unwrap failed"),
l2_lambda: A::from(0.001).expect("unwrap failed"),
dropout_rate: A::from(0.1).expect("unwrap failed"),
early_stopping_patience: 10,
},
optimization: OptimizationParams {
momentum: A::from(0.9).expect("unwrap failed"),
beta1: A::from(0.9).expect("unwrap failed"),
beta2: A::from(0.999).expect("unwrap failed"),
epsilon: A::from(1e-8).expect("unwrap failed"),
grad_clip_threshold: A::from(1.0).expect("unwrap failed"),
},
},
_ => MetaModelParameters {
weights: vec![vec![A::from(0.1).expect("unwrap failed"); 50]; 3],
biases: vec![A::zero(); 50],
learning_rate: A::from(0.001).expect("unwrap failed"),
regularization: RegularizationParams {
l1_lambda: A::from(0.0001).expect("unwrap failed"),
l2_lambda: A::from(0.0001).expect("unwrap failed"),
dropout_rate: A::from(0.2).expect("unwrap failed"),
early_stopping_patience: 20,
},
optimization: OptimizationParams {
momentum: A::from(0.9).expect("unwrap failed"),
beta1: A::from(0.9).expect("unwrap failed"),
beta2: A::from(0.999).expect("unwrap failed"),
epsilon: A::from(1e-8).expect("unwrap failed"),
grad_clip_threshold: A::from(1.0).expect("unwrap failed"),
},
},
};
Ok(Self {
model_type: MetaModelType::NeuralNetwork,
parameters,
training_history: VecDeque::with_capacity(1000),
performance_metrics: ModelPerformanceMetrics {
prediction_accuracy: A::from(0.5).expect("unwrap failed"),
decision_quality: A::from(0.5).expect("unwrap failed"),
adaptation_effectiveness: A::from(0.5).expect("unwrap failed"),
transfer_success_rate: A::from(0.5).expect("unwrap failed"),
generalization_performance: A::from(0.5).expect("unwrap failed"),
},
feature_importance: Vec::new(),
})
}
fn train_on_batch(&mut self, batch: &[MetaExperience<A>]) -> Result<(), String> {
if batch.is_empty() {
return Ok(());
}
let avg_reward = batch.iter().map(|e| e.reward).sum::<A>()
/ A::from(batch.len()).expect("unwrap failed");
if avg_reward > A::from(0.5).expect("unwrap failed") {
self.parameters.learning_rate =
self.parameters.learning_rate * A::from(1.01).expect("unwrap failed");
} else {
self.parameters.learning_rate =
self.parameters.learning_rate * A::from(0.99).expect("unwrap failed");
}
self.performance_metrics.prediction_accuracy = avg_reward;
Ok(())
}
fn predict_action(&self, state: &MetaState<A>) -> Result<MetaAction<A>, String> {
let action = MetaAction {
adaptation_magnitudes: vec![
A::from(0.1).expect("unwrap failed"),
A::from(-0.05).expect("unwrap failed"),
],
adaptation_types: vec![AdaptationType::LearningRate, AdaptationType::BufferSize],
learning_rate_change: A::from(0.01).expect("unwrap failed"),
buffer_size_change: A::from(5.0).expect("unwrap failed"),
timestamp: Instant::now(),
};
Ok(action)
}
}
impl<A: Float + Default + Clone + Send + Sync + std::iter::Sum> StrategySelector<A> {
fn new() -> Self {
let mut strategies = HashMap::new();
strategies.insert(
"conservative".to_string(),
AdaptationStrategy {
name: "conservative".to_string(),
parameters: HashMap::new(),
strategy_type: StrategyType::Conservative,
conditions: Vec::new(),
expected_outcomes: vec![A::from(0.05).expect("unwrap failed")],
},
);
strategies.insert(
"aggressive".to_string(),
AdaptationStrategy {
name: "aggressive".to_string(),
parameters: HashMap::new(),
strategy_type: StrategyType::Aggressive,
conditions: Vec::new(),
expected_outcomes: vec![A::from(0.2).expect("unwrap failed")],
},
);
Self {
strategies,
strategy_performance: HashMap::new(),
selection_policy: SelectionPolicy::EpsilonGreedy { epsilon: 0.1 },
exploration_params: ExplorationParams {
exploration_rate: A::from(0.1).expect("unwrap failed"),
exploration_decay: A::from(0.99).expect("unwrap failed"),
min_exploration_rate: A::from(0.01).expect("unwrap failed"),
curiosity_weight: A::from(0.1).expect("unwrap failed"),
novelty_weight: A::from(0.1).expect("unwrap failed"),
},
context_selector: ContextBasedSelector::new(),
}
}
fn select_strategy(&self, _state: &MetaState<A>) -> Result<AdaptationStrategy<A>, String> {
if let Some(strategy) = self.strategies.get("balanced") {
Ok(strategy.clone())
} else if let Some(strategy) = self.strategies.values().next() {
Ok(strategy.clone())
} else {
Err("No strategies available".to_string())
}
}
fn update_from_experiences(
&mut self,
_experiences: &[MetaExperience<A>],
) -> Result<(), String> {
Ok(())
}
}
impl<A: Float + Default + Clone + Send + Sync + std::iter::Sum> ContextBasedSelector<A> {
fn new() -> Self {
Self {
context_features: Vec::new(),
context_clusters: Vec::new(),
context_strategies: HashMap::new(),
context_model: ContextModel {
parameters: Vec::new(),
feature_weights: Vec::new(),
threshold: A::from(0.5).expect("unwrap failed"),
accuracy: A::from(0.5).expect("unwrap failed"),
},
}
}
}
impl<A: Float + Default + Clone + Send + Sync + std::iter::Sum> TransferLearning<A> {
fn new() -> Self {
Self {
source_experiences: HashMap::new(),
transfer_strategies: vec![TransferStrategy::ParameterTransfer],
domain_adaptation: DomainAdaptation {
source_characteristics: Vec::new(),
target_characteristics: Vec::new(),
adaptation_weights: Vec::new(),
domain_similarity: A::from(0.5).expect("unwrap failed"),
},
transfer_metrics: TransferMetrics {
success_rate: A::from(0.5).expect("unwrap failed"),
improvement: A::from(0.1).expect("unwrap failed"),
efficiency: A::from(0.7).expect("unwrap failed"),
negative_transfer_count: 0,
},
}
}
}
impl<A: Float + Default + Clone + Send + Sync + std::iter::Sum> LearningRateAdapter<A> {
fn new(initial_rate: f64) -> Self {
Self {
current_rate: A::from(initial_rate).expect("unwrap failed"),
rate_history: VecDeque::with_capacity(100),
performance_feedback: VecDeque::with_capacity(100),
adaptation_strategy: LearningRateStrategy::PerformanceBased,
min_rate: A::from(1e-6).expect("unwrap failed"),
max_rate: A::from(0.1).expect("unwrap failed"),
}
}
fn update_rate(&mut self, new_rate: A) -> Result<(), String> {
self.current_rate = new_rate.max(self.min_rate).min(self.max_rate);
if self.rate_history.len() >= 100 {
self.rate_history.pop_front();
}
self.rate_history.push_back(self.current_rate);
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct MetaLearningDiagnostics {
pub total_experiences: usize,
pub training_episodes: usize,
pub current_learning_rate: f64,
pub model_accuracy: f64,
pub strategy_count: usize,
pub transfer_success_rate: f64,
}