53 lines
1.3 KiB
Rust
53 lines
1.3 KiB
Rust
//! Trimmed mean Byzantine-robust aggregation
|
|
|
|
use super::{ByzantineConfig, ByzantineRobust};
|
|
use crate::aggregation::ModelUpdate;
|
|
use crate::error::{FederatedError, Result};
|
|
use async_trait::async_trait;
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Debug)]
|
|
pub struct TrimmedMean {
|
|
trim_fraction: f64,
|
|
coordinate_wise: bool,
|
|
}
|
|
|
|
impl TrimmedMean {
|
|
pub async fn new(trim_fraction: f64) -> Result<Self> {
|
|
Ok(Self {
|
|
trim_fraction,
|
|
coordinate_wise: true,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl ByzantineRobust for TrimmedMean {
|
|
async fn filter_updates(&self, updates: &[ModelUpdate]) -> Result<Vec<ModelUpdate>> {
|
|
if updates.is_empty() {
|
|
return Err(FederatedError::NoUpdatesCollected);
|
|
}
|
|
// Simplified: return all updates for now
|
|
Ok(updates.to_vec())
|
|
}
|
|
|
|
async fn detect_malicious_clients(&self, _updates: &[ModelUpdate]) -> Result<Vec<Uuid>> {
|
|
Ok(Vec::new())
|
|
}
|
|
|
|
fn get_robustness_config(&self) -> ByzantineConfig {
|
|
ByzantineConfig::TrimmedMean {
|
|
trim_fraction: self.trim_fraction,
|
|
coordinate_wise: self.coordinate_wise,
|
|
}
|
|
}
|
|
|
|
async fn update_state(&mut self, _round: usize, _updates: &[ModelUpdate]) -> Result<()> {
|
|
Ok(())
|
|
}
|
|
|
|
fn name(&self) -> &'static str {
|
|
"TrimmedMean"
|
|
}
|
|
}
|