Skip to content

个性化联邦学习方法

全局联邦模型可能不适合所有参与方。个性化联邦学习为每个参与方生成定制化模型,平衡全局知识与本地适配。

个性化联邦学习

个性化方法分类

类别代表方法原理个性化程度
元学习Per-FedAvg学习好的初始化
多任务学习FedMTL每方一个任务
基底+头部FedPer共享基底,私有头部中高
聚类IFCA相似方共享模型
正则化FedRep表示共享,分类器私有

FedPer:基底+头部

python
class FedPerModel(nn.Module):
    """FedPer: 共享特征提取器 + 私有分类头"""

    def __init__(self, backbone, num_classes_per_client):
        super().__init__()
        self.backbone = backbone  # 全局共享

    def get_backbone(self):
        return self.backbone

    def create_head(self, num_classes):
        """为每个客户端创建私有分类头"""
        return nn.Linear(self.backbone.hidden_dim, num_classes)


class FedPerClient:
    def __init__(self, model, num_classes):
        self.backbone = model.get_backbone()
        self.head = model.create_head(num_classes)

    def local_train(self, dataloader, lr=0.01):
        """本地训练:更新 backbone 和 head"""
        optimizer = torch.optim.SGD(
            list(self.backbone.parameters()) + list(self.head.parameters()),
            lr=lr
        )

        for batch in dataloader:
            features = self.backbone(batch["x"])
            logits = self.head(features)
            loss = F.cross_entropy(logits, batch["y"])
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()

        # 只上传 backbone 参数
        return self.backbone.state_dict()

元学习:Per-FedAvg

python
class PerFedAvg:
    """Per-FedAvg: 元学习联邦"""

    def __init__(self, model, alpha=0.01, beta=0.01):
        self.model = model
        self.alpha = alpha  # 内循环学习率
        self.beta = beta    # 外循环学习率

    def meta_update(self, support_data, query_data):
        """MAML 风格的元更新"""
        # 内循环:在 support set 上适应
        adapted_params = self.adapt(support_data, self.alpha)

        # 外循环:在 query set 上评估
        query_loss = self.evaluate(query_data, adapted_params)

        # 计算元梯度
        meta_grads = torch.autograd.grad(query_loss, self.model.parameters())

        # 更新全局模型
        for param, grad in zip(self.model.parameters(), meta_grads):
            param.data -= self.beta * grad

聚类联邦

python
class IFCA:
    """IFCA: 联邦聚类"""

    def __init__(self, num_clusters=3):
        self.num_clusters = num_clusters
        self.cluster_models = []  # 每个聚类一个模型

    def assign_cluster(self, client_data, client_model):
        """将客户端分配到最近的聚类"""
        min_loss = float('inf')
        best_cluster = 0

        for c, model in enumerate(self.cluster_models):
            loss = self.evaluate(client_data, model)
            if loss < min_loss:
                min_loss = loss
                best_cluster = c

        return best_cluster

    def aggregate(self, cluster_id, client_updates):
        """在聚类内聚合"""
        self.cluster_models[cluster_id] = FedAvg.aggregate(client_updates)

个性化方法选择

  1. 参与方数据分布差异大:FedPer 或聚类
  2. 快速适应新任务:Per-FedAvg(元学习)
  3. 参与方数量多且可分组:IFCA
  4. 追求简单实现:FedRep(只共享表示层)

个性化 vs 全局

个性化程度越高,越偏离全局知识,可能导致:1) 过拟合本地数据;2) 丢失跨方知识;3) 需要更多本地数据。需要在个性化和泛化间权衡。

相关资源

最近更新