use crate::error::Result;
use scirs2_core::ndarray::Array1;
use scirs2_core::numeric::Float;
use std::collections::HashMap;
use std::fmt::Debug;
use super::types::{
MetaLearningAlgorithm, MetaTask, MetaTrainingResult, QueryEvaluationResult,
TaskAdaptationResult,
};
pub trait MetaLearner<T: Float + Debug + Send + Sync + 'static>: Send + Sync {
fn meta_train_step(
&mut self,
task_batch: &[MetaTask<T>],
meta_parameters: &mut HashMap<String, Array1<T>>,
) -> Result<MetaTrainingResult<T>>;
fn adapt_to_task(
&mut self,
task: &MetaTask<T>,
meta_parameters: &HashMap<String, Array1<T>>,
adaptation_steps: usize,
) -> Result<TaskAdaptationResult<T>>;
fn evaluate_query_set(
&self,
task: &MetaTask<T>,
adapted_parameters: &HashMap<String, Array1<T>>,
) -> Result<QueryEvaluationResult<T>>;
fn get_algorithm(&self) -> MetaLearningAlgorithm;
}
#[cfg(test)]
mod tests {
use crate::meta_learning::types::{
AdaptationStrategy, AntiForgettingStrategy, AugmentationStrategy,
ContinualLearningSettings, DistanceMetric, FewShotAlgorithm, FewShotSettings,
GradientBalancingMethod, InterferenceMitigationStrategy, MAMLConfig, MemoryReplaySettings,
MemorySelectionCriteria, MetaLearningAlgorithm, MetaLearningConfig, MetricLearningSettings,
MultiTaskSettings, ReplayStrategy, SharedRepresentationStrategy, SimilarityMeasure,
TaskIdentificationMethod, TaskSamplingStrategy, TaskWeightingStrategy,
TransferLearningSettings, TransferStrategy,
};
#[test]
fn test_meta_learning_config() {
let config = MetaLearningConfig {
algorithm: MetaLearningAlgorithm::MAML,
inner_steps: 5,
outer_steps: 100,
meta_learning_rate: 0.001,
inner_learning_rate: 0.01,
task_batch_size: 16,
support_set_size: 10,
query_set_size: 15,
second_order: true,
gradient_clip: 1.0,
adaptation_strategies: vec![AdaptationStrategy::FullFineTuning],
transfer_settings: TransferLearningSettings {
domain_adaptation: true,
source_domain_weights: vec![1.0],
strategies: vec![TransferStrategy::FineTuning],
similarity_measures: vec![SimilarityMeasure::CosineDistance],
progressive_transfer: false,
},
continual_settings: ContinualLearningSettings {
anti_forgetting_strategies: vec![
AntiForgettingStrategy::ElasticWeightConsolidation,
],
memory_replay: MemoryReplaySettings {
buffer_size: 1000,
replay_strategy: ReplayStrategy::Random,
replay_frequency: 10,
selection_criteria: MemorySelectionCriteria::Random,
},
task_identification: TaskIdentificationMethod::Oracle,
plasticity_stability_balance: 0.5,
},
multitask_settings: MultiTaskSettings {
task_weighting: TaskWeightingStrategy::Uniform,
gradient_balancing: GradientBalancingMethod::Uniform,
interference_mitigation: InterferenceMitigationStrategy::OrthogonalGradients,
shared_representation: SharedRepresentationStrategy::HardSharing,
},
few_shot_settings: FewShotSettings {
num_shots: 5,
num_ways: 5,
algorithm: FewShotAlgorithm::MAML,
metric_learning: MetricLearningSettings {
distance_metric: DistanceMetric::Euclidean,
embedding_dim: 64,
learned_metric: false,
},
augmentation_strategies: vec![AugmentationStrategy::Geometric],
},
enable_meta_regularization: true,
meta_regularization_strength: 0.01,
task_sampling_strategy: TaskSamplingStrategy::Uniform,
};
assert_eq!(config.inner_steps, 5);
assert_eq!(config.task_batch_size, 16);
assert!(config.second_order);
assert!(matches!(config.algorithm, MetaLearningAlgorithm::MAML));
}
#[test]
fn test_maml_config() {
let config = MAMLConfig {
second_order: true,
inner_lr: 0.01f64,
outer_lr: 0.001f64,
inner_steps: 5,
allow_unused: true,
gradient_clip: Some(1.0),
};
assert!(config.second_order);
assert_eq!(config.inner_steps, 5);
assert_eq!(config.inner_lr, 0.01);
}
}